skip to content

In a GitHub organization, how is a member's effective permission on a repository determined?

level: middleimportance: must knowfreq 55%

answer

  1. Several grants can apply at once
  2. No grant ever subtracts from another
  3. Nesting flows in one direction
  4. Owners sit outside the calculation
  5. The highest applicable role wins

basics

~20 s

GitHub takes the highest access from every source that applies: the organization's base permission, each team the member belongs to (including access inherited from a parent team), and any direct collaborator grant. Organization owners always hold admin.

solid answer

~50 s

Four sources can grant a member access to an organization repository. The **base permission** is an org-wide setting — none, read, write or admin — applied to every member on every org repository. **Team grants** attach a role to a team; a member of a **child team** also inherits the parent team's repository access, so nesting adds permissions downward. A **direct collaborator grant** attaches a role to one person on one repository. And **organization owners** hold admin everywhere regardless of the other three. GitHub resolves these by taking the **maximum**, not the most recent or the most specific. Adding someone to a Read team never demotes the Write they hold elsewhere. That single rule drives the practical consequence: revoking access means finding and removing *every* source that supplies it, which is why mature orgs grant through teams only and keep base permission low.

code

json · 8 lines
json
{
  "permission": "write",
  "role_name": "write",
  "user": {
    "login": "dana",
    "type": "User"
  }
}

go deeper

for a junior

Know that your access can come from the organization, a team, or a personal invitation, and that being on several teams is normal. Do not assume the repository page lists the only reason you have access.

for a middle

Explain the four sources and state the maximum-wins rule explicitly. The interviewer usually follows with "so how do you take access away" — the answer is remove every source, not add a lower one.

for a senior

Demonstrate that you have traced this in a real incident: enumerate grants through the API, separate a role failure from a branch-rule failure, and describe how you audit direct collaborator grants that no team roster shows.

for a principal

Own the org-shape decision: a low base permission with team-only grants is auditable; a high base permission with individual invitations is convenient and unreviewable. Be able to argue the migration path between them.

## The four sources Ask "can Dana push to this repository?" and GitHub does not consult one record — it unions several. **Base permission** is an organization setting that gives every organization member the same floor on every repository the org owns. The choices are no permission, read, write, or admin. It is convenient and dangerous in equal measure: setting it to write means every person who joins the company can push to every repository on day one, including repositories they have never heard of. **Team grants** attach a repository role to a team; every member of that team gets the role. Teams are the intended unit of access because they are the unit of onboarding and offboarding — remove someone from the team and every grant that flowed through it disappears at once. **Nested teams** complicate the picture in one specific direction. A child team **inherits the parent team's repository access**, so a member of `platform/storage` also gets whatever `platform` was granted. Inheritance runs from parent to child; being in the parent does not give you the child's grants. This is why org charts are modelled with the broad team at the top and narrow teams beneath. **Direct collaborator grants** attach a role to one person on one repository. They are how outside collaborators — people with repository access who are not organization members — get in at all, since outside collaborators cannot be placed on teams. On top of all of it, **organization owners** have administrative access to every repository in the organization by virtue of the org role, and no repository-level setting reduces that. ## The resolution rule: maximum wins GitHub computes the **highest** of the applicable grants. There is no ordering by specificity, no "deny" grant, and no way to subtract. A team granted Read cannot pull someone down from the Write they get from base permission. If you need someone to have less, you must lower or remove the source that is granting more. This has a blunt corollary that interviewers probe: **you cannot revoke access by adding something**. Someone leaving a project needs every path traced — base permission, each team including inherited parent grants, and any direct grant. The API helps here: a per-user permission endpoint returns the effective level for one person on one repository, and the collaborators listing reports each user's `role_name`, which is what access-review scripts read. ## Why this shapes org design Because resolution is a maximum, least privilege on GitHub is achieved by keeping the *floor* low and expressing everything else through teams. The common shape is: base permission set to read (or no permission where repositories are sensitive), all routine access granted to teams that mirror the organization, admin reserved to a very small group, and direct collaborator grants used sparingly and reviewed on a schedule because they are invisible from the team structure. The opposite shape — base permission write, plus ad-hoc individual invitations — looks frictionless for a year and then produces the audit finding that nobody can say who can push to the payments repository. ## Repository visibility interacts Access sources apply to private and internal repositories. A **public** repository is readable by anyone regardless, so the grants only decide who can push or administer it. An **internal** repository (available in organizations under an enterprise) is readable by enterprise members without an explicit grant — another floor that sits underneath your team model, and one people forget when they reason about who can see the code. ## Diagnosing in practice When someone reports "I can see it but can't push", walk the sources in order: is base permission read? Are they on a team with only read? Did they expect a parent-team grant that actually lives on a sibling team? Is the branch itself protected, so the failure is a rule and not a role at all? That last distinction matters — a push rejected by branch protection looks identical to a push rejected by permissions to a candidate who has not thought about it, and separating the two is the sign of someone who has actually operated a GitHub organization.

  • Why can you not restrict someone by adding them to a team with a lower role?
    Because GitHub resolves access as the maximum of all applicable grants — there is no deny rule and no specificity ordering. A read team grant simply adds read, which is already implied by any higher access. To reduce someone's level you must lower the base permission, remove them from the team that grants more, or delete the direct collaborator grant.
  • How does access work for an outside collaborator compared with an organization member?
    An outside collaborator is not an org member, so the base permission does not apply to them and they cannot be added to teams. Their access is exactly the direct per-repository grants they hold, which makes them well scoped but easy to lose track of — they do not appear in any team roster, so they need a scheduled review of their own.
  • A developer can clone a repository but their push is rejected. How do you tell a permissions problem from a branch rule?
    Check the effective role first — the per-user permission API endpoint or the repository access settings will say whether they have write at all. If they do, the rejection is coming from a repository rule on that branch (required reviews, required checks, restricted push actors), which is policy rather than role. The two produce similar-looking failures and are fixed in completely different places.

saying these in an interview costs you the question

  • Thinks the most specific grant wins over others
  • Believes a team can revoke access someone already has
  • Assumes nested child grants flow upward to parents
  • Forgets base permission applies to every repository
  • Thinks removing one team fully offboards a person

context