| 1 | --- |
| 2 | title: Access and roles |
| 3 | description: The five repository roles and what each can do, the base permission members get, roles through teams, outside collaborators and invitations, who may manage deploy keys, and what agents may do on a person's behalf. |
| 4 | --- |
| 5 | |
| 6 | Everyone who can work in a repository has a role on it. The role says what |
| 7 | they can do there, from reading it to managing who else has access. A |
| 8 | workspace gives its members a role on every one of its repositories, a |
| 9 | repository can give anyone a role of their own: a member who needs more |
| 10 | there, or someone outside the workspace, and it can give a |
| 11 | [team](/guides/teams/) a role that everyone in the team has. |
| 12 | |
| 13 | ## The roles |
| 14 | |
| 15 | | Role | For | |
| 16 | | --- | --- | |
| 17 | | **Read** | Read and clone; open issues and pull requests, and comment. | |
| 18 | | **Triage** | Read, and manage issues and pull requests: label, assign, close. | |
| 19 | | **Write** | Triage, and push, merge, and put agents to work. | |
| 20 | | **Maintain** | Write, and manage the repository's settings and branch protection. | |
| 21 | | **Admin** | Everything: webhooks, secrets, deployments, who has access, and the repository's name, visibility and archiving. | |
| 22 | |
| 23 | Each role has everything the one above it has. |
| 24 | |
| 25 | ## What each role can do |
| 26 | |
| 27 | | | Read | Triage | Write | Maintain | Admin | |
| 28 | | --- | --- | --- | --- | --- | --- | |
| 29 | | See code, issues and pull requests; clone and fetch | Yes | Yes | Yes | Yes | Yes | |
| 30 | | Open issues and pull requests, and comment | Yes | Yes | Yes | Yes | Yes | |
| 31 | | Label, assign, close and reopen issues and pull requests | | Yes | Yes | Yes | Yes | |
| 32 | | Push to branches that are not protected | | | Yes | Yes | Yes | |
| 33 | | Merge pull requests and use the merge queue | | | Yes | Yes | Yes | |
| 34 | | Assign agents and start runs, plans and workflows | | | Yes | Yes | Yes | |
| 35 | | Change the description, topics, and pull request and agent settings | | | | Yes | Yes | |
| 36 | | Change branch protection and guardrails | | | | Yes | Yes | |
| 37 | | Manage webhooks, secrets, variables, deployments and domains | | | | | Yes | |
| 38 | | Manage who has access, invitations and deploy keys | | | | | Yes | |
| 39 | | Rename, archive, change visibility and the default branch | | | | | Yes | |
| 40 | | Transfer or delete the repository | | | | | Owners only | |
| 41 | |
| 42 | Transferring and deleting a repository also need an owner of its |
| 43 | workspace: someone given Admin on one repository cannot do either. Whoever |
| 44 | opened an issue or pull request can still edit and close their own, |
| 45 | whatever their role. |
| 46 | |
| 47 | Read and Triage cannot put agents to work, or start anything else that |
| 48 | spends compute: runs, plans, workflows and deployments need Write. |
| 49 | |
| 50 | ## How your role is worked out |
| 51 | |
| 52 | Your role on a repository is the highest of: |
| 53 | |
| 54 | 1. **Ownership.** An owner of the workspace has Admin on every repository |
| 55 | in it. |
| 56 | 2. **The base permission.** Every member of the workspace gets the |
| 57 | workspace's [base permission](#the-base-permission) on every repository |
| 58 | in it. |
| 59 | 3. **A role given to you on that repository.** See |
| 60 | [add someone to a repository](#add-someone-to-a-repository). |
| 61 | 4. **Your teams.** The role each [team](/guides/teams/) you are in has on |
| 62 | that repository, and the roles of that team's parent teams, which child |
| 63 | teams inherit. See [repository access](/guides/teams/#repository-access). |
| 64 | 5. **Public.** Anyone, signed in or not, can read a public repository. |
| 65 | |
| 66 | The highest wins. A member whose base permission is Read and who is given |
| 67 | Maintain on one repository has Maintain there and Read everywhere else. A |
| 68 | role lower than what you already have changes nothing. When a role given to |
| 69 | you and a team's role are the same, the one given to you is shown as where |
| 70 | it comes from. |
| 71 | |
| 72 | A workspace's own [access token](/guides/workspaces/#workspace-access-tokens) |
| 73 | has Write on its workspace's repositories, as a member does, and none on any |
| 74 | other. An owner can give one Admin instead, only when making it. A workflow |
| 75 | job's token and a [deploy key](/guides/git/#deploy-keys) have Write at most, |
| 76 | on their one repository. What is for people only, such as transferring or |
| 77 | deleting a repository, still needs a person. |
| 78 | |
| 79 | A [fine-grained personal access token](/guides/authentication/#create-a-fine-grained-token) |
| 80 | has your role only in its resource owner's repositories that it reaches: |
| 81 | all of them, the ones chosen, or none. Everywhere else it reads public |
| 82 | repositories, as anyone can, and does nothing more. A classic token has |
| 83 | your role wherever you have one, unless a workspace's |
| 84 | [rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens) |
| 85 | keep it out. |
| 86 | |
| 87 | ### Private repositories |
| 88 | |
| 89 | Someone without at least Read on a private repository cannot tell it |
| 90 | exists: its pages answer 404, and the API answers `404` with |
| 91 | `Repository not found.`, the same as for a repository that does not exist. |
| 92 | Someone who can read it but lacks the role for what they tried gets `403` |
| 93 | and a message naming the role they need: |
| 94 | |
| 95 | ```text |
| 96 | You need the Maintain role or higher on acme/rocket to do that. |
| 97 | ``` |
| 98 | |
| 99 | ### Git |
| 100 | |
| 101 | | | Needs | |
| 102 | | --- | --- | |
| 103 | | `git clone`, `fetch`, `pull` | Read | |
| 104 | | `git push` | Write | |
| 105 | |
| 106 | A [protected branch](/guides/git/#protected-branches) refuses pushes from |
| 107 | everyone, whatever their role, Admin included; changes reach it through |
| 108 | pull requests. |
| 109 | |
| 110 | ## The base permission |
| 111 | |
| 112 | The base permission is what every member of a workspace gets on every one |
| 113 | of its repositories: |
| 114 | |
| 115 | | Base permission | Members get | |
| 116 | | --- | --- | |
| 117 | | **None** | Nothing beyond what is public. Members see only the private repositories they are given a role on. | |
| 118 | | **Read** | Read on every repository. | |
| 119 | | **Write** | Write on every repository. The default. | |
| 120 | | **Admin** | Admin on every repository. Transferring and deleting stay with owners. | |
| 121 | |
| 122 | Owners always have Admin, whatever it says. Only owners can change it: |
| 123 | |
| 124 | 1. Open the workspace's **People** in the sidebar, `g1t.sh/<workspace>/-/people`. Every member can see it; owners manage it. |
| 125 | 2. Under **Base permission**, choose one. |
| 126 | |
| 127 | It takes effect on everyone's next request. To give one member more on |
| 128 | one repository, give them a role there; to give them less, lower the base |
| 129 | permission and give roles to the people who need them. |
| 130 | |
| 131 | ### What changed for existing members |
| 132 | |
| 133 | Before roles, every member of a workspace could also change a repository's |
| 134 | settings, its branch protection and guardrails, webhooks, secrets and |
| 135 | variables, deployments and domains. With the default base permission, |
| 136 | Write, members keep pushing, merging and putting agents to work; changing |
| 137 | settings and protection now needs Maintain, and the rest Admin. Owners |
| 138 | have Admin, so they keep all of it. |
| 139 | |
| 140 | To give members everything they had before, an owner sets the base |
| 141 | permission to **Admin**. They then also get what only owners could do |
| 142 | before: managing who has access, renaming and archiving repositories, and |
| 143 | changing their visibility and default branch. |
| 144 | |
| 145 | ## Add someone to a repository |
| 146 | |
| 147 | You need Admin on the repository and a confirmed email address. |
| 148 | |
| 149 | 1. Open the repository's **Settings → Access**, |
| 150 | `g1t.sh/<workspace>/<repo>/settings/access`. |
| 151 | 2. Under **Add people**, type a username or an email address. |
| 152 | 3. Pick their role and choose **Add**. |
| 153 | |
| 154 | Everyone with access is listed under **People with access**, with their |
| 155 | role and where it comes from: owner, the base permission, a role given to |
| 156 | them, or **Through team** and the team's slug. **Teams with access** lists the |
| 157 | teams given a role on it, with how many people each has. People with Write |
| 158 | or Maintain can see the lists; changing them needs Admin. |
| 159 | |
| 160 | Someone with Admin can give a team a role under **Teams with access**: |
| 161 | pick the team and its role, and add it. Only the workspace's own teams can |
| 162 | be added. See [teams](/guides/teams/#repository-access). |
| 163 | |
| 164 | What happens depends on who they are: |
| 165 | |
| 166 | | Who | What happens | |
| 167 | | --- | --- | |
| 168 | | A member of the workspace | They have the role at once. It matters only where it is higher than the base permission. | |
| 169 | | Someone else on g1t | They are sent an [invitation](#invitations) to accept. Typing the confirmed email address of someone on g1t does the same. | |
| 170 | | An email address with no g1t account | g1t emails an invite code that only that address can use. Signing up with it makes their account and accepts the invitation in one step. | |
| 171 | |
| 172 | An invite code to someone without an account uses one of the workspace's |
| 173 | granted invites, or else one of yours (see |
| 174 | [invites](/guides/authentication/#invites)), and works for 30 days. |
| 175 | |
| 176 | On a free workspace, only the first row works: its members can be given a |
| 177 | role, but nobody else can be invited until the workspace starts the g1t |
| 178 | plan. **Add people** says **Start the plan to invite people** above the |
| 179 | form, and an invitation is refused with `402` (`payment_required`). An |
| 180 | invitation sent before cannot be accepted until then. See |
| 181 | [who a free workspace can add](/guides/usage-and-billing/#who-a-free-workspace-can-add). |
| 182 | |
| 183 | To change someone's role, pick another beside their name. To take it away, |
| 184 | choose **Remove**. Removing takes away only the role given on this |
| 185 | repository: an owner's Admin, a member's base permission and what their |
| 186 | teams give them stay. Anyone |
| 187 | can remove their own role from a repository. Each change is confirmed |
| 188 | under the list; one that is refused says why on that person's row. |
| 189 | |
| 190 | ## Outside collaborators |
| 191 | |
| 192 | An outside collaborator has a role on some of a workspace's repositories |
| 193 | without being a member of it. They: |
| 194 | |
| 195 | - see the repositories shared with them under **Shared with you** in the |
| 196 | sidebar, and only those: not the workspace's other private |
| 197 | repositories, its members, settings, usage or billing. The workspace's |
| 198 | page, `g1t.sh/<workspace>`, shows them its public repositories and the |
| 199 | ones shared with them; |
| 200 | - can do on each repository what their role allows, and nothing in the |
| 201 | workspace itself, such as its webhooks, secrets, tokens or integrations; |
| 202 | - are held to whatever the workspace asks of its members, checked when |
| 203 | they are added, when they accept, and on every request after. |
| 204 | |
| 205 | - can put agents to work where they have Write; the runs are charged to |
| 206 | the repository's workspace, and they do not see which model ran or what |
| 207 | it cost. An agent working for them is told the project's memory, never |
| 208 | the workspace's. |
| 209 | |
| 210 | Owners see every outside collaborator, and the repositories and roles each |
| 211 | has, on the **Outside collaborators** tab of the workspace's |
| 212 | **People**. **Convert to member** adds one to the workspace |
| 213 | (see [members and roles](/guides/workspaces/#members-and-roles)); the |
| 214 | roles they have stay, and the base permission adds to them. |
| 215 | |
| 216 | Removing a member from a workspace also removes the roles they were given |
| 217 | on its repositories, and takes them out of its teams. |
| 218 | |
| 219 | ## Invitations |
| 220 | |
| 221 | An invitation to someone on g1t waits for them to answer, and they are |
| 222 | emailed a link to it. |
| 223 | |
| 224 | 1. Open `g1t.sh/<workspace>/<repo>/invitations`, the link in the email. |
| 225 | 2. Choose **Accept invitation** or **Decline**. |
| 226 | |
| 227 | Accepting gives you the role; you then find the repository under **Shared |
| 228 | with you**. An invitation lasts **7 days**, then expires. Until it is |
| 229 | answered, it is listed as pending on the repository's **Settings → Access**, |
| 230 | where someone with Admin can change its role or **Revoke** it. To invite |
| 231 | someone again after an expired or declined invitation, add them again. |
| 232 | |
| 233 | ## Agents |
| 234 | |
| 235 | An agent works with the role of the person it acts for, on the |
| 236 | repository it works in, and never more than Write. An owner's agent has |
| 237 | Write, not Admin. So an agent working for you can push, open and merge |
| 238 | pull requests where you can, and cannot change settings, protection, |
| 239 | webhooks or secrets, even when you can. |
| 240 | |
| 241 | An agent's credential can never change who has access: it cannot add, |
| 242 | remove or invite anyone, answer an invitation, or change the base |
| 243 | permission. When the person it works for loses their role on the |
| 244 | repository, or leaves the workspace, the agent loses it too. See |
| 245 | [credentials](/guides/working-with-g1t/#credentials). |
| 246 | |
| 247 | Because putting agents to work spends compute, it needs Write. Someone with |
| 248 | Read or Triage who mentions or assigns an agent is told so, and nothing |
| 249 | starts. |
| 250 | |
| 251 | ## Deploy keys |
| 252 | |
| 253 | A [deploy key](/guides/git/#deploy-keys) is an SSH key that lets a machine |
| 254 | reach one repository: Read, or Write when it was added with write access, |
| 255 | on that repository and no other. It is part of who has access, so managing |
| 256 | deploy keys needs the Admin role: |
| 257 | |
| 258 | | Who | Can list, add and delete a repository's deploy keys | |
| 259 | | --- | --- | |
| 260 | | Someone with the Admin role on it, owners included | Yes | |
| 261 | | Someone with Maintain or less | No | |
| 262 | | An agent, whoever it works for | No | |
| 263 | | A workspace's [access token](/guides/workspaces/#workspace-access-tokens) | Only when an owner gave it Admin | |
| 264 | | A deploy key | No | |
| 265 | |
| 266 | Adding one also needs a confirmed email address. A personal access token |
| 267 | needs the `access:read` scope to list and read them, and `access:admin` to |
| 268 | add and delete them. |
| 269 | |
| 270 | ## Through the API |
| 271 | |
| 272 | Every route is in the [API reference](/reference/api/). Each is also an |
| 273 | action of an [MCP tool](/reference/mcp/): `access` for a repository's |
| 274 | people, its deploy keys and the base permission, `account` for invitations to you. |
| 275 | |
| 276 | | Route | MCP tool and action | What it does | Who | |
| 277 | | --- | --- | --- | --- | |
| 278 | | `GET /repos/{owner}/{name}/collaborators` | `access` `list_collaborators` | Everyone with access to a repository, their role and where it comes from. | Write | |
| 279 | | `GET /repos/{owner}/{name}/collaborators/{username}/permission` | `access` `get_permission` | One person's role on a repository and what it lets them do. | Write, or about yourself | |
| 280 | | `POST /repos/{owner}/{name}/collaborators` | `access` `add_collaborator` | Give someone a role. Body: `invitee` (a username or an email address) and `role`. Answers with `result`: `granted` or `invited`. | Admin | |
| 281 | | `PATCH /repos/{owner}/{name}/collaborators/{username}` | `access` `update_collaborator` | Change someone's role, or a pending invitation's. Body: `role`. | Admin | |
| 282 | | `DELETE /repos/{owner}/{name}/collaborators/{username}` | `access` `remove_collaborator` | Take away the role given to someone on the repository. | Admin, or yourself | |
| 283 | | `GET /repos/{owner}/{name}/invitations` | `access` `list_invitations` | A repository's pending invitations. | Admin | |
| 284 | | `DELETE /repos/{owner}/{name}/invitations/{id}` | `access` `revoke_invitation` | Withdraw a pending invitation. | Admin | |
| 285 | | `GET /user/repository_invitations` | `account` `list_repository_invitations` | The invitations waiting for you. | You | |
| 286 | | `PATCH /user/repository_invitations/{id}` | `account` `accept_repository_invitation` | Accept one. | You | |
| 287 | | `DELETE /user/repository_invitations/{id}` | `account` `decline_repository_invitation` | Decline one. | You | |
| 288 | | `PUT /workspaces/{workspace}/base_permission` | `access` `set_base_permission` | Set the base permission. Body: `base_permission`: `none`, `read`, `write` or `admin`. `PATCH /workspaces/{workspace}` (`workspace` `update`) takes `base_permission` too, with the `access:admin` scope. | Owners | |
| 289 | | `GET /workspaces/{workspace}/outside_collaborators` | `access` `list_outside_collaborators` | A workspace's outside collaborators and the repositories each can reach. | Owners | |
| 290 | | `GET /repos/{owner}/{name}/keys` | `access` `list_deploy_keys` | A repository's [deploy keys](/guides/git/#deploy-keys). | Admin | |
| 291 | | `GET /repos/{owner}/{name}/keys/{id}` | `access` `get_deploy_key` | One deploy key. | Admin | |
| 292 | | `POST /repos/{owner}/{name}/keys` | `access` `add_deploy_key` | Add a deploy key. Body: `title`, `key` and `read_only` (true unless you send false). | Admin | |
| 293 | | `DELETE /repos/{owner}/{name}/keys/{id}` | `access` `remove_deploy_key` | Delete a deploy key. | Admin | |
| 294 | |
| 295 | Changing who has access, answering an invitation and setting the base |
| 296 | permission are for people, signed in or with a personal access token. |
| 297 | |
| 298 | Roles are written `read`, `triage`, `write`, `maintain` and `admin`. |
| 299 | |
| 300 | ```sh |
| 301 | curl https://api.g1t.sh/repos/acme/rocket/collaborators/ada/permission \ |
| 302 | -H "Authorization: Bearer $G1T_TOKEN" |
| 303 | ``` |
| 304 | |
| 305 | ```json |
| 306 | { |
| 307 | "username": "ada", |
| 308 | "role": "write", |
| 309 | "source": "base", |
| 310 | "capabilities": ["read", "participate", "triage", "push", "merge", "run"] |
| 311 | } |
| 312 | ``` |
| 313 | |
| 314 | `source` is `owner`, `base`, `direct` or `team`. In the list from |
| 315 | `list_collaborators`, each person also has `direct`, the role given to them |
| 316 | on the repository if any, and `team_role` and `team`: the highest role a |
| 317 | team gives them there, and that team's slug. A team's own roles are managed |
| 318 | through the [teams API](/guides/teams/#through-the-api). |
| 319 | |
| 320 | ## Webhooks and the audit log |
| 321 | |
| 322 | A change to someone's role on a repository is sent to |
| 323 | [webhooks](/guides/webhooks/) as one of: |
| 324 | |
| 325 | | Event | When | |
| 326 | | --- | --- | |
| 327 | | `repo.collaborator_added` | Someone was given a role on the repository, or accepted an invitation. | |
| 328 | | `repo.collaborator_role_changed` | Their role changed. `data.role` and `data.previous_role`. | |
| 329 | | `repo.collaborator_removed` | Their role was taken away. | |
| 330 | |
| 331 | Each has `data.username`, `data.role` and `data.previous_role`. |
| 332 | |
| 333 | The workspace's [audit log](/guides/audit-log/) records the same changes |
| 334 | under those names, and also `repo.invitation_created`, |
| 335 | `repo.invitation_revoked`, `workspace.base_permission_changed`, and |
| 336 | `repo.deploy_key_added` and `repo.deploy_key_removed` for |
| 337 | [deploy keys](#deploy-keys). |
| 338 | |
| 339 | A team's role on a repository changing is sent as `team.repo_added`, |
| 340 | `team.repo_role_changed` or `team.repo_removed`; see |
| 341 | [teams](/guides/teams/#webhooks-and-the-audit-log). |