| 1 | --- |
| 2 | title: Accounts and authentication |
| 3 | description: Accounts, invites, email addresses, confirming them, two-factor authentication and recovery codes, personal access tokens and their permissions and scopes, a workspace's rules for tokens, OAuth, signing in from a tool, password reset, your security log and deleting your account. |
| 4 | --- |
| 5 | |
| 6 | ## Creating an account |
| 7 | |
| 8 | g1t is invite-only for now: to make an account you need an |
| 9 | [invite](#invites). Open the link in your invite, or enter its code at |
| 10 | [g1t.sh/register](https://g1t.sh/register). Without one, ask for access |
| 11 | on the same page. |
| 12 | |
| 13 | Usernames are letters, digits and single hyphens, 1 to 39 characters, not |
| 14 | starting or ending with a hyphen. They keep the case you type: choose |
| 15 | `Ana-Lopez` and your profile, menus and cards show `Ana-Lopez`. Case never |
| 16 | makes a different name, though: `ana-lopez` is the same person and can't |
| 17 | be registered by anyone else, signing in works in any case, |
| 18 | `g1t.sh/u/ANA-LOPEZ` opens the same profile, and an `@ana-lopez` mention |
| 19 | reaches you. Addresses and git URLs use the lowercase form. Reserved words |
| 20 | (such as `settings`, `api` or `g1t`) are reserved in every case. |
| 21 | |
| 22 | Before you can do anything else, you [confirm your email |
| 23 | address](#confirming-your-email-address) with the code g1t emails you, |
| 24 | unless you signed up from the link in an invite g1t emailed to that address |
| 25 | (see [invites from your inbox](#invites-from-your-inbox)). |
| 26 | |
| 27 | Accounts can only be created in a browser. There is no API for it, by |
| 28 | design: it keeps passwords out of scripts and agents, and lets g1t protect |
| 29 | the one place accounts are made. |
| 30 | |
| 31 | ## Your settings |
| 32 | |
| 33 | Your own settings are at [g1t.sh/settings](https://g1t.sh/settings), one |
| 34 | page each. Open them from your account menu at the bottom of the sidebar, |
| 35 | under **Your settings**; the sidebar then lists every page. |
| 36 | |
| 37 | | Page | Address | What is on it | |
| 38 | | --- | --- | --- | |
| 39 | | Profile | [`/settings/profile`](https://g1t.sh/settings/profile) | Your picture, and your [public profile](/guides/workspaces/#profiles): name, pronouns, bio, location, website and time zone. | |
| 40 | | Emails | [`/settings/emails`](https://g1t.sh/settings/emails) | Your [email addresses](#email-addresses), the backup address, and [keeping your address private](#keeping-your-address-private). | |
| 41 | | Invites to g1t | [`/settings/invites`](https://g1t.sh/settings/invites) | [Making, copying and revoking invites to g1t](#making-invites), while g1t is invite-only; after that, the invites you made. | |
| 42 | | SSH keys | [`/settings/keys`](https://g1t.sh/settings/keys) | Public keys for [git over SSH](/guides/git/#ssh), each with when it was added and last used. | |
| 43 | | Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens): their permissions, where they reach, and when they expire. | |
| 44 | | Integrations | [`/settings/integrations`](https://g1t.sh/settings/integrations) | [Your own integrations](/guides/integrations/#workspace-and-personal): what you have connected for yourself, in every workspace, and what is coming. | |
| 45 | | GitHub | [`/settings/github`](https://g1t.sh/settings/github) | [Linking and unlinking GitHub](/guides/github/#link-and-unlink-github). | |
| 46 | | Connected applications | [`/settings/applications`](https://g1t.sh/settings/applications) | Tools you [signed in to with OAuth](#signing-in-with-oauth), such as an agent using the MCP server. | |
| 47 | | Two-factor authentication | [`/settings/two-factor`](https://g1t.sh/settings/two-factor) | [An authenticator app and recovery codes](#two-factor-authentication). | |
| 48 | | Security log | [`/settings/security-log`](https://g1t.sh/settings/security-log) | [What happened to your account](#security-log). | |
| 49 | | Account | [`/settings/account`](https://g1t.sh/settings/account) | Your username, and [deleting your account](#deleting-your-account). | |
| 50 | |
| 51 | `g1t.sh/settings` opens Profile. |
| 52 | |
| 53 | ## Signing in with GitHub |
| 54 | |
| 55 | **Continue with GitHub** on the sign-in and sign-up pages signs you in with |
| 56 | your GitHub account, and makes a g1t account the first time. Link or |
| 57 | unlink GitHub in [Settings → GitHub](https://g1t.sh/settings/github). See |
| 58 | [GitHub](/guides/github/#sign-in-with-github). |
| 59 | |
| 60 | Making an account with GitHub needs an invite too: start from your invite |
| 61 | link, or enter the code when g1t asks for it after GitHub. |
| 62 | |
| 63 | With [two-factor authentication](#two-factor-authentication) on, signing in |
| 64 | with GitHub asks for a code from your app as well. |
| 65 | |
| 66 | ## Two-factor authentication |
| 67 | |
| 68 | Two-factor authentication asks for a code from an authenticator app on |
| 69 | your phone each time you sign in with your password or with GitHub, so a |
| 70 | stolen password is not enough. Any app that reads a time-based one-time |
| 71 | password (TOTP) QR code works, such as 1Password, Google Authenticator or |
| 72 | Authy. |
| 73 | |
| 74 | ### Turn it on |
| 75 | |
| 76 | 1. Open [Settings → Two-factor authentication](https://g1t.sh/settings/two-factor) |
| 77 | and choose **Set up**. g1t asks for your password if you have not |
| 78 | signed in in the last 10 minutes. |
| 79 | 2. Scan the QR code with your app, or type the key shown under it. |
| 80 | 3. Enter the six-digit code the app shows, and choose **Turn on**. |
| 81 | 4. Save the ten recovery codes g1t shows. They are shown only then. |
| 82 | |
| 83 | ### Signing in with it on |
| 84 | |
| 85 | After your password (or GitHub), g1t asks for the code from your app. A |
| 86 | code works for 30 seconds, and the one before and after it are accepted |
| 87 | too, for a phone clock a little off. Each code works once. After five wrong |
| 88 | codes, or ten minutes, start the sign-in again. |
| 89 | |
| 90 | Lost your phone? Enter a recovery code instead of the app's code. Each |
| 91 | works once, and your security log records its use. |
| 92 | |
| 93 | Git over HTTPS never takes your password while two-factor authentication |
| 94 | is on: use a [personal access token](#access-tokens) as the password, or |
| 95 | [SSH](/guides/git/). Access tokens, SSH keys and OAuth applications are |
| 96 | not affected. |
| 97 | |
| 98 | ### Recovery codes, and turning it off |
| 99 | |
| 100 | On the same page: |
| 101 | |
| 102 | - **Make new recovery codes** replaces all ten; the old ones stop working. |
| 103 | - **Turn off** needs a code from your app or a recovery code, and your |
| 104 | password if you have not signed in in the last 10 minutes. |
| 105 | |
| 106 | You cannot turn it off while you own a workspace that |
| 107 | [requires it](/guides/workspaces/#require-two-factor-authentication): stop |
| 108 | requiring it there first, or hand the workspace to another owner. In a |
| 109 | workspace that requires it, turning it off holds you out of that workspace |
| 110 | until you turn it on again. |
| 111 | |
| 112 | Turning it on or off, and making new recovery codes, are emailed to your |
| 113 | primary and backup addresses, written to your [security log](#security-log), |
| 114 | and recorded in the [audit log](/guides/audit-log/) of each of your |
| 115 | workspaces as `two_factor.enabled` and `two_factor.disabled`. |
| 116 | |
| 117 | ### Require two-factor authentication |
| 118 | |
| 119 | An owner can require it of everyone with access to a workspace. See |
| 120 | [Workspaces](/guides/workspaces/#require-two-factor-authentication). |
| 121 | |
| 122 | Passkeys are not supported yet; they are next. |
| 123 | |
| 124 | ## Invites |
| 125 | |
| 126 | There are two kinds of invite, and they do different things: |
| 127 | |
| 128 | | | Invite to g1t | Invite to a workspace | |
| 129 | | --- | --- | --- | |
| 130 | | Made from | [Settings → Invites](https://g1t.sh/settings/invites), your own | The workspace's **People** page, by its owners | |
| 131 | | What it gives | One new account. It adds them to no workspace: the account gets a workspace of its own | An invitation to join that workspace, which they accept or decline | |
| 132 | | Someone without an account | Makes their account with it | Makes their account with it too, while g1t is invite-only, then answers the invitation | |
| 133 | | Someone already on g1t | Nothing: they have an account | The invitation, in their notifications and by email | |
| 134 | | Exists | Only while g1t is invite-only | Always | |
| 135 | | What its page and email say | "@syntaqx invited you to g1t" | "@syntaqx invited you to join Flagon, Inc. on g1t" | |
| 136 | |
| 137 | So you can invite someone to g1t without inviting them into any |
| 138 | workspace; an invite to g1t only adds them to a workspace when you tick |
| 139 | **Also invite them to a workspace** (see [making invites](#making-invites)). |
| 140 | |
| 141 | While g1t is invite-only, every new account needs an invite code, such as |
| 142 | `g1t-k7m2-q9xd-…`. People already on g1t make them, and g1t sends them to |
| 143 | people who [asked for access](#asking-for-access). An invite: |
| 144 | |
| 145 | - works once, for one new account; |
| 146 | - works for 30 days; |
| 147 | - when it was made for an email address, works only with that address; |
| 148 | - can be revoked by whoever made it until it is used, and after that until |
| 149 | the new account [confirms its email address](#confirming-your-email-address). |
| 150 | |
| 151 | ### Using an invite |
| 152 | |
| 153 | Every invite email links to `g1t.sh/invite/<code>`. That one page shows |
| 154 | who sent it and what it is for (joining a workspace, collaborating on a |
| 155 | repository, or just making an account), and finishes the job there: |
| 156 | |
| 157 | 1. **No account yet**: sign up on the page. When the invite was sent to |
| 158 | your address, the email field is filled in and locked. Choose a |
| 159 | username (one is suggested from your address) and a password. If you |
| 160 | opened the page from the invite email itself, the address is already |
| 161 | confirmed and you go straight in (see |
| 162 | [invites from your inbox](#invites-from-your-inbox)); otherwise |
| 163 | [confirm the address](#confirming-your-email-address) with the code g1t |
| 164 | emails it. Or select **Continue with GitHub**: the invite rides along, |
| 165 | and the account uses the invited address when GitHub has verified it |
| 166 | too, in which case no confirmation is needed. |
| 167 | 2. **The address already has an account**: select **Sign in to accept**. |
| 168 | After you sign in, the invite is accepted for you. |
| 169 | 3. **Signed in as someone else**: an invite sent to one address works only |
| 170 | for an account that has confirmed that address. The page says so and |
| 171 | offers **Sign out and continue**. |
| 172 | |
| 173 | Nobody joins a workspace without saying yes. With an existing account, |
| 174 | accepting on the invite's page is that yes: you land in the workspace (or |
| 175 | the repository) the invite was for, with a one-time "You're in" banner, |
| 176 | and it becomes the workspace your sidebar shows. |
| 177 | |
| 178 | A new account made from an invite that names a workspace is invited to |
| 179 | it: once the account's address is confirmed, g1t takes you to |
| 180 | [g1t.sh/invitations](https://g1t.sh/invitations), where you |
| 181 | [accept or decline](#workspace-invitations) it. Until you answer, you have |
| 182 | no workspace of your own, so you never end up with two. An invite that |
| 183 | names no workspace gives the new account a workspace of its own instead; |
| 184 | see [your first workspace](#your-first-workspace). |
| 185 | |
| 186 | Signing up spends the invite at once, so nobody else can use it while you |
| 187 | confirm your address. Until you confirm, the invite shows as **confirming |
| 188 | their email** to whoever made it, and they can still revoke it. If the |
| 189 | invite is revoked or expires, or its workspace is deleted, before you |
| 190 | confirm, your address is confirmed all the same and g1t tells you the |
| 191 | invite no longer applies: ask whoever invited you to invite you again. A |
| 192 | code typed at [g1t.sh/register](https://g1t.sh/register) goes to the |
| 193 | same page. |
| 194 | |
| 195 | An expired, revoked or used invite says which, and who sent it, so you |
| 196 | can ask them for a new one; or ask for access from the same page. |
| 197 | |
| 198 | ### Invites from your inbox |
| 199 | |
| 200 | When g1t emails an invite to an address (an invite you make for someone, |
| 201 | an owner's invite into a workspace or a repository, or an approved |
| 202 | [request for access](#asking-for-access)), the link in that email carries a |
| 203 | `proof` that only the email has: `g1t.sh/invite/<code>?proof=…`. Opening |
| 204 | the link shows that you can read that inbox, so: |
| 205 | |
| 206 | - the invite page says the address is confirmed because you came from the |
| 207 | invite email, and the email field stays locked to it; |
| 208 | - your new account starts with the address confirmed: no code is sent. A |
| 209 | repository the invite was for is yours straight away; a workspace it |
| 210 | names is a [workspace invitation](#workspace-invitations) you accept or |
| 211 | decline straight away, since nobody joins a workspace without saying yes. |
| 212 | |
| 213 | Anything else confirms the address the usual way, after you sign up: the |
| 214 | code typed at [g1t.sh/register](https://g1t.sh/register), an invite link |
| 215 | copied from **Settings → Invites** (whoever made the invite sees the code, |
| 216 | never the proof), an invite made for anyone with the link, or an invite |
| 217 | email sent before this existed. The proof is tied to one invite and its |
| 218 | address, and stops working when the invite is used, revoked or expires. |
| 219 | |
| 220 | ### Invite links for a group |
| 221 | |
| 222 | g1t sometimes hands one link to a group: an event's judges, readers of a |
| 223 | post, a community. It looks like |
| 224 | `https://g1t.sh/register?invite=g1t-k7m2-…` and opens sign-up with the |
| 225 | code filled in and the group named above the form, such as **Invited as |
| 226 | part of Launch week judges**. |
| 227 | |
| 228 | - **It makes your own account.** Each person who uses it gets a new |
| 229 | account, and then makes their own workspace. It does not add you to |
| 230 | anyone else's workspace; once you are in, a workspace's owners can add |
| 231 | you from its People page. |
| 232 | - **It may be for some email domains only.** When it is, the email field |
| 233 | says which, such as `example.com`, and sign-up takes only an address |
| 234 | there. Use your address at that organization; you confirm it like any |
| 235 | other. |
| 236 | - **It works a set number of times, until a set day.** Once every place |
| 237 | is taken, or the day has passed, or g1t has stopped it, the link gets |
| 238 | the same answer as any invite that cannot be used. Ask whoever shared |
| 239 | it, or [ask for access](#asking-for-access). |
| 240 | |
| 241 | Using the link spends one place in the same step that makes your account, |
| 242 | so two people signing up at the same moment can never take more places |
| 243 | than it has. Anyone with an account can still [make invites](#making-invites) |
| 244 | of their own; group links are made by g1t staff only. |
| 245 | |
| 246 | ### Making invites |
| 247 | |
| 248 | These are invites to g1t. They let one person make an account, and add |
| 249 | them to no workspace unless you say so. |
| 250 | |
| 251 | 1. Open [Settings → Invites](https://g1t.sh/settings/invites) (**Invites |
| 252 | to g1t** in your settings and account menu). |
| 253 | 2. Optionally enter the email address of the person you are inviting. |
| 254 | With one, g1t emails them the invite, and only that address can use it. |
| 255 | Without one, anyone with the link can, once. |
| 256 | 3. Optionally tick **Also invite them to a workspace**, then choose the |
| 257 | workspace and the role (**Member** or **Owner**) they are invited with. |
| 258 | It is off to start with, and no workspace is chosen for you, not even |
| 259 | the one you are in. |
| 260 | 4. Select **Create invite**, then copy the link. |
| 261 | |
| 262 | Left unticked, the invite is to g1t only: the new account gets a |
| 263 | [workspace of its own](#your-first-workspace). Ticked, the new account |
| 264 | gets a [workspace invitation](#workspace-invitations) to the workspace you |
| 265 | chose once its address is confirmed, and is not given a workspace of its |
| 266 | own. The list of workspaces holds the ones you can add members to: the ones |
| 267 | you own that are on the g1t plan. A workspace on the free plan cannot add |
| 268 | people, so it is not offered, and the form says so when it is the one you |
| 269 | are in. |
| 270 | |
| 271 | To bring someone into a workspace, you do not need an invite to g1t: |
| 272 | invite them from the workspace's People page instead (see |
| 273 | [inviting someone into a workspace](#inviting-someone-into-a-workspace)). |
| 274 | Settings → Invites links to the People pages of the workspaces you own. |
| 275 | |
| 276 | Once anyone can sign up for g1t, there are no invites to g1t to make: |
| 277 | Settings → Invites keeps only the list of invites you already made, and |
| 278 | says that anyone can sign up now and that workspace invitations live on |
| 279 | each workspace's People page. With no invites made, the page is not listed |
| 280 | in your settings or account menu. |
| 281 | |
| 282 | Each person can have **5** invites out at a time. Pending and used invites |
| 283 | count; an invite you revoke, or one that expires before anyone uses it, |
| 284 | comes back to you. The list under the form shows each invite's state: |
| 285 | pending, confirming their email (used to sign up by someone who has not |
| 286 | confirmed their address yet), waiting for them to accept (the account is |
| 287 | made and confirmed, and the workspace invitation waits for its answer), |
| 288 | joined (with the username of who joined), declined, expired or revoked. You |
| 289 | must confirm your email before you can make invites. An agent's token and |
| 290 | a workspace's token cannot make them. |
| 291 | |
| 292 | ### Inviting someone into a workspace |
| 293 | |
| 294 | An owner can invite someone into a workspace from its People page, by |
| 295 | username or by email address, with the role they join as; see |
| 296 | [add people](/guides/workspaces/#add-people). Nobody is added without |
| 297 | saying yes: someone on g1t gets a [workspace invitation](#workspace-invitations) |
| 298 | to accept or decline. When an address has no g1t account, the invitation |
| 299 | also lets it make one first, and the invitation is answered once the |
| 300 | account's address is confirmed (at once when it was made from the invite |
| 301 | email's link). While g1t is invite-only, that uses one invite: one of the |
| 302 | workspace's shared invites when it has any, otherwise one of yours. Once |
| 303 | anyone can sign up, it costs nothing. Inviting someone who is already on |
| 304 | g1t never costs anything. |
| 305 | |
| 306 | ### Workspace invitations |
| 307 | |
| 308 | A workspace invitation asks one account to join one workspace, with the |
| 309 | role chosen when it was sent. You hear of it in your notifications and by email, |
| 310 | and answer it at [g1t.sh/invitations](https://g1t.sh/invitations): |
| 311 | |
| 312 | - **Accept** joins the workspace with that role, and takes you there. |
| 313 | - **Decline** joins nothing; whoever invited you is told in their notifications. |
| 314 | |
| 315 | An invitation works for 30 days, the same as an invite. Until it is |
| 316 | answered, the workspace's owners see it under **Pending invitations** on |
| 317 | its People page and can revoke it. A workspace on the free plan cannot add |
| 318 | people, so an invitation to one cannot be accepted until it starts the |
| 319 | plan. Only you can answer your invitations: an agent's token and a |
| 320 | workspace's token cannot. |
| 321 | |
| 322 | ### Your first workspace |
| 323 | |
| 324 | Everything on g1t lives in a workspace, so every new account gets one: |
| 325 | |
| 326 | - An account whose invite brings it into a workspace gets the invitation |
| 327 | to it, and no workspace of its own. |
| 328 | - Every other account (signed up with a password, with GitHub, from a |
| 329 | shared invite link or an invite from g1t staff, or with an invite that |
| 330 | names no workspace) gets a workspace of its own, named for its username, |
| 331 | on the free plan. Rename it or start the plan on it whenever you like. |
| 332 | |
| 333 | Signed in without any workspace (you declined an invitation, or left the |
| 334 | only workspace you were in), g1t shows **Create your workspace or ask to |
| 335 | join one** in place of Mission control: the invitations waiting for you, if |
| 336 | any, and the form to create a workspace. To join a team already on g1t, |
| 337 | ask one of its owners to invite you by your username. |
| 338 | |
| 339 | ### Need more invites? |
| 340 | |
| 341 | Write to [hey@flagon.io](mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20) |
| 342 | with the subject `[g1t Invites]` and say who you would like to bring. g1t |
| 343 | can give more invites to you, or to a workspace, whose owners then share |
| 344 | them. Invites given to a workspace appear under |
| 345 | [Settings → Invites](https://g1t.sh/settings/invites) for |
| 346 | each of its owners, as a choice of whose invites to use. |
| 347 | |
| 348 | ### Asking for access |
| 349 | |
| 350 | Without an invite, [g1t.sh/register](https://g1t.sh/register) asks for your |
| 351 | email address and, if you like, what you will build. g1t emails that |
| 352 | address once to confirm you are on the list, and staff see the request |
| 353 | straight away. When they approve it, the invite comes to the same address, |
| 354 | sometimes with a note, and its link opens sign-up with the address filled |
| 355 | in. There is no fixed date: g1t opens up a few people at a time. Asking |
| 356 | again with the same address updates your request without another email; it |
| 357 | does not move you down the list. |
| 358 | |
| 359 | ### Invites through the API |
| 360 | |
| 361 | | Route | MCP tool and action | What it does | |
| 362 | | --- | --- | --- | |
| 363 | | [`GET /user/invites`](/reference/api/invites/list-invites/) | `account` `list_invites` | Your invites and how many you have left | |
| 364 | | [`POST /user/invites`](/reference/api/invites/create-invite/) | `account` `create_invite` | Make an invite, optionally for one `email`; with `workspace` (a slug), the new account is invited to that workspace | |
| 365 | | [`DELETE /user/invites/{id}`](/reference/api/invites/revoke-invite/) | `account` `revoke_invite` | Revoke a pending invite, or one whose new account has not confirmed its address | |
| 366 | | [`POST /workspaces/{workspace}/invitations`](/reference/api/invites/invite-member/) | `workspace` `invite_member` | Invite a `username` or an `email` into a workspace, with a `role`. Owners only. | |
| 367 | | [`GET /user/invitations`](/reference/api/invites/list-invitations/) | `account` `list_workspace_invitations` | The workspace invitations waiting for your answer | |
| 368 | | [`POST /user/invitations/{id}/accept`](/reference/api/invites/accept-invitation/) | `account` `accept_workspace_invitation` | Join the invitation's workspace with its role | |
| 369 | | [`POST /user/invitations/{id}/decline`](/reference/api/invites/decline-invitation/) | `account` `decline_invitation` | Decline it; whoever sent it is told | |
| 370 | |
| 371 | ## Confirming your email address |
| 372 | |
| 373 | A new account confirms its email address before it can do anything else on |
| 374 | g1t, unless it already has (it was made with GitHub, or from the link in |
| 375 | its invite email). Right after you sign up, g1t emails the address from `noreply@g1t.sh` |
| 376 | with two ways to confirm it, either one enough: |
| 377 | |
| 378 | - a **six-digit code**, shown large in the email (and in its subject, so a |
| 379 | phone's notification shows it). Type it on the **Confirm your email** |
| 380 | page g1t takes you to. On a phone, the keyboard offers it from the |
| 381 | message. |
| 382 | - a **link**, for when you would rather click than type. It works whether |
| 383 | or not you are signed in, in any browser. |
| 384 | |
| 385 | The code and the link work for **60 minutes**, once. Using either ends the |
| 386 | other. **Send a new code** on the confirmation page sends a fresh code and |
| 387 | link, at most once a minute and 10 times an hour, and the ones before stop |
| 388 | working. |
| 389 | |
| 390 | | On the confirmation page | What it does | |
| 391 | | --- | --- | |
| 392 | | **Confirm email** | Checks the code. A wrong, used or expired code gets the same answer. After 10 wrong codes in an hour, codes for the account are not checked for a while (a minute, then longer); the link in the email still works. Wrong codes from one network are limited the same way. | |
| 393 | | **Send a new code** | A new code and link; the ones before stop working. | |
| 394 | | **Wrong address? Change it** | Replaces the address you signed up with and sends the new one a code. Only while the account has no confirmed address. | |
| 395 | | **Sign out** | Signs out. Sign in again to come back to the page. | |
| 396 | |
| 397 | ### Until you confirm |
| 398 | |
| 399 | An account that has not confirmed its address can only confirm it: |
| 400 | |
| 401 | - **The site** sends every page to the confirmation page, and back to where |
| 402 | you were going once you confirm. Signing in and out, password resets, |
| 403 | the confirmation link, and g1t's [policies](https://g1t.sh/policies), |
| 404 | security, support, status and pricing pages stay open. |
| 405 | - **The API** answers `403` with a message saying to confirm your address, |
| 406 | except for [`GET /user`](/reference/api/accounts/whoami/), |
| 407 | [`GET /user/emails`](/reference/api/accounts/list-emails/) and |
| 408 | [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/). |
| 409 | - **The MCP server** answers `403` with the same message. |
| 410 | - **Git** over HTTPS refuses pushes and fetches with your credentials, with |
| 411 | the same message. Package registries treat them as wrong credentials. |
| 412 | - You cannot create a workspace, answer the invitation your invite brought, make |
| 413 | invites or tokens, or approve a tool's sign-in. |
| 414 | |
| 415 | You cannot make a token before you confirm, so the API and MCP refusals |
| 416 | matter only for an account that made one before this rule existed. |
| 417 | |
| 418 | ### Addresses GitHub has confirmed |
| 419 | |
| 420 | An account made with **Continue with GitHub** starts confirmed: its address |
| 421 | is one GitHub has verified, so GitHub has already proved the inbox is |
| 422 | yours, and no code is sent. |
| 423 | |
| 424 | ### Addresses an invite email has confirmed |
| 425 | |
| 426 | An account made from the link in the invite g1t emailed to its address |
| 427 | starts confirmed the same way: following that link proved the inbox is |
| 428 | yours. It works only for the address the invite was sent to, and only from |
| 429 | the email's own link; see [invites from your inbox](#invites-from-your-inbox). |
| 430 | |
| 431 | ### Accounts that never confirmed |
| 432 | |
| 433 | Accounts are confirmed once and stay confirmed. An account made before this |
| 434 | rule that never confirmed its address, or whose address another account |
| 435 | confirmed first, is held at the confirmation page the same way the next |
| 436 | time it signs in; **Send a new code** gets it a code, and **Change it** |
| 437 | gives it a new address. |
| 438 | |
| 439 | ### Confirming through the API |
| 440 | |
| 441 | | Route | MCP tool and action | What it does | |
| 442 | | --- | --- | --- | |
| 443 | | [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/) | `account` `confirm_email` | Confirm an address with the `code` from its email | |
| 444 | |
| 445 | The answer says whether the account is now confirmed (`verified`), the |
| 446 | workspace its invite invites it to (`invited_to`: accept or decline it with |
| 447 | [`POST /user/invitations/{id}/accept`](/reference/api/invites/accept-invitation/) |
| 448 | or [`/decline`](/reference/api/invites/decline-invitation/)), or why its |
| 449 | invite no longer applies (`invite_lapsed`). `joined` is always null: nothing |
| 450 | is joined without an answer. |
| 451 | |
| 452 | ## Email addresses |
| 453 | |
| 454 | An account can have up to 10 email addresses. Manage them in |
| 455 | [Settings → Emails](https://g1t.sh/settings/emails). |
| 456 | |
| 457 | | An address that is | Can | |
| 458 | | --- | --- | |
| 459 | | Primary | Get account mail and password reset links. Exactly one, always confirmed once any address is. | |
| 460 | | Confirmed | Sign you in (type it instead of your username), ask for a password reset, and mark commits that carry it as yours. | |
| 461 | | Backup | Get security notices as well as the primary. Optional, and a confirmed address other than the primary. | |
| 462 | | Unconfirmed | Nothing yet. It is not yours until you enter the code or follow the link g1t sent it. | |
| 463 | |
| 464 | A confirmed address belongs to one account. Anyone can add an address they |
| 465 | have not confirmed; the first account to confirm it keeps it, and the |
| 466 | address leaves every other account that added it. An address another |
| 467 | account has confirmed cannot be added. |
| 468 | |
| 469 | ### Add an address |
| 470 | |
| 471 | 1. Open [Settings → Emails](https://g1t.sh/settings/emails). |
| 472 | 2. Enter the address under **Add an email address** and select **Add**. |
| 473 | 3. Enter the code g1t emails it, or follow the link in the same email. |
| 474 | Both work for 60 minutes; **Resend link** sends a new code and link, at |
| 475 | most once a minute and 10 times an hour, and ends the ones before. |
| 476 | |
| 477 | If your account had no confirmed address yet, the first one you confirm |
| 478 | becomes your primary. |
| 479 | |
| 480 | ### Choose your primary and backup |
| 481 | |
| 482 | Select **Make primary** beside a confirmed address. Under **Backup |
| 483 | address**, choose a confirmed address to get security notices too, or |
| 484 | **Primary address only**. |
| 485 | |
| 486 | ### Remove an address |
| 487 | |
| 488 | Select **Remove** beside it. You cannot remove your primary address (make |
| 489 | another one primary first) or your last confirmed address. |
| 490 | |
| 491 | ### Confirming it is you |
| 492 | |
| 493 | Adding or removing an address, changing your primary or backup, and |
| 494 | turning two-factor authentication on or off, need proof that it is you: a |
| 495 | sign-in in the last 10 minutes, or your password, |
| 496 | which g1t asks for on the page. After you enter it, g1t does not ask again |
| 497 | for 10 minutes. An account that signs in only with GitHub signs out and in |
| 498 | with GitHub again, or sets a password with |
| 499 | [Forgot your password](https://g1t.sh/forgot). |
| 500 | |
| 501 | Each of these changes is emailed to every confirmed address on the account, |
| 502 | including an address that was just removed, and written to your |
| 503 | [security log](#security-log). |
| 504 | |
| 505 | ### Keeping your address private |
| 506 | |
| 507 | **Keep my email address private** is on for every account unless you turn |
| 508 | it off. While it is on, commits g1t makes for you (merging a pull request |
| 509 | on the web, catching a branch up, and commits an agent makes for you) carry |
| 510 | your noreply address instead of your primary: |
| 511 | |
| 512 | ``` |
| 513 | <8 characters of your account id>+<username>@users.noreply.g1t.sh |
| 514 | ``` |
| 515 | |
| 516 | The page shows yours. It never receives mail. Turn the setting off to put |
| 517 | your primary address on those commits instead. |
| 518 | |
| 519 | **Block pushes that expose my email** refuses a push that would publish one |
| 520 | of your addresses while you keep it private. When both settings are on, |
| 521 | g1t reads the new commits in each push you make, and declines the push if |
| 522 | any of them has one of your confirmed addresses as its author or committer |
| 523 | address. git shows why, with the address masked: |
| 524 | |
| 525 | ``` |
| 526 | remote: push declined: commit 3f9a1c2 would publish s***@gmail.com while your email is private. |
| 527 | remote: Commit with 6c1d0efg+sam@users.noreply.g1t.sh (git config user.email 6c1d0efg+sam@users.noreply.g1t.sh) and amend, |
| 528 | remote: or change this in g1t.sh/settings/emails. |
| 529 | ``` |
| 530 | |
| 531 | To push those commits: |
| 532 | |
| 533 | 1. Set your noreply address for the repository: |
| 534 | `git config user.email <your noreply address>`. |
| 535 | 2. Rewrite the commits with it. For the last commit, |
| 536 | `git commit --amend --reset-author --no-edit`; for several, |
| 537 | `git rebase <base> --exec "git commit --amend --reset-author --no-edit"`. |
| 538 | 3. Push again. |
| 539 | |
| 540 | Only your own addresses are checked: commits by other people in the same |
| 541 | push go through, and so does your noreply address. A push an agent makes |
| 542 | for you follows your settings. |
| 543 | |
| 544 | ### How commits are attributed |
| 545 | |
| 546 | g1t shows a commit as yours, with your picture and a link to your profile, |
| 547 | when its author address is one of your confirmed addresses or your noreply |
| 548 | address. Commits that g1t made for you before noreply addresses existed |
| 549 | (`<username>@users.g1t.sh`) count as yours too. An unconfirmed address |
| 550 | never attributes a commit, so nobody can claim your commits by adding your |
| 551 | address. Commits whose address matches no account show the name in the |
| 552 | commit. See [Commits and your account](/guides/workspaces/#commits-and-your-account) |
| 553 | for setting your noreply address in git. |
| 554 | |
| 555 | ### Email addresses through the API |
| 556 | |
| 557 | | Route | MCP tool and action | What it does | |
| 558 | | --- | --- | --- | |
| 559 | | [`GET /user/emails`](/reference/api/accounts/list-emails/) | `account` `list_emails` | Your addresses and email settings | |
| 560 | | [`POST /user/emails`](/reference/api/accounts/add-email/) | `account` `add_email` | Add an address; takes `email` and `password` | |
| 561 | | [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/) | `account` `confirm_email` | Confirm an address with the `code` from its email | |
| 562 | | [`DELETE /user/emails/{email}`](/reference/api/accounts/remove-email/) | `account` `remove_email` | Remove an address; takes `password` | |
| 563 | | [`PATCH /user/email-settings`](/reference/api/accounts/update-email-settings/) | `account` `update_email_settings` | Change `primary`, `backup`, `private_email` or `block_private_pushes` | |
| 564 | |
| 565 | Through the API, `password` is the proof a sensitive change needs. Without |
| 566 | it, or with the wrong one, the answer is `403` with the code |
| 567 | `reauth_required`. Only a person's own token can use these: an agent's |
| 568 | token and a workspace's token are refused. |
| 569 | |
| 570 | ## Workspaces |
| 571 | |
| 572 | Your account does not own repositories itself: a workspace does. A new |
| 573 | account gets one of its own, named for its username, unless its invite |
| 574 | brings it into one; see [your first workspace](#your-first-workspace). Workspaces, |
| 575 | their members and roles, and the access tokens that belong to a workspace |
| 576 | are covered in [workspaces](/guides/workspaces/). |
| 577 | |
| 578 | ## Access tokens |
| 579 | |
| 580 | A token stands in for your password everywhere outside the website, and on |
| 581 | the website too when you turn that on for it: |
| 582 | |
| 583 | | Where | How to send it | |
| 584 | | --- | --- | |
| 585 | | git | As the password, with your username. | |
| 586 | | API | `Authorization: Bearer g1t_…` | |
| 587 | | MCP | The same header, set when you add the server. | |
| 588 | | The website | The same header on every request, from automation that drives a browser. Only a token with **Use the website as you** turned on. See [use a token on the website](#use-a-token-on-the-website). | |
| 589 | |
| 590 | A token is shown once, when it is created; g1t stores only a hash of it. |
| 591 | If you lose one, delete it and create another. Delete a token the moment |
| 592 | you think someone else has seen it. |
| 593 | |
| 594 | There is one kind of access token. Every token has: |
| 595 | |
| 596 | - **Permissions**: a level for each resource, such as Issues: read and |
| 597 | write, or Code: read. See [permissions](#permissions). |
| 598 | - **A reach**: the workspaces and repositories it works in. See |
| 599 | [where a token reaches](#where-a-token-reaches). |
| 600 | - **An expiration**: 7 days to 1 year, or none where the workspaces it |
| 601 | reaches allow that. |
| 602 | |
| 603 | It never does more than you could on the website. Your own tokens are |
| 604 | under [Settings → Access tokens](https://g1t.sh/settings/tokens). For CI |
| 605 | and integrations that work for a team, a workspace can have tokens of its |
| 606 | own, made with the same form, that act as the workspace and keep working |
| 607 | when their creator leaves. See [workspace tokens](#workspace-tokens). |
| 608 | |
| 609 | ### Create a token |
| 610 | |
| 611 | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens) and |
| 612 | select **New token**. |
| 613 | 2. Give it a **Token name** after what will use it, and optionally a |
| 614 | **Description**, which a workspace's owners see if they review it. |
| 615 | 3. Choose its **Expiration**: 7, 30, 60, 90 or 180 days, 1 year, or **No |
| 616 | expiration**. A workspace it reaches can set a shorter limit, or forbid |
| 617 | tokens that never expire; the choices follow its rules. No expiration |
| 618 | shows a warning: the token works until someone deletes it. |
| 619 | 4. Under **Where it reaches**, choose **Workspaces**: |
| 620 | - **All your workspaces**: every workspace you belong to, including |
| 621 | ones you join later. |
| 622 | - **One workspace**: then choose its **Repository access**: **All |
| 623 | repositories** (including ones made later), **Only select |
| 624 | repositories** (tick up to 50), or **No private repositories** |
| 625 | (public repositories, read-only, and the workspace's own settings its |
| 626 | permissions allow). |
| 627 | - **No workspace**: your account and public repositories only, such as |
| 628 | a token that reads your notifications. |
| 629 | 5. Under **Permissions**, set each resource the token needs to a level. |
| 630 | **Read only**, **Agent** and **CI** fill in a [preset](#presets); |
| 631 | **Clear** sets everything back to no access. |
| 632 | 6. Leave **Use the website as you**, under **Website**, off unless the |
| 633 | token is for automation that drives a browser. See |
| 634 | [use a token on the website](#use-a-token-on-the-website). |
| 635 | 7. Select **Generate token**, and copy it. It is not shown again. |
| 636 | |
| 637 | When you make a token for one workspace that |
| 638 | [requires approval](#a-workspaces-rules-for-tokens), and you are not one of |
| 639 | its owners, the token is made **Pending approval**: it works at once, but |
| 640 | reads public repositories only until an owner approves it. The owners hear |
| 641 | of it in their [notifications](/guides/notifications/), and you hear of their answer in |
| 642 | yours. An owner's own token never waits. |
| 643 | |
| 644 | ### Change or delete a token |
| 645 | |
| 646 | The list under Settings → Access tokens shows each token's name, status |
| 647 | (pending, denied or revoked, with the owner's note), where it reaches, its |
| 648 | permissions, and when it was made, last used and expires. Select a token to |
| 649 | open its page, where you can change its name, description, repositories, |
| 650 | permissions and **Use the website as you**, and select **Save changes**. |
| 651 | A token that can use the website is marked **Uses the website**. The token |
| 652 | itself stays the |
| 653 | same; the change applies from its next request. Widening a token made for |
| 654 | a workspace that requires approval asks its owners again. Where it reaches |
| 655 | and when it expires cannot change; make a new token instead. |
| 656 | |
| 657 | **Delete token**, at the bottom of its page, stops it working at once. |
| 658 | |
| 659 | ### Use a token on the website |
| 660 | |
| 661 | Automation that drives a browser, such as end-to-end tests or an agent |
| 662 | checking how a page looks, can use g1t.sh as you with an access token, so it |
| 663 | never types your password or a two-factor code. Each request it makes |
| 664 | carries the token in the `Authorization` header; no cookie is set and no |
| 665 | session is started. |
| 666 | |
| 667 | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens) and |
| 668 | select **New token**, or open a token you have. |
| 669 | 2. Give it an expiration, and the permissions it needs for git, the API and |
| 670 | MCP, if any. |
| 671 | 3. Under **Website**, tick **Use the website as you**. It is off unless you |
| 672 | tick it, and a workspace's own token cannot have it. |
| 673 | 4. Select **Generate token** (or **Save changes**), and keep the token in a |
| 674 | file only the automation can read. |
| 675 | 5. Send `Authorization: Bearer g1t_…` on every request to g1t.sh. |
| 676 | |
| 677 | With [Playwright](https://playwright.dev), set the header on the browser |
| 678 | context, reading the token from a file so it is never printed: |
| 679 | |
| 680 | ```js |
| 681 | import { readFileSync } from "node:fs"; |
| 682 | import { chromium } from "playwright"; |
| 683 | |
| 684 | const token = readFileSync(process.env.G1T_TOKEN_FILE, "utf8").trim(); |
| 685 | const browser = await chromium.launch(); |
| 686 | const context = await browser.newContext({ |
| 687 | extraHTTPHeaders: { authorization: `Bearer ${token}` }, |
| 688 | }); |
| 689 | const page = await context.newPage(); |
| 690 | await page.goto("https://g1t.sh/acme/rocket/pulls"); |
| 691 | await page.screenshot({ path: "pulls.png", fullPage: true }); |
| 692 | await browser.close(); |
| 693 | ``` |
| 694 | |
| 695 | `extraHTTPHeaders` sends the header with every request the page makes, |
| 696 | including to other addresses it loads files from. To send it to g1t.sh |
| 697 | only, add it per request instead: |
| 698 | |
| 699 | ```js |
| 700 | const context = await browser.newContext(); |
| 701 | await context.route("https://g1t.sh/**", (route) => |
| 702 | route.continue({ headers: { ...route.request().headers(), authorization: `Bearer ${token}` } }), |
| 703 | ); |
| 704 | ``` |
| 705 | |
| 706 | Any HTTP client works the same way: |
| 707 | |
| 708 | ```sh |
| 709 | curl -H "Authorization: Bearer $(cat ~/.config/g1t/website-token)" https://g1t.sh/acme/rocket/pulls |
| 710 | ``` |
| 711 | |
| 712 | On the website, the token acts as you in the workspaces it |
| 713 | [reaches](#where-a-token-reaches). Its permissions are made for git, the API |
| 714 | and MCP, and the website does not hold it to them: treat it as able to do |
| 715 | anything there that you can. Keep it as safe as your password, and give it |
| 716 | an expiration. |
| 717 | |
| 718 | - **Only the header counts.** A token in a query string or a cookie is |
| 719 | ignored. A request with the header is the token's, even if it also has a |
| 720 | session cookie. |
| 721 | - **Checked on every request.** Deleting the token, its expiry, or a |
| 722 | workspace [revoking it](#a-workspaces-rules-for-tokens) stops it at once. |
| 723 | - **A token that is not accepted is no one.** One that is not valid, has |
| 724 | expired, or does not have **Use the website as you** loads pages as |
| 725 | someone signed out, with a `WWW-Authenticate` header saying the token was |
| 726 | refused; the data requests and form posts pages make answer `401`. |
| 727 | - **Live features work too.** Chat, presence, notifications and editing an |
| 728 | artifact with others run over WebSockets, which cannot carry the header. |
| 729 | So a page opened with a token asks `GET /-/live/ticket` (with the |
| 730 | header) for a socket ticket just before it opens each socket, and adds |
| 731 | it to the socket's address. A ticket lasts 60 seconds, opens only the |
| 732 | socket it was made for, and is never accepted by a page, a data request |
| 733 | or the API. When the socket opens, the token is checked again, so a |
| 734 | token deleted, expired, revoked or without **Use the website as you** |
| 735 | opens nothing. Your automation does nothing for this: route the header |
| 736 | to g1t.sh as above, and the page asks for its tickets itself. A session |
| 737 | in a browser never uses tickets. |
| 738 | - **Form posts need nothing more.** Browsers never send the header by |
| 739 | themselves, so a post with it needs no other proof it came from g1t.sh. |
| 740 | A post from another site is still refused. |
| 741 | - **Limits follow the token**: 1,000 requests a minute, as on the API. See |
| 742 | [rate limits](/reference/rate-limits/). |
| 743 | - **The audit log names it.** A change made this way is recorded as yours, |
| 744 | with the token's id under **Credential**. See [the audit log](/guides/audit-log/). |
| 745 | |
| 746 | Some things always need you to sign in on g1t.sh yourself. With a token, |
| 747 | these pages answer **This needs you to sign in** (`403`): |
| 748 | |
| 749 | | What | Where | |
| 750 | | --- | --- | |
| 751 | | Access tokens, yours and a workspace's, and a workspace's rules for and approvals of members' tokens | Settings → Access tokens; a workspace's Settings → Access tokens and Personal access tokens | |
| 752 | | Two-factor authentication | Settings → Two-factor authentication | |
| 753 | | Your username, and deleting your account | Settings → Account | |
| 754 | | Email addresses, which reset your password | Settings → Emails | |
| 755 | | SSH keys | Settings → SSH keys | |
| 756 | | Applications you signed in to, and signing in with GitHub | Settings → Connected applications, Settings → GitHub | |
| 757 | | Letting a device or an application sign in | `g1t.sh/device`, `g1t.sh/oauth/authorize` | |
| 758 | | Deleting a workspace, and giving it to another owner | A workspace's Settings and People | |
| 759 | | Payment methods: the billing portal, adding a card, subscribing and buying AI credit | A workspace's Billing | |
| 760 | |
| 761 | ### Permissions |
| 762 | |
| 763 | A permission is a resource and a level. A higher level includes the lower |
| 764 | ones: Issues: read and write includes reading issues. Each level is one of |
| 765 | g1t's [scopes](#scopes), so Issues: read and write is `issues:write`; the |
| 766 | API, the MCP server and git check every token by those scopes. |
| 767 | |
| 768 | Repository permissions apply in every repository the token reaches: |
| 769 | |
| 770 | | Permission | Levels | Scope names | |
| 771 | | --- | --- | --- | |
| 772 | | Repositories | read, read and write, admin | `repo:read`, `repo:write`, `repo:admin` | |
| 773 | | Code | read, read and write | `code:read`, `code:write` | |
| 774 | | Security | read, read and write | `security:read`, `security:write` | |
| 775 | | Packages | read, read and write, read, write and delete | `packages:read`, `packages:write`, `packages:delete` | |
| 776 | | Issues | read, read and write | `issues:read`, `issues:write` | |
| 777 | | Pull requests | read, read and write | `pull_requests:read`, `pull_requests:write` | |
| 778 | | g1t agents | run | `agents:run` | |
| 779 | | Workflows | read, read and write | `workflows:read`, `workflows:write` | |
| 780 | | Workflow files | write | `workflow_files:write` | |
| 781 | | Checks and statuses | read, read and write | `checks:read`, `checks:write` | |
| 782 | | Deployments | read, read and write | `deployments:read`, `deployments:write` | |
| 783 | | Memory and context | read, read and write | `memory:read`, `memory:write` | |
| 784 | | Who has access | read, admin | `access:read`, `access:admin` | |
| 785 | | Webhooks | read, admin | `webhooks:read`, `webhooks:admin` | |
| 786 | | Secrets and variables | read, admin | `secrets:read`, `secrets:admin` | |
| 787 | |
| 788 | Workspace permissions apply to the workspaces the token reaches themselves: |
| 789 | |
| 790 | | Permission | Levels | Scope names | |
| 791 | | --- | --- | --- | |
| 792 | | Workspaces | read, admin | `workspace:read`, `workspace:admin` | |
| 793 | | Billing | read, read and write | `billing:read`, `billing:write` | |
| 794 | | Self-hosted runners | read, admin | `runners:read`, `runners:admin` | |
| 795 | | AI Gateway | read, read and write | `models:read`, `models:write` | |
| 796 | | Artifacts | read, read and write, admin | `artifacts:read`, `artifacts:write`, `artifacts:admin` | |
| 797 | |
| 798 | Account permissions are about you, wherever you are, and only a personal |
| 799 | token can hold them: |
| 800 | |
| 801 | | Permission | Levels | Scope names | |
| 802 | | --- | --- | --- | |
| 803 | | Your account | read, read and write | `account:read`, `account:write` | |
| 804 | | Notifications | read, read and write | `notifications:read`, `notifications:write` | |
| 805 | |
| 806 | What each level lets a token do is in [scopes](#scopes). On the form, each |
| 807 | row says it for the level chosen, and admin and delete levels are shown in |
| 808 | red: they change things that are hard to undo, or decide who can reach |
| 809 | what. Give them only to something you trust as much as yourself. |
| 810 | |
| 811 | ### Where a token reaches |
| 812 | |
| 813 | | Made for | Reaches | |
| 814 | | --- | --- | |
| 815 | | All your workspaces | Every workspace you belong to, and repositories you were given, including ones you join later, unless a workspace's [rules](#a-workspaces-rules-for-tokens) keep it out. | |
| 816 | | One workspace, all repositories | That workspace, and every repository of it you can reach. | |
| 817 | | One workspace, select repositories | That workspace, and only the repositories chosen. | |
| 818 | | One workspace, no private repositories | That workspace's own settings its permissions allow, and public repositories. | |
| 819 | | No workspace | Your account, and public repositories. | |
| 820 | |
| 821 | Wherever it does not reach, a token reads public repositories, read-only, |
| 822 | as anyone can; it cannot comment, open issues or push there. While a token |
| 823 | made for a workspace is pending, denied or revoked, that is all it does |
| 824 | there too. |
| 825 | |
| 826 | A request it cannot make answers `403` naming why: the scope it lacks, or |
| 827 | `This access token is made for the workspace acme: elsewhere it can only |
| 828 | read public repositories, …`. A repository outside its selection answers as |
| 829 | if it did not exist. |
| 830 | |
| 831 | ### Presets |
| 832 | |
| 833 | A preset fills in a starting set of permissions. Select one, then change |
| 834 | any row. |
| 835 | |
| 836 | | Preset | Permissions | |
| 837 | | --- | --- | |
| 838 | | Read only | Every resource at read. Changes nothing. | |
| 839 | | Agent | Every resource at read except Self-hosted runners, and Code, Issues, Pull requests, Memory and context and Notifications at read and write, and g1t agents at run. Reads everything, works on issues and pull requests, pushes code, puts g1t to work, and answers your inbox. No admin level. | |
| 840 | | CI | Repositories: read; Code, Packages, Workflows, Checks and statuses, and Deployments: read and write. Clones and pushes code, pushes and pulls packages, runs workflows, and reports [checks](/guides/checks/) and deployments. | |
| 841 | |
| 842 | A new personal token starts on Read only; a new workspace token on CI. |
| 843 | |
| 844 | ## Scopes |
| 845 | |
| 846 | A scope is a permission's level, written `resource:level`, such as |
| 847 | `issues:write`. A token stores the highest scope of each resource it |
| 848 | holds, and every check reads them. A higher level includes the lower ones |
| 849 | of the same resource: `repo:admin` includes `repo:write`, which includes |
| 850 | `repo:read`. It never includes another resource: `repo:admin` does not let |
| 851 | a token push, which is `code:write`. |
| 852 | |
| 853 | Applications that [sign in with OAuth](#signing-in-with-oauth) ask for |
| 854 | scopes by these names, and you choose them on a checklist when you approve |
| 855 | one. |
| 856 | |
| 857 | | Scope | What it lets a token do | |
| 858 | | --- | --- | |
| 859 | | `repo:read` | See repositories, their settings, labels, timelines, releases, languages, contributors and security alerts, and search | |
| 860 | | `repo:write` | Create repositories, rename branches, change how pull requests merge and publish releases | |
| 861 | | `repo:admin` | Rename, archive, transfer, delete or change who can see a repository, and dismiss security alerts | |
| 862 | | `code:read` | Clone and fetch private repositories with git | |
| 863 | | `code:write` | Push commits with git | |
| 864 | | `security:read` | See [secret scanning](/guides/security/secret-protection/), [code scanning](/guides/security/code-scanning/) and vulnerability alerts, custom patterns, the dependency graph and SBOM, and security settings | |
| 865 | | `security:write` | Dismiss and reopen alerts, bypass push protection, review bypass requests, manage custom patterns, upload SARIF and change security settings | |
| 866 | | `packages:read` | Pull container images and install private [packages](/guides/packages/). Public ones need no scope. | |
| 867 | | `packages:write` | Push container images and publish packages; with the Admin role on a package, change its settings | |
| 868 | | `packages:delete` | Delete and restore packages and their versions | |
| 869 | | `issues:read` | Read issues, comments and plans | |
| 870 | | `issues:write` | Open, edit, close and comment on issues | |
| 871 | | `pull_requests:read` | Read pull requests, their changes, sessions and merge queues | |
| 872 | | `pull_requests:write` | Open, review, close and merge pull requests | |
| 873 | | `agents:run` | Put g1t to work and message it, which uses the workspace's money | |
| 874 | | `workflows:read` | Read workflows, runs and logs | |
| 875 | | `workflows:write` | Run, cancel, rerun and turn workflows on or off | |
| 876 | | `workflow_files:write` | Add, change and delete [workflow files](#workflow-files) under `.g1t/workflows` and `.github/workflows`, with git or the API. Not in any preset. | |
| 877 | | `checks:read` | Read commits' statuses, check runs, check suites and annotations | |
| 878 | | `checks:write` | Report [statuses and check runs](/guides/checks/) on commits, and ask for checks to run again | |
| 879 | | `deployments:read` | See [deployments](/guides/deployments-api/), their statuses and environments | |
| 880 | | `deployments:write` | Report deployments and their statuses, from any CI | |
| 881 | | `memory:read` | Recall memory and search the workspace's context | |
| 882 | | `memory:write` | Save memory for the next agent | |
| 883 | | `account:read` | Read your email addresses, invites, invitations, pinned projects and stars | |
| 884 | | `account:write` | Change your email addresses, make invites, answer invitations, pin projects and star repositories | |
| 885 | | `notifications:read` | See your [notifications](/guides/notifications/), its threads, and what you subscribe to and watch | |
| 886 | | `notifications:write` | Mark notifications read, done, saved or snoozed, subscribe to threads and watch repositories | |
| 887 | | `workspace:read` | Read workspace settings, invites, integrations, model routes and [teams](/guides/teams/) | |
| 888 | | `workspace:admin` | Create and delete workspaces, invite members, manage teams, connect integrations | |
| 889 | | `billing:read` | See a workspace's [usage, budget, AI credit and invoices](/guides/usage-and-billing/) | |
| 890 | | `billing:write` | Change a workspace's budget and buy AI credit. Only owners, as people: a workspace's own token and g1t's agents never change billing, whatever their scopes. Not in any preset. | |
| 891 | | `access:read` | See who has access to repositories | |
| 892 | | `access:admin` | Give people and teams access to repositories, and take it away | |
| 893 | | `webhooks:read` | See webhooks and their deliveries | |
| 894 | | `webhooks:admin` | Create, change and delete webhooks | |
| 895 | | `secrets:read` | List secrets (never their values) and read variables | |
| 896 | | `secrets:admin` | Set and delete secrets and variables | |
| 897 | | `runners:read` | See [self-hosted runners](/guides/self-hosted-runners/), their groups and where agents run. Not in the Agent preset. | |
| 898 | | `runners:admin` | Register and remove self-hosted runners, change their groups and settings | |
| 899 | | `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status | |
| 900 | | `models:write` | Send model requests through the [AI Gateway](/guides/ai-gateway/), which uses the workspace's AI credit. Only a workspace's own token can send them. Not in any preset. | |
| 901 | | `artifacts:read` | List, read and search the [artifacts](/guides/bring-your-own-agent/#artifacts) you can open (docs, and later slides, designs and dashboards), their versions and who can open them. Not workflow runs' artifacts, which are `workflows:read`. | |
| 902 | | `artifacts:write` | Create, rename, move, edit, trash and restore artifacts, and suggest changes to them | |
| 903 | | `artifacts:admin` | Share artifacts, change who can open them, and delete them for good. Not in any preset. | |
| 904 | |
| 905 | Every operation of the API and the MCP server needs exactly one of these, |
| 906 | except `whoami` (`GET /user`), which any token may use. Each endpoint's page |
| 907 | in the [API reference](/reference/api/) names its scope, and so does each |
| 908 | action in [MCP tools](/reference/mcp/); the MCP server lists only the tools |
| 909 | a token's permissions can use. A few calls need a second scope for what |
| 910 | they ask: |
| 911 | |
| 912 | | Call | Also needs | |
| 913 | | --- | --- | |
| 914 | | `delegate` (`POST /repos/{owner}/{name}/issues/delegate`, the `agent` tool's `delegate`), which opens an issue | `issues:write`, beside `agents:run` | |
| 915 | | `apply_plan` or `import_issue` (the `plan` tool's `apply`, the `issue` tool's `import`) with `assign: true` | `agents:run` | |
| 916 | | `update_repo` with `private` or `default_branch` | `repo:admin` | |
| 917 | |
| 918 | ### What a token can do |
| 919 | |
| 920 | What a request may do is where these overlap: |
| 921 | |
| 922 | 1. **Your role.** A token never does more than you could on the website. A |
| 923 | token with Repositories: admin still cannot delete a repository unless |
| 924 | you are an owner of its workspace. See |
| 925 | [access and roles](/guides/access-and-roles/). |
| 926 | 2. **Where it reaches.** All your workspaces, one, or none, and in one, its |
| 927 | repositories. See [where a token reaches](#where-a-token-reaches). |
| 928 | 3. **Its permissions.** What kinds of thing it may do there. |
| 929 | |
| 930 | ### Git and scopes |
| 931 | |
| 932 | Over HTTPS, git checks the same token: |
| 933 | |
| 934 | | To | Needs | |
| 935 | | --- | --- | |
| 936 | | Clone or fetch a public repository | No permission | |
| 937 | | Clone or fetch a private repository | Code: read (`code:read`) | |
| 938 | | Push | Code: read and write (`code:write`) | |
| 939 | | Push commits that add, change or delete [workflow files](#workflow-files) | Code: read and write, and Workflow files: write (`workflow_files:write`) | |
| 940 | |
| 941 | Your role on the repository applies too, as on the website. A refused push |
| 942 | or clone says which scope is missing. |
| 943 | |
| 944 | ### Workflow files |
| 945 | |
| 946 | A workflow runs with its repository's secrets and a token of its own, so |
| 947 | changing one is as powerful as holding those. A token therefore needs |
| 948 | Workflow files: write (`workflow_files:write`) to add, change or delete any |
| 949 | file under `.g1t/workflows/` or `.github/workflows/`, besides Code: read |
| 950 | and write: |
| 951 | |
| 952 | - **With git**, every commit a push adds is compared with its parent, and a |
| 953 | push that changes a workflow file is declined, naming it: |
| 954 | |
| 955 | ```text |
| 956 | remote: This access token cannot change the workflow file .github/workflows/ci.yml: it needs the workflow_files:write scope. |
| 957 | remote: Push with a token that has the workflow_files:write scope, or make the change signed in on g1t.sh. |
| 958 | ``` |
| 959 | |
| 960 | A push too large for g1t to read whole is declined for such a token too, |
| 961 | since it cannot be checked; push it in smaller parts. |
| 962 | - **Through g1t**, a file written for a token (such as a starter workflow) |
| 963 | is refused the same way. |
| 964 | - **A workflow job's token** never may, whatever its `permissions:` say. |
| 965 | See [the job's token](/guides/actions/#the-jobs-token). |
| 966 | - **Signed in on g1t.sh**, your role decides, as for any file. |
| 967 | |
| 968 | A [deploy key](/guides/git/#deploy-keys) with write access may change |
| 969 | workflow files. |
| 970 | |
| 971 | ### When a token lacks a scope |
| 972 | |
| 973 | The API answers `403` with the scope that was missing in `needed_scope`: |
| 974 | |
| 975 | ```json |
| 976 | { |
| 977 | "error": { |
| 978 | "code": "forbidden", |
| 979 | "message": "This access token needs the issues:write scope to use create_issue.", |
| 980 | "needed_scope": "issues:write" |
| 981 | } |
| 982 | } |
| 983 | ``` |
| 984 | |
| 985 | Through MCP the same message comes back as a tool result with `isError` |
| 986 | set. Give the token that permission on its page, or make a new token. |
| 987 | |
| 988 | ### Tokens made before |
| 989 | |
| 990 | Tokens once came in two kinds, with scopes or with permissions for one |
| 991 | workspace. Every one of them is now a token like any other, and does |
| 992 | exactly what it did: |
| 993 | |
| 994 | - A token made with scopes is made for **all your workspaces**, with the |
| 995 | permissions its scopes were. |
| 996 | - A token made for one workspace (or for your account only) is made for |
| 997 | that workspace (or for **No workspace**), with the repositories it had, |
| 998 | and with permissions that are the scopes its old permissions gave. |
| 999 | - A token with full access, including one made before tokens had scopes and |
| 1000 | one from [signing in from a tool](#signing-in-from-a-tool) such as the |
| 1001 | g1t CLI, has every permission at its highest level. Narrow it on its page |
| 1002 | to what it needs. |
| 1003 | |
| 1004 | An application signed in with OAuth before applications had scopes keeps |
| 1005 | full access too, marked **Legacy · full access**: select **Change access** |
| 1006 | in [Connected applications](https://g1t.sh/settings/applications) to narrow |
| 1007 | it. |
| 1008 | |
| 1009 | The old addresses of the token settings lead to the list and to each |
| 1010 | token's page. |
| 1011 | |
| 1012 | ### Workspace tokens |
| 1013 | |
| 1014 | A workspace's own tokens act as the workspace rather than a person. An |
| 1015 | owner makes them in the workspace's **Settings → Access tokens** |
| 1016 | (`g1t.sh/<workspace>/-/tokens`), with **New token**: the same form as a |
| 1017 | personal token, starting on the CI preset. A workspace token reaches all |
| 1018 | of that workspace's repositories, or the ones chosen, never another |
| 1019 | workspace, and cannot manage people, tokens or workspaces. It holds no |
| 1020 | account permissions, and cannot use artifacts, which always belong to a |
| 1021 | person. |
| 1022 | |
| 1023 | It has the Write role on the workspace's repositories, as a member does: |
| 1024 | it pushes, merges and works on issues and pull requests, within its |
| 1025 | permissions. Give it **Repositories: admin** to make it an admin of the |
| 1026 | workspace's repositories instead, so it can also manage webhooks, secrets, |
| 1027 | deploy keys and who has access, and manage teams as an owner would. Only an |
| 1028 | owner can make, change or delete one. See |
| 1029 | [workspace access tokens](/guides/workspaces/#workspace-access-tokens). |
| 1030 | |
| 1031 | ## A workspace's rules for tokens |
| 1032 | |
| 1033 | An owner decides which of the members' own personal tokens reach the |
| 1034 | workspace, under its **Settings → Personal access tokens** |
| 1035 | (`g1t.sh/<workspace>/-/personal-access-tokens`). The rules apply from each |
| 1036 | token's next request, to tokens made before them too. A token they keep out |
| 1037 | keeps working everywhere else, and reads the workspace's public |
| 1038 | repositories as anyone can. |
| 1039 | |
| 1040 | | Rule | Default | What it does | |
| 1041 | | --- | --- | --- | |
| 1042 | | Allow tokens made for the workspace | On | Off: no token can be made for the workspace alone, and existing ones stop reaching it. | |
| 1043 | | Require approval of tokens made for the workspace | On | A member's token made for the workspace waits for an owner's approval, and again when it is widened. Owners' own tokens never wait. | |
| 1044 | | Allow tokens made for all of a member's workspaces | On | Off: tokens made for all of their owner's workspaces no longer reach this one; members make a token for it alone instead, which the rule above can require approval for. | |
| 1045 | | Tokens must expire | Off | On: a token that never expires does not reach the workspace. | |
| 1046 | | Longest lifetime | No limit | A token that lasts longer (from when it was made to when it expires), or never expires, does not reach the workspace. Tokens for it cannot be made longer. | |
| 1047 | |
| 1048 | The same page lists: |
| 1049 | |
| 1050 | - **Waiting for approval.** Each pending token with its owner, |
| 1051 | permissions, repositories and expiry. Add an optional note, then select |
| 1052 | **Approve** or **Deny**. Its owner hears of it in their notifications, with the |
| 1053 | note. |
| 1054 | - **Tokens that can reach the workspace.** Every token made for it, and |
| 1055 | every token of its members and outside collaborators made for all of |
| 1056 | their workspaces, that has not expired, with its owner, permissions, |
| 1057 | reach, last use and expiry, and whether it reaches the workspace now (and |
| 1058 | if not, why). Never the token itself. Select **Revoke** to take one out: |
| 1059 | a token made for the workspace stops reaching it for good; a token made |
| 1060 | for all of its owner's workspaces keeps working everywhere else, but |
| 1061 | never reaches this workspace again. |
| 1062 | |
| 1063 | Approvals, denials, revocations and rule changes are |
| 1064 | [audit log](/guides/audit-log/) entries: `token.approval_requested`, |
| 1065 | `token.approved`, `token.denied`, `token.revoked` and |
| 1066 | `token.policy_changed`. |
| 1067 | |
| 1068 | ### A workspace's rules through the API |
| 1069 | |
| 1070 | Owners, as people (a personal token with the permission works; a |
| 1071 | workspace's own token does not): |
| 1072 | |
| 1073 | | Route | MCP tool and action | What it does | Scope | |
| 1074 | | --- | --- | --- | --- | |
| 1075 | | [`GET /workspaces/{workspace}/personal-access-token-policy`](/reference/api/personal-access-tokens/get-token-policy/) | `workspace` `get_token_policy` | The rules. Members may read them. | `workspace:read` | |
| 1076 | | [`PATCH /workspaces/{workspace}/personal-access-token-policy`](/reference/api/personal-access-tokens/set-token-policy/) | `workspace` `set_token_policy` | Change `allow_tokens_for_this_workspace`, `allow_tokens_for_all_workspaces`, `require_approval`, `max_lifetime_days` (0 for no limit) or `forbid_no_expiry` | `workspace:admin` | |
| 1077 | | [`GET /workspaces/{workspace}/personal-access-tokens`](/reference/api/personal-access-tokens/list-member-tokens/) | `workspace` `list_member_tokens` | The tokens that can reach it, each with its `permissions` (`{"issues": "write"}`), `scopes`, `workspace` (null when made for all of its owner's), `repository_selection`, `repositories` and `status` | `access:read` | |
| 1078 | | [`GET /workspaces/{workspace}/personal-access-token-requests`](/reference/api/personal-access-tokens/list-token-requests/) | `workspace` `list_token_requests` | The tokens waiting for approval | `access:read` | |
| 1079 | | [`POST /workspaces/{workspace}/personal-access-token-requests/{id}`](/reference/api/personal-access-tokens/review-token-request/) | `workspace` `review_token_request` | `decision` is `approve` or `deny`, with an optional `reason` | `access:admin` | |
| 1080 | | [`POST /workspaces/{workspace}/personal-access-tokens/{id}`](/reference/api/personal-access-tokens/revoke-member-token/) | `workspace` `revoke_member_token` | Revoke a token in the workspace, with an optional `reason` | `access:admin` | |
| 1081 | |
| 1082 | ## Signing in with OAuth |
| 1083 | |
| 1084 | Applications that can open your browser, such as an agent connecting to the |
| 1085 | [MCP server](/guides/bring-your-own-agent/), sign you in with OAuth 2.1. |
| 1086 | You see a page on g1t naming the application and where it will send you |
| 1087 | back, and you approve or deny. The application never sees your password and |
| 1088 | there is no token to copy. |
| 1089 | |
| 1090 | The page lists what the application will be able to do, as the same |
| 1091 | checklist a token has, with only the scopes it asked for, all ticked. |
| 1092 | Untick anything you would rather it could not do, leaving at least one; |
| 1093 | you cannot give it more than it asked for. Like a token, it reaches |
| 1094 | everything you can. |
| 1095 | |
| 1096 | An application that asks for no scopes in particular gets the |
| 1097 | [Agent preset](#presets): every `read` scope except `runners:read`, and `code:write`, |
| 1098 | `issues:write`, `pull_requests:write`, `agents:run`, `memory:write` and |
| 1099 | `notifications:write`. |
| 1100 | It never gets an admin scope unless it asks for one and you leave it |
| 1101 | ticked. |
| 1102 | |
| 1103 | Applications you have approved are listed in |
| 1104 | [Settings → Connected applications](https://g1t.sh/settings/applications), |
| 1105 | each with its access. Select **Change access** to tick or untick its |
| 1106 | scopes, then **Save access**: it stays signed in, the change applies at |
| 1107 | once, and its next refresh keeps it. Select **Sign out** to end its access |
| 1108 | at once. |
| 1109 | |
| 1110 | For people building a client: |
| 1111 | |
| 1112 | | | | |
| 1113 | | --- | --- | |
| 1114 | | Metadata | `https://api.g1t.sh/.well-known/oauth-authorization-server` | |
| 1115 | | Authorization | `https://g1t.sh/oauth/authorize` | |
| 1116 | | Token | `https://api.g1t.sh/oauth/token` | |
| 1117 | | Registration | `https://api.g1t.sh/oauth/register` | |
| 1118 | |
| 1119 | - The flow is authorization code with PKCE. `S256` is required. |
| 1120 | - Clients are public: there are no client secrets. |
| 1121 | - Register with `client_name` and `redirect_uris`. A redirect address is an |
| 1122 | `https` URL, `http` on `localhost`, or the application's own scheme. A |
| 1123 | client on `localhost` may use any port. |
| 1124 | - Registration stores nothing. The client id it returns encodes what was |
| 1125 | registered, so it cannot be used to fill g1t with junk. |
| 1126 | - Ask for scopes with `scope` on the authorization request, separated by |
| 1127 | spaces, such as `scope=repo:read issues:write pull_requests:write`. |
| 1128 | Names g1t does not know are left out. Leave `scope` out for the Agent |
| 1129 | preset. The authorization server's metadata and |
| 1130 | `https://mcp.g1t.sh/.well-known/oauth-protected-resource` list every |
| 1131 | scope in `scopes_supported`. |
| 1132 | - The token response's `scope` holds the scopes the person granted, |
| 1133 | separated by spaces, or `*` for a sign-in with full access. Refreshing |
| 1134 | keeps them. |
| 1135 | - An access token lasts 30 days. The refresh token returned with it works |
| 1136 | once and returns the next pair; the previous access token stops working. |
| 1137 | - An authorization code lasts five minutes and works once. |
| 1138 | |
| 1139 | ## Signing in from a tool |
| 1140 | |
| 1141 | A tool that cannot receive a redirect, such as a script on a remote machine, |
| 1142 | gets a token without ever handling your password: |
| 1143 | |
| 1144 | 1. The tool asks g1t for a code and shows you a link and a short code such |
| 1145 | as `WDJB-MJHT`. |
| 1146 | 2. You open the link, sign in (or create an account), check that the code |
| 1147 | matches, and approve. |
| 1148 | 3. The tool collects its token. |
| 1149 | |
| 1150 | ```sh |
| 1151 | # 1. The tool starts a sign-in. |
| 1152 | curl -X POST https://api.g1t.sh/device/code -H "Content-Type: application/json" -d '{"client_name": "my-tool"}' |
| 1153 | |
| 1154 | # 2. You open verification_uri_complete from the response and approve. |
| 1155 | |
| 1156 | # 3. The tool polls, no faster than "interval" seconds, until it is approved. |
| 1157 | curl -X POST https://api.g1t.sh/device/token -H "Content-Type: application/json" -d '{"device_code": "…"}' |
| 1158 | ``` |
| 1159 | |
| 1160 | The poll answers with a `status` of `pending`, `approved`, `denied` or |
| 1161 | `expired`. An approved answer carries the token, once. Codes expire after 15 |
| 1162 | minutes. The token appears in |
| 1163 | [Settings → Access tokens](https://g1t.sh/settings/tokens) under the tool's name, where you |
| 1164 | can delete it. |
| 1165 | |
| 1166 | Only approve a code you asked for. The token has full access: it can do |
| 1167 | everything you can. To give a tool less, make an |
| 1168 | [access token](#create-a-token) with only the scopes it needs instead. |
| 1169 | |
| 1170 | ## Resetting your password |
| 1171 | |
| 1172 | Use [g1t.sh/forgot](https://g1t.sh/forgot) and enter any confirmed |
| 1173 | address of your account. The link goes to that address and works for one |
| 1174 | hour; your primary and backup addresses are told a reset was asked for |
| 1175 | when it went elsewhere. A new account that has not confirmed its address |
| 1176 | yet can use that address, and following the link confirms it. |
| 1177 | |
| 1178 | The page answers the same way whether or not the address has an account. |
| 1179 | g1t sends at most 5 reset links an hour to one address. If g1t cannot |
| 1180 | take the request at all, the page says so and keeps what you typed, so you |
| 1181 | can try again. |
| 1182 | |
| 1183 | Setting a new password signs you out everywhere and emails your primary |
| 1184 | and backup addresses. |
| 1185 | |
| 1186 | ## Too many attempts |
| 1187 | |
| 1188 | g1t counts wrong passwords, on the sign-in page, for git over HTTPS and |
| 1189 | when confirming it is you, against the account and against where they come |
| 1190 | from. After 10 wrong passwords for one account in an hour, or 30 from one |
| 1191 | place, g1t stops checking passwords for it for a minute, then twice as long |
| 1192 | after each further wrong password, up to an hour. While it waits, every |
| 1193 | attempt gets the same answer: "Too many attempts". The account's primary |
| 1194 | and backup addresses are told the first time. Signing in with the right |
| 1195 | password, or resetting it, clears the count. Access tokens, SSH keys and |
| 1196 | GitHub sign-in are not affected. |
| 1197 | |
| 1198 | ## Security log |
| 1199 | |
| 1200 | [Settings → Security log](https://g1t.sh/settings/security-log) lists what |
| 1201 | happened to your account: addresses added, confirmed, removed or made |
| 1202 | primary, your backup and privacy settings, password changes, pauses after |
| 1203 | too many wrong passwords, two-factor authentication turned on or off and |
| 1204 | recovery codes made or used, personal access tokens created, deleted or |
| 1205 | given new scopes, SSH keys added or removed, and applications authorized, |
| 1206 | changed or revoked. Changes g1t staff made, such as removing an address |
| 1207 | someone else needed, say so and why. |
| 1208 | |
| 1209 | Token, SSH key, application and two-factor changes are also recorded in the |
| 1210 | [audit log](/guides/audit-log/) of each workspace you belong to, where its |
| 1211 | owners see them. |
| 1212 | |
| 1213 | ## Deleting your account |
| 1214 | |
| 1215 | You can delete your account from |
| 1216 | [Settings → Account](https://g1t.sh/settings/account), signed in as |
| 1217 | yourself. It is not gone at once: for **30 days** g1t keeps it, so that a |
| 1218 | deletion you did not mean, or did not make, can be undone through support. |
| 1219 | After 30 days it is removed for good. |
| 1220 | |
| 1221 | 1. Open **Settings → Account** and go to **Danger zone**. If anything is |
| 1222 | in the way, it says what, instead of offering the button. |
| 1223 | 2. Choose **Delete account**. The dialog lists what goes with it: your |
| 1224 | workspaces, the repositories you were added to, your access tokens, SSH |
| 1225 | keys and connected applications. |
| 1226 | 3. Type your username, and your password unless you signed in within the |
| 1227 | last 10 minutes. An account that signs in with GitHub only signs out, |
| 1228 | signs in with GitHub again, and deletes it within 10 minutes. |
| 1229 | 4. Choose **Delete account** again. You are signed out, and g1t emails your |
| 1230 | primary and backup addresses to say it was deleted. |
| 1231 | |
| 1232 | There is no API route or MCP tool for deleting an account, by design: like |
| 1233 | [creating one](#creating-an-account), it happens only in a browser, signed |
| 1234 | in as yourself, never with a token or as an agent. |
| 1235 | |
| 1236 | ### What stands in the way |
| 1237 | |
| 1238 | | | | |
| 1239 | | --- | --- | |
| 1240 | | A workspace you own alone | Each live workspace where you are the only owner is listed. [Make someone else an owner](/guides/workspaces/#change-someones-role) of it, or [delete it](/guides/workspaces/#delete-a-workspace), first. Deleting a workspace settles its billing, which can ask for something first: the list says what. A workspace you own with someone else is not in the way. | |
| 1241 | | A protected account | `g1t` and the other names g1t uses for itself can never be deleted, by anyone. | |
| 1242 | |
| 1243 | Billing belongs to workspaces, not to accounts, so once no workspace |
| 1244 | depends on you alone there is nothing for billing to settle. |
| 1245 | |
| 1246 | When g1t's staff delete an account, on its owner's request or for abuse, |
| 1247 | the workspaces it alone owns are not left without an owner. Staff either |
| 1248 | wait for another owner to be made, or delete those workspaces together |
| 1249 | with the account, each exactly as its owner would: its billing is settled |
| 1250 | first, everything in it goes with it, and it is kept 30 days for a |
| 1251 | restore like any deleted workspace. Its audit log records the deletion as |
| 1252 | g1t's staff. Staff never do this for a workspace whose billing cannot be |
| 1253 | settled yet (an unpaid invoice, prepaid credit, usage still being metered), |
| 1254 | or for one of the workspaces g1t protects; if any of them stands in the |
| 1255 | way, nothing is deleted. |
| 1256 | |
| 1257 | ### What happens |
| 1258 | |
| 1259 | At once, when you delete it: |
| 1260 | |
| 1261 | | | | |
| 1262 | | --- | --- | |
| 1263 | | Signing in | You are signed out everywhere. Signing in with your password, GitHub, a recovery code or from a tool fails, with the same answer a wrong password gets. | |
| 1264 | | Access tokens, SSH keys and applications | Your personal access tokens, SSH keys, connected applications and sign-ins from a tool stop working and are removed, and so do the deploy keys you added to repositories. A workspace's own tokens are not affected, even ones you made. | |
| 1265 | | Workspaces, teams and repositories | You leave every workspace and team, and lose the roles you were given on single repositories. Repository invitations waiting for you are withdrawn, and invites you made that nobody used are revoked. | |
| 1266 | | Your profile | `g1t.sh/<username>` answers 404, and you drop out of search. Nobody can add you to a workspace, team or repository, and nothing more is emailed to you. | |
| 1267 | | What you wrote | Stays where it is, under your username for now. Commits made with your confirmed or noreply addresses show as `ghost`, and as yours again if your account is restored. | |
| 1268 | | Your username | Held for your account. Nobody else can take it. | |
| 1269 | |
| 1270 | Within 30 days, support can restore it: write to support@g1t.sh from one |
| 1271 | of its addresses. You come back to the workspaces, teams and repositories |
| 1272 | you were in, where they are still there, and sign in again with your |
| 1273 | password. Your old sessions, tokens and keys stay ended: make new ones. |
| 1274 | |
| 1275 | After 30 days it is removed for good: |
| 1276 | |
| 1277 | | | | |
| 1278 | | --- | --- | |
| 1279 | | Your addresses, keys and profile | Removed: your email addresses, two-factor secret and recovery codes, GitHub link, picture, profile and security log, and your notifications and their settings. | |
| 1280 | | What you wrote | Issues, pull requests, comments and reviews keep their place and their words, and show as written by `ghost`. You are taken off issues and pull requests you were assigned to or asked to review. Commits keep the name and address git recorded in them; those made with your [noreply address](#keeping-your-address-private) show as `ghost`. | |
| 1281 | | Workspaces you made | Name `ghost` as their creator. | |
| 1282 | | Statements, invoices and audit logs | Kept with your username, for the workspaces they belong to. | |
| 1283 | | Your username | Never given to another account or workspace, so links, mentions and remotes that use it keep meaning what they meant. `ghost` is reserved for this, and nobody can register it. | |
| 1284 | |
| 1285 | ## What g1t stores |
| 1286 | |
| 1287 | Passwords are stored as salted PBKDF2-SHA256 hashes. Sessions and tokens are |
| 1288 | stored as SHA-256 hashes. Neither can be read back. A two-factor secret is |
| 1289 | encrypted (AES-256-GCM) and bound to your account, and recovery codes are |
| 1290 | kept as SHA-256 hashes. |