Code of Conduct
What article on docs.github.com is affected?
Two related articles:
- https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/repository-access-and-collaboration/permission-levels-for-a-personal-account-repository
- https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2026-03-10#add-a-repository-collaborator
What part(s) of the article would you like to see updated?
Three statements across these two articles do not match the current behaviour of the
REST API. I verified each against the live API (X-GitHub-Api-Version: 2026-03-10).
1. "A repository owned by a personal account has two permission levels: the repository
owner and collaborators."
Collaborators on a personal-account repository can be assigned three distinct roles:
read, write and admin. The API accepts all three and records them as such.
2. "Collaborators can't have read-only access to repositories owned by a personal
account."
PUT /repos/{owner}/{repo}/collaborators/{username} with {"permission": "pull"} on a
private personal-account repository returns 201, and the resulting invitation object
records "permissions": "read".
The same article also states that admin rights cannot be assigned to collaborators on a
personal-account repository. Sending {"permission": "admin"} returns 201 and records
"permissions": "admin".
3. REST reference, permission body parameter: "Only valid on organization-owned
repositories."
The parameter is honoured on personal-account repositories for pull, push and
admin. Only triage and maintain are organization-only; those two return
422 Validation Failed on a personal-account repository.
Suggested wording
For the personal-account article:
A repository owned by a personal account has one owner. The owner can add
collaborators and grant each collaborator one of three access levels: read, write, or
admin. The triage and maintain roles are only available on repositories owned by an
organization. If you need those roles, or team-based access management, consider
transferring the repository to an organization.
For the REST reference, replacing "Only valid on organization-owned repositories":
On organization-owned repositories you can use pull, triage, push, maintain,
admin, or a custom repository role name. On repositories owned by a personal account
only pull, push and admin are accepted; triage and maintain return 422.
Additional information
Reproducible on 100% of attempts.
Method. For each of the five documented permission values, send
PUT /repos/{owner}/{repo}/collaborators/{username} and read the permissions field of
the returned invitation object, cancelling the invitation between attempts. The same
script and token were run twice: once against a private repository owned by a personal
account, once against a private repository owned by an organization. The invitee was an
outside collaborator in both cases and was never an organization member, so no
organization base permission applied.
Private repository owned by a personal account:
| requested |
HTTP |
recorded permission |
pull |
201 |
read |
triage |
422 |
Validation Failed |
push |
201 |
write |
maintain |
422 |
Validation Failed |
admin |
201 |
admin |
Private repository owned by an organization (control):
| requested |
HTTP |
recorded permission |
pull |
201 |
read |
triage |
201 |
triage |
push |
201 |
write |
maintain |
201 |
maintain |
admin |
201 |
admin |
Enforcement was confirmed independently: on a private personal-account repository, a
collaborator granted pull has git push rejected by the server and cannot access
repository settings, while a collaborator granted admin can.
This is a documentation accuracy issue, not a security report. The API behaves safely and
predictably — it rejects unsupported values with an explicit 422 rather than silently
substituting a different permission level. The problem is only that the documentation
understates what personal-account repositories support. That leads people to build
unnecessary workarounds, or to assume an access restriction is not being applied when in
fact it is.
Note on the web UI. As far as I can tell, the repository settings UI for a
personal-account repository does not expose a role selector for collaborators, so these
three levels appear to be reachable only through the REST API. That may well be why the
articles are worded as they are — they describe what the UI offers rather than what the
API accepts.
That leads to my actual question, which determines whether this behaviour can be relied
on: is accepting pull, push and admin on personal-account repositories intended and
supported behaviour that the docs should describe, or is it unintended behaviour that
happens to work today? Tools that manage repository access programmatically need to know
which, because the answer decides whether a read-only collaborator on a personal-account
repository is a guarantee or an accident.
Code of Conduct
What article on docs.github.com is affected?
Two related articles:
What part(s) of the article would you like to see updated?
Three statements across these two articles do not match the current behaviour of the
REST API. I verified each against the live API (
X-GitHub-Api-Version: 2026-03-10).1. "A repository owned by a personal account has two permission levels: the repository
owner and collaborators."
Collaborators on a personal-account repository can be assigned three distinct roles:
read,writeandadmin. The API accepts all three and records them as such.2. "Collaborators can't have read-only access to repositories owned by a personal
account."
PUT /repos/{owner}/{repo}/collaborators/{username}with{"permission": "pull"}on aprivate personal-account repository returns
201, and the resulting invitation objectrecords
"permissions": "read".The same article also states that admin rights cannot be assigned to collaborators on a
personal-account repository. Sending
{"permission": "admin"}returns201and records"permissions": "admin".3. REST reference,
permissionbody parameter: "Only valid on organization-ownedrepositories."
The parameter is honoured on personal-account repositories for
pull,pushandadmin. Onlytriageandmaintainare organization-only; those two return422 Validation Failedon a personal-account repository.Suggested wording
For the personal-account article:
For the REST reference, replacing "Only valid on organization-owned repositories":
Additional information
Reproducible on 100% of attempts.
Method. For each of the five documented permission values, send
PUT /repos/{owner}/{repo}/collaborators/{username}and read thepermissionsfield ofthe returned invitation object, cancelling the invitation between attempts. The same
script and token were run twice: once against a private repository owned by a personal
account, once against a private repository owned by an organization. The invitee was an
outside collaborator in both cases and was never an organization member, so no
organization base permission applied.
Private repository owned by a personal account:
pullreadtriagepushwritemaintainadminadminPrivate repository owned by an organization (control):
pullreadtriagetriagepushwritemaintainmaintainadminadminEnforcement was confirmed independently: on a private personal-account repository, a
collaborator granted
pullhasgit pushrejected by the server and cannot accessrepository settings, while a collaborator granted
admincan.This is a documentation accuracy issue, not a security report. The API behaves safely and
predictably — it rejects unsupported values with an explicit
422rather than silentlysubstituting a different permission level. The problem is only that the documentation
understates what personal-account repositories support. That leads people to build
unnecessary workarounds, or to assume an access restriction is not being applied when in
fact it is.
Note on the web UI. As far as I can tell, the repository settings UI for a
personal-account repository does not expose a role selector for collaborators, so these
three levels appear to be reachable only through the REST API. That may well be why the
articles are worded as they are — they describe what the UI offers rather than what the
API accepts.
That leads to my actual question, which determines whether this behaviour can be relied
on: is accepting
pull,pushandadminon personal-account repositories intended andsupported behaviour that the docs should describe, or is it unintended behaviour that
happens to work today? Tools that manage repository access programmatically need to know
which, because the answer decides whether a read-only collaborator on a personal-account
repository is a guarantee or an accident.