GitHub Permissions for Maximum Security

Role-based access control (RBAC) is an approach to restricting system access to authorized users. GitHub enforces RBAC via “Access Permissions”, a permission scheme divided into two categories: repository permissions and organization permissions.

Here, we will explore these permissions and show you how to best leverage them to secure your source code in an era of cyber threats and data leaks.

Repository Permissions

Repository-specific permissions define which users may access the repository and to what extent they may interact with it.  The three main roles are:

  • Read
  • Write
  • Admin


Users with the read permission are able to read and clone the repository’s code, create and interact with issues, submit new pull requests, and review existing pull requests.

The write permission grants users all of the abilities of read permissions and adds the ability to issue commits to the repository.

Users granted admin (administrator) rights have unrestricted access to the repository and all of its features.  Among other unlimited abilities, they may read, write, adjust security settings, rename the repository, or even archive or delete the repository entirely.  

Of note, more nuanced triage and maintain permissions exist as well, granting a range of access rights between the base permissions above.  For example, a user with triage rights has more access than read rights allow but less access than write rights allow.  Maintain rights are similarly between write and admin levels.  We will set these aside for the purpose of this discussion; simply be aware that these additional options exist and that the concepts detailed here apply to these optional roles just as they do the base roles.

Organization Permissions

Permissions at the organizational level allow users either an owner or member role (or, optionally, a billing manager role, which is beyond the scope of this article).  An owner has administrator rights across all of their organization’s repositories as well as access to organization-wide features, such as inviting new users to the organization.  

One such org-wide feature worth highlighting is the default repository permission, called the base permissions setting, which defines the repository permission level automatically granted to each member upon joining the organization. This default permission may be set to read, write, admin, or none, the latter meaning that the user has no access whatsoever until a repository permission is manually assigned to them.

Further complicating these roles is a feature by which an organization can grant a repository-specific permission to a user outside of the organization, such as a contractor or freelancer.  This type of user, called an outside collaborator, may be created by adding a non-organization user to a specific repository via a repository-specific permission.

And if that wasn’t complicated enough, you also have teams. In GitHub, a team groups the organization’s members into a logical unit to ease the permissions hierarchy within the organization.  For example, a group of users may be designated as a “DevOps Team”. 

Github Permissions: How it Should Work

Let’s create an example to try and illustrate the different aspects of these various permission levels.

A new startup creates its own GitHub organization and adds three core full stack: Erica, Ryan and David.  The new organization initially consists of three generic repositories, named “Frontend”, “Backend” and “DevOps”.

Erica, the head of engineering, is given the owner role.  Ryan and David are each given the member role.  This means that Erica is the administrator over the organization and has admin rights across all of the organization’s repositories, including other admin perks such as inviting new members, access to audit logs, and the ability to create webhooks, just to name a few.

At this early stage, all developers perform all tasks, so Erica sets the organization’s base permissions to admin (spoiler: it’s against best practices).

A few weeks pass, then the organization hires Peter, an external DevOps freelancer.  Peter is added as an outside collaborator with write permissions to the “DevOps” repository.  This means that Peter can commit code, add issues, and submit pull requests to that individual repository, but can’t access the other two repositories within the organization.

A few more weeks pass, then a new frontend developer, Theresa is hired and added as an organization member.  Since Theresa doesn’t really need to commit code to other repositories, Erica adds her with read permissions to the “Backend” repository so that she can be aware of backend changes that may affect her work.

Unfortunately, GitHub informs Erica that there is a conflict with that permission since Theresa automatically received admin permissions to all of the organization’s repositories

Remember what the repository base permissions was set to?  Though the idea was for Theresa to write to the “Frontend” repository and read from the “Backend”, she instead has full admin rights over both of them — including the “Dev/Ops” repository and every new repository created in the future!

An unrestricted or otherwise high-level default repository permission will become a real pain when more and more users are added to the organization because all of them are automatically added with a wide range of access to repositories they should not be privileged to modify.

GitHub permissions, as well as any other system’s RBAC policy, should be as strict as possible, providing only the privileges necessary for each specific user.

The GitHub community recommends making repositories “as open as possible to promote sharing, reuse, and contribution across the organization” (though it also acknowledges this is not true for all use cases).  The scenario above, however, demonstrates that none is the best base permission.  Work with teams and outside collaborators to fine tune the correct access to each repository.

Here is a possible workflow for changing an over-permissive default setting:

  1. Group your users into logical units (e.g “Frontend”, “Backend”, “DevOps”, etc.).
  2. Add team-based permissions to your repositories (e.g repositories pertaining to your frontend should only be accessible to the “Frontend” team only).
  3. Decrease the base permissions setting to none.
  4. Wait for furious emails like “Why can’t I access repository <repository_name>??” to arrive, apologize and add the missing permissions.
  5. Repeat #4 until everything is back to normal.

We Use SSO – Should I Care About All These Permissions?

The short answer: Yes.

The long answer: Single Sign-On (SSO) integration allows an organization’s own administrators to manage their users internally, outside of GitHub.  SSO authenticates an organization’s internal user accounts through an identity provider (IdP) which then allows these users access to the organization’s GitHub repositories.  In other words, a user’s internal organization login is also used to login to GitHub, without the need to create a separate GitHub account.

GitHub permission settings are applied just the same to SSO users, meaning that if the user has no permissions to a given repository (and base permissions is set to none), the user will not be able to access it.

Note that at the time of this writing, GitHub supports team synchronization (SSO integration) with Azure Active Directory IdP only, and has just started a private beta with Okta.

With team synchronization enabled, GitHub will automatically synchronize teams with your IdP’s corresponding group structure. This means that once you add a user to a group in your organization’s IdP which corresponds to a GitHub team, the user will automatically be added to that GitHub team as well.

Securing Your Source Code For The Long Haul

We created teams, modified permissions, and set base permissions to none. Can we finally relax and go on with developing our product?

Well…not really.

Whatever permissions are in place any given moment reflect a point in time in which specific users were privileged to collaborate on specific repositories.  Any personnel changes that occur (users move between teams or leave the organization) should be immediately reflected in the permissions structure.

Without proper monitoring and constant updates to these permissions, unprivileged users can gain access to the organization’s most precious assets.

Cycode’s Access Review module provides full visibility and automatic remediations for all of an organization’s permissions-related assets.

To learn more about how to reduce the risk of unprivileged code access in your organization, reach out to us and we can share how we can best protect your source code.

Protect Your Source Code in Minutes

Learn how you can gain visibility into all of your organization’s
source code to protect it from theft and loss.

Related Posts

Why You Need to Know SAMM

Introduction We here at Cycode passionately advocate for protecting your source code and the secrets within it throughout its lifecycle and along all points of

Read More »

How to Setup Branch Protection Rules

Branching is the cornerstone of cooperative work using Git. Developers utilize branches to work on the same source code repository in parallel. Generally speaking, when working with branches, there is one main branch in a repository from which

Read More »