| 1 | --- |
| 2 | title: Accounts and authentication |
| 3 | description: Accounts, invites, email addresses, confirming them, personal access tokens and their scopes, OAuth, signing in from a tool, password reset and your security log. |
| 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. Usernames are lowercase letters, digits and single |
| 12 | hyphens, up to 39 characters. |
| 13 | |
| 14 | Accounts can only be created in a browser. There is no API for it, by |
| 15 | design: it keeps passwords out of scripts and agents, and lets g1t protect |
| 16 | the one place accounts are made. |
| 17 | |
| 18 | ## Your settings |
| 19 | |
| 20 | Your own settings are at [g1t.sh/settings](https://g1t.sh/settings), one |
| 21 | page each. Open them from your account menu at the bottom of the sidebar, |
| 22 | under **Your settings**; the sidebar then lists every page. |
| 23 | |
| 24 | | Page | Address | What is on it | |
| 25 | | --- | --- | --- | |
| 26 | | Profile | [`/settings/profile`](https://g1t.sh/settings/profile) | Your picture, and your [public profile](/guides/workspaces/#profiles): name, pronouns, bio, location and website. | |
| 27 | | 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). | |
| 28 | | Invites | [`/settings/invites`](https://g1t.sh/settings/invites) | [Making, copying and revoking invites](#invites). | |
| 29 | | SSH keys | [`/settings/keys`](https://g1t.sh/settings/keys) | Public keys for [git over SSH](/guides/git/). | |
| 30 | | Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens). | |
| 31 | | GitHub | [`/settings/github`](https://g1t.sh/settings/github) | [Linking and unlinking GitHub](/guides/github/#link-and-unlink-github). | |
| 32 | | 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. | |
| 33 | | Security log | [`/settings/security-log`](https://g1t.sh/settings/security-log) | [What happened to your account](#security-log). | |
| 34 | |
| 35 | `g1t.sh/settings` opens Profile. |
| 36 | |
| 37 | ## Signing in with GitHub |
| 38 | |
| 39 | **Continue with GitHub** on the sign-in and sign-up pages signs you in with |
| 40 | your GitHub account, and makes a g1t account the first time. Link or |
| 41 | unlink GitHub in [Settings → GitHub](https://g1t.sh/settings/github). See |
| 42 | [GitHub](/guides/github/#sign-in-with-github). |
| 43 | |
| 44 | Making an account with GitHub needs an invite too: start from your invite |
| 45 | link, or enter the code when g1t asks for it after GitHub. |
| 46 | |
| 47 | ## Invites |
| 48 | |
| 49 | While g1t is invite-only, every new account needs an invite code, such as |
| 50 | `g1t-k7m2-q9xd-…`. People already on g1t make them, and g1t sends them to |
| 51 | people who [asked for access](#asking-for-access). An invite: |
| 52 | |
| 53 | - works once, for one new account; |
| 54 | - works for 30 days; |
| 55 | - when it was made for an email address, works only with that address; |
| 56 | - can be revoked by whoever made it until it is used. |
| 57 | |
| 58 | ### Using an invite |
| 59 | |
| 60 | Every invite email links to `g1t.sh/invite/<code>`. That one page shows |
| 61 | who sent it and what it is for (joining a workspace, collaborating on a |
| 62 | repository, or just making an account), and finishes the job there: |
| 63 | |
| 64 | 1. **No account yet**: sign up on the page. When the invite was sent to |
| 65 | your address, the email field is filled in and locked, and the address |
| 66 | is confirmed already, so no confirmation email follows. Choose a |
| 67 | username (one is suggested from your address) and a password, or select |
| 68 | **Continue with GitHub**: the invite rides along, and the account uses |
| 69 | the invited address when GitHub has verified it too. |
| 70 | 2. **The address already has an account**: select **Sign in to accept**. |
| 71 | After you sign in, the invite is accepted for you. |
| 72 | 3. **Signed in as someone else**: an invite sent to one address works only |
| 73 | for an account that has confirmed that address. The page says so and |
| 74 | offers **Sign out and continue**. |
| 75 | |
| 76 | Once the account exists or you have signed in, you land in the workspace |
| 77 | (or the repository) the invite was for, already a member, with a one-time |
| 78 | "You're in" banner, and it becomes the workspace your sidebar shows. A |
| 79 | code typed at [g1t.sh/register](https://g1t.sh/register) goes to the |
| 80 | same page. |
| 81 | |
| 82 | An expired, revoked or used invite says which, and who sent it, so you |
| 83 | can ask them for a new one; or ask for access from the same page. |
| 84 | |
| 85 | ### Making invites |
| 86 | |
| 87 | 1. Open [Settings → Invites](https://g1t.sh/settings/invites). |
| 88 | 2. Optionally enter the email address of the person you are inviting. |
| 89 | With one, g1t emails them the invite, and only that address can use it. |
| 90 | Without one, anyone with the link can, once. |
| 91 | 3. Select **Create invite**, then copy the link. |
| 92 | |
| 93 | Each person can have **5** invites out at a time. Pending and used invites |
| 94 | count; an invite you revoke, or one that expires before anyone uses it, |
| 95 | comes back to you. The list under the form shows each invite's state: |
| 96 | pending, joined (with the username of who joined), expired or revoked. You |
| 97 | must confirm your email before you can make invites. An agent's token and |
| 98 | a workspace's token cannot make them. |
| 99 | |
| 100 | ### Inviting someone into a workspace |
| 101 | |
| 102 | An owner can invite an email address straight into a workspace from its |
| 103 | People page; see [members and roles](/guides/workspaces/#members-and-roles). |
| 104 | When the address has no g1t account, accepting makes the account and joins |
| 105 | the workspace in one step, and it uses one invite. Inviting someone who is |
| 106 | already on g1t costs nothing. |
| 107 | |
| 108 | ### Need more invites? |
| 109 | |
| 110 | Write to [hey@flagon.io](mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20) |
| 111 | with the subject `[g1t Invites]` and say who you would like to bring. g1t |
| 112 | can give more invites to you, or to a workspace, whose owners then share |
| 113 | them. Invites given to a workspace appear under |
| 114 | [Settings → Invites](https://g1t.sh/settings/invites) for |
| 115 | each of its owners, as a choice of whose invites to use. |
| 116 | |
| 117 | ### Asking for access |
| 118 | |
| 119 | Without an invite, [g1t.sh/register](https://g1t.sh/register) asks for your |
| 120 | email address and, if you like, what you will build. g1t emails that |
| 121 | address once to confirm you are on the list, and staff see the request |
| 122 | straight away. When they approve it, the invite comes to the same address, |
| 123 | sometimes with a note, and its link opens sign-up with the address filled |
| 124 | in. There is no fixed date: g1t opens up a few people at a time. Asking |
| 125 | again with the same address updates your request without another email; it |
| 126 | does not move you down the list. |
| 127 | |
| 128 | ### Invites through the API |
| 129 | |
| 130 | | Route | MCP tool and action | What it does | |
| 131 | | --- | --- | --- | |
| 132 | | [`GET /user/invites`](/reference/api/invites/list-invites/) | `account` `list_invites` | Your invites and how many you have left | |
| 133 | | [`POST /user/invites`](/reference/api/invites/create-invite/) | `account` `create_invite` | Make an invite, optionally for one `email` | |
| 134 | | [`DELETE /user/invites/{id}`](/reference/api/invites/revoke-invite/) | `account` `revoke_invite` | Revoke a pending invite | |
| 135 | | [`POST /workspaces/{workspace}/invitations`](/reference/api/invites/invite-member/) | `workspace` `invite_member` | Invite an address into a workspace. Owners only. | |
| 136 | |
| 137 | ## Confirming your email |
| 138 | |
| 139 | g1t sends a confirmation link from `noreply@g1t.sh`. It works for 24 hours. |
| 140 | |
| 141 | Until you follow it you can sign in and look around, but you cannot create |
| 142 | repositories, push, or open issues and pull requests. Those requests fail with `403` and a |
| 143 | message telling you to confirm your address. To get a new link, sign in and |
| 144 | use the banner at the top of the site. |
| 145 | |
| 146 | ## Email addresses |
| 147 | |
| 148 | An account can have up to 10 email addresses. Manage them in |
| 149 | [Settings → Emails](https://g1t.sh/settings/emails). |
| 150 | |
| 151 | | An address that is | Can | |
| 152 | | --- | --- | |
| 153 | | Primary | Get account mail and password reset links. Exactly one, always confirmed once any address is. | |
| 154 | | Confirmed | Sign you in (type it instead of your username), ask for a password reset, and mark commits that carry it as yours. | |
| 155 | | Backup | Get security notices as well as the primary. Optional, and a confirmed address other than the primary. | |
| 156 | | Unconfirmed | Nothing yet. It is not yours until you follow the link g1t sent it. | |
| 157 | |
| 158 | A confirmed address belongs to one account. Anyone can add an address they |
| 159 | have not confirmed; the first account to follow its link keeps it, and the |
| 160 | address leaves every other account that added it. An address another |
| 161 | account has confirmed cannot be added. |
| 162 | |
| 163 | ### Add an address |
| 164 | |
| 165 | 1. Open [Settings → Emails](https://g1t.sh/settings/emails). |
| 166 | 2. Enter the address under **Add an email address** and select **Add**. |
| 167 | 3. Follow the link g1t sends it. The link works for 24 hours; **Resend |
| 168 | link** sends a new one, at most once a minute and 10 times an hour. |
| 169 | |
| 170 | If your account had no confirmed address yet, the first one you confirm |
| 171 | becomes your primary. |
| 172 | |
| 173 | ### Choose your primary and backup |
| 174 | |
| 175 | Select **Make primary** beside a confirmed address. Under **Backup |
| 176 | address**, choose a confirmed address to get security notices too, or |
| 177 | **Primary address only**. |
| 178 | |
| 179 | ### Remove an address |
| 180 | |
| 181 | Select **Remove** beside it. You cannot remove your primary address (make |
| 182 | another one primary first) or your last confirmed address. |
| 183 | |
| 184 | ### Confirming it is you |
| 185 | |
| 186 | Adding or removing an address, and changing your primary or backup, need |
| 187 | proof that it is you: a sign-in in the last 10 minutes, or your password, |
| 188 | which g1t asks for on the page. After you enter it, g1t does not ask again |
| 189 | for 10 minutes. An account that signs in only with GitHub signs out and in |
| 190 | with GitHub again, or sets a password with |
| 191 | [Forgot your password](https://g1t.sh/forgot). |
| 192 | |
| 193 | Each of these changes is emailed to every confirmed address on the account, |
| 194 | including an address that was just removed, and written to your |
| 195 | [security log](#security-log). |
| 196 | |
| 197 | ### Keeping your address private |
| 198 | |
| 199 | **Keep my email address private** is on for every account unless you turn |
| 200 | it off. While it is on, commits g1t makes for you (merging a pull request |
| 201 | on the web, catching a branch up, and commits an agent makes for you) carry |
| 202 | your noreply address instead of your primary: |
| 203 | |
| 204 | ``` |
| 205 | <8 characters of your account id>+<username>@users.noreply.g1t.sh |
| 206 | ``` |
| 207 | |
| 208 | The page shows yours. It never receives mail. Turn the setting off to put |
| 209 | your primary address on those commits instead. |
| 210 | |
| 211 | **Block pushes that expose my email** refuses a push that would publish one |
| 212 | of your addresses while you keep it private. When both settings are on, |
| 213 | g1t reads the new commits in each push you make, and declines the push if |
| 214 | any of them has one of your confirmed addresses as its author or committer |
| 215 | address. git shows why, with the address masked: |
| 216 | |
| 217 | ``` |
| 218 | remote: push declined: commit 3f9a1c2 would publish s***@gmail.com while your email is private. |
| 219 | remote: Commit with 6c1d0efg+sam@users.noreply.g1t.sh (git config user.email 6c1d0efg+sam@users.noreply.g1t.sh) and amend, |
| 220 | remote: or change this in g1t.sh/settings/emails. |
| 221 | ``` |
| 222 | |
| 223 | To push those commits: |
| 224 | |
| 225 | 1. Set your noreply address for the repository: |
| 226 | `git config user.email <your noreply address>`. |
| 227 | 2. Rewrite the commits with it. For the last commit, |
| 228 | `git commit --amend --reset-author --no-edit`; for several, |
| 229 | `git rebase <base> --exec "git commit --amend --reset-author --no-edit"`. |
| 230 | 3. Push again. |
| 231 | |
| 232 | Only your own addresses are checked: commits by other people in the same |
| 233 | push go through, and so does your noreply address. A push an agent makes |
| 234 | for you follows your settings. |
| 235 | |
| 236 | ### How commits are attributed |
| 237 | |
| 238 | g1t shows a commit as yours, with your picture and a link to your profile, |
| 239 | when its author address is one of your confirmed addresses or your noreply |
| 240 | address. Commits that g1t made for you before noreply addresses existed |
| 241 | (`<username>@users.g1t.sh`) count as yours too. An unconfirmed address |
| 242 | never attributes a commit, so nobody can claim your commits by adding your |
| 243 | address. Commits whose address matches no account show the name in the |
| 244 | commit. |
| 245 | |
| 246 | ### Email addresses through the API |
| 247 | |
| 248 | | Route | MCP tool and action | What it does | |
| 249 | | --- | --- | --- | |
| 250 | | [`GET /user/emails`](/reference/api/accounts/list-emails/) | `account` `list_emails` | Your addresses and email settings | |
| 251 | | [`POST /user/emails`](/reference/api/accounts/add-email/) | `account` `add_email` | Add an address; takes `email` and `password` | |
| 252 | | [`DELETE /user/emails/{email}`](/reference/api/accounts/remove-email/) | `account` `remove_email` | Remove an address; takes `password` | |
| 253 | | [`PATCH /user/email-settings`](/reference/api/accounts/update-email-settings/) | `account` `update_email_settings` | Change `primary`, `backup`, `private_email` or `block_private_pushes` | |
| 254 | |
| 255 | Through the API, `password` is the proof a sensitive change needs. Without |
| 256 | it, or with the wrong one, the answer is `403` with the code |
| 257 | `reauth_required`. Only a person's own token can use these: an agent's |
| 258 | token and a workspace's token are refused. |
| 259 | |
| 260 | ## Workspaces |
| 261 | |
| 262 | Your account does not own repositories itself: a workspace does. After |
| 263 | confirming your email, the first thing you do is create one. Workspaces, |
| 264 | their members and roles, and the access tokens that belong to a workspace |
| 265 | are covered in [workspaces](/guides/workspaces/). |
| 266 | |
| 267 | ## Access tokens |
| 268 | |
| 269 | A token stands in for your password everywhere outside the website: |
| 270 | |
| 271 | | Where | How to send it | |
| 272 | | --- | --- | |
| 273 | | git | As the password, with your username. | |
| 274 | | API | `Authorization: Bearer g1t_…` | |
| 275 | | MCP | The same header, set when you add the server. | |
| 276 | |
| 277 | A token is shown once, when it is created; g1t stores only a hash of it. |
| 278 | If you lose one, delete it and create another. Delete a token the moment |
| 279 | you think someone else has seen it. |
| 280 | |
| 281 | A token reaches everything you can reach, and its [scopes](#scopes) say |
| 282 | what it may do there. Give each token only the scopes the thing using it |
| 283 | needs. |
| 284 | |
| 285 | For CI and integrations that work for a team, a workspace can have tokens |
| 286 | of its own that act as the workspace and keep working when their creator |
| 287 | leaves. See [workspace tokens](#workspace-tokens). |
| 288 | |
| 289 | ### Create a token |
| 290 | |
| 291 | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens). |
| 292 | 2. Under **New token**, give it a **Name** after what will use it. |
| 293 | 3. Choose when it **Expires**: 7 days, 30 days, 90 days (the default), |
| 294 | 1 year, or No expiry. An expired token stops working; make a new one. |
| 295 | No expiry shows a warning: the token works until someone deletes it. |
| 296 | 4. Under **Scopes**, tick the boxes for what it may do. They are grouped |
| 297 | by area. The form starts on the **Agent** [preset](#presets); select |
| 298 | another preset to tick its boxes instead. |
| 299 | 5. Select **Create token**, and copy the token. It is not shown again. |
| 300 | |
| 301 | The list shows each token's name, when it was made and last used, when it |
| 302 | expires, and its access: a preset's name, its scopes, or Full access. To |
| 303 | change what a token may do, select **Edit access**, tick or untick boxes, |
| 304 | and select **Save access**. The token stays the same; the change applies |
| 305 | from its next request. |
| 306 | |
| 307 | ## Scopes |
| 308 | |
| 309 | A scope is a resource and a level, written `resource:level`, such as |
| 310 | `issues:write`. A higher level includes the lower ones of the same |
| 311 | resource: `repo:admin` includes `repo:write`, which includes `repo:read`. |
| 312 | It never includes another resource: `repo:admin` does not let a token push, |
| 313 | which is `code:write`. |
| 314 | |
| 315 | On the form, scopes are a checklist grouped by area: |
| 316 | |
| 317 | | Group | Scopes | |
| 318 | | --- | --- | |
| 319 | | Repositories & code | `repo:read`, `repo:write`, `code:read`, `code:write` | |
| 320 | | Issues & pull requests | `issues:read`, `issues:write`, `pull_requests:read`, `pull_requests:write` | |
| 321 | | Agents | `agents:run` | |
| 322 | | Workflows | `workflows:read`, `workflows:write` | |
| 323 | | Memory & search | `memory:read`, `memory:write` | |
| 324 | | Account | `account:read`, `account:write` | |
| 325 | | Workspace | `workspace:read`, `access:read`, `webhooks:read`, `secrets:read` | |
| 326 | | Dangerous | `repo:admin`, `workspace:admin`, `access:admin`, `webhooks:admin`, `secrets:admin` | |
| 327 | |
| 328 | Ticking a higher level ticks the lower ones of its resource and greys |
| 329 | them out: tick `issues:write` and `issues:read` is ticked too. Untick |
| 330 | `issues:write` and `issues:read` stays ticked. |
| 331 | |
| 332 | | Scope | What it lets a token do | |
| 333 | | --- | --- | |
| 334 | | `repo:read` | See repositories, their settings, labels and timelines, and search | |
| 335 | | `repo:write` | Create repositories, rename branches and change how pull requests merge | |
| 336 | | `repo:admin` | Rename, archive, transfer, delete or change who can see a repository | |
| 337 | | `code:read` | Clone and fetch private repositories with git | |
| 338 | | `code:write` | Push commits with git | |
| 339 | | `issues:read` | Read issues, comments and plans | |
| 340 | | `issues:write` | Open, edit, close and comment on issues | |
| 341 | | `pull_requests:read` | Read pull requests, their changes, sessions and merge queues | |
| 342 | | `pull_requests:write` | Open, review, close and merge pull requests | |
| 343 | | `agents:run` | Put g1t agents to work and message them, which uses the workspace's money | |
| 344 | | `workflows:read` | Read workflows, runs and logs | |
| 345 | | `workflows:write` | Run, cancel, rerun and turn workflows on or off | |
| 346 | | `memory:read` | Recall memory and search the workspace's context | |
| 347 | | `memory:write` | Save memory for the next agent | |
| 348 | | `account:read` | Read your email addresses, invites and invitations | |
| 349 | | `account:write` | Change your email addresses, make invites and answer invitations | |
| 350 | | `workspace:read` | Read workspace invites, integrations and model routes | |
| 351 | | `workspace:admin` | Create and delete workspaces, invite members, connect integrations | |
| 352 | | `access:read` | See who has access to repositories | |
| 353 | | `access:admin` | Give and take away access to repositories | |
| 354 | | `webhooks:read` | See webhooks and their deliveries | |
| 355 | | `webhooks:admin` | Create, change and delete webhooks | |
| 356 | | `secrets:read` | List secrets (never their values) and read variables | |
| 357 | | `secrets:admin` | Set and delete secrets and variables | |
| 358 | |
| 359 | Every operation of the API and the MCP server needs exactly one of these, |
| 360 | except `whoami` (`GET /user`), which any token may use. Each endpoint's page |
| 361 | in the [API reference](/reference/api/) names its scope, and so does each |
| 362 | action in [MCP tools](/reference/mcp/). A few calls need a second scope for |
| 363 | what they ask: |
| 364 | |
| 365 | | Call | Also needs | |
| 366 | | --- | --- | |
| 367 | | `delegate` (`POST /repos/{owner}/{name}/issues/delegate`, the `agent` tool's `delegate`), which opens an issue | `issues:write`, beside `agents:run` | |
| 368 | | `apply_plan` or `import_issue` (the `plan` tool's `apply`, the `issue` tool's `import`) with `assign: true` | `agents:run` | |
| 369 | | `update_repo` with `private` or `default_branch` | `repo:admin` | |
| 370 | |
| 371 | ### What a token can do |
| 372 | |
| 373 | What a request may do is where two things overlap: |
| 374 | |
| 375 | 1. **Your role.** A token reaches every workspace and repository you can, |
| 376 | including ones you join later, and never does more there than you could |
| 377 | on the website. A token with `repo:admin` still cannot delete a |
| 378 | repository unless you are an owner of its workspace. See |
| 379 | [access and roles](/guides/access-and-roles/). |
| 380 | 2. **Its scopes.** What kinds of thing it may do. |
| 381 | |
| 382 | To keep a token away from a workspace, use a |
| 383 | [workspace token](#workspace-tokens) instead: it reaches only its own |
| 384 | workspace. |
| 385 | |
| 386 | ### Presets |
| 387 | |
| 388 | A preset ticks a starting set of boxes. Select one, then tick or untick |
| 389 | any box. |
| 390 | |
| 391 | | Preset | Scopes | |
| 392 | | --- | --- | |
| 393 | | Read only | Every `read` scope. Changes nothing. | |
| 394 | | Agent | Every `read` scope, and `code:write`, `issues:write`, `pull_requests:write`, `agents:run` and `memory:write`. Reads everything, works on issues and pull requests, pushes code and runs g1t agents. No admin scope. | |
| 395 | | CI | `repo:read`, `code:read`, `code:write`, `workflows:read` and `workflows:write`. Clones and pushes code, and runs workflows. | |
| 396 | | Full access | Everything you can do, including deleting repositories and changing who has access. Marked **Dangerous**. | |
| 397 | |
| 398 | Admin scopes change things that are hard to undo, or decide who can reach |
| 399 | what. They are under **Dangerous**, with a warning. Give them only to |
| 400 | something you trust as much as yourself. |
| 401 | |
| 402 | ### Git and scopes |
| 403 | |
| 404 | Over HTTPS, git checks the same token: |
| 405 | |
| 406 | | To | Needs | |
| 407 | | --- | --- | |
| 408 | | Clone or fetch a public repository | No scope | |
| 409 | | Clone or fetch a private repository | `code:read` | |
| 410 | | Push | `code:write` | |
| 411 | |
| 412 | Your role on the repository applies too, as on the website. A refused push |
| 413 | or clone says which scope is missing. |
| 414 | |
| 415 | ### When a token lacks a scope |
| 416 | |
| 417 | The API answers `403` with the scope that was missing in `needed_scope`: |
| 418 | |
| 419 | ```json |
| 420 | { |
| 421 | "error": { |
| 422 | "code": "forbidden", |
| 423 | "message": "This access token needs the issues:write scope to use create_issue.", |
| 424 | "needed_scope": "issues:write" |
| 425 | } |
| 426 | } |
| 427 | ``` |
| 428 | |
| 429 | Through MCP the same message comes back as a tool result with `isError` |
| 430 | set. Give the token that scope with **Edit access**, or make a new token. |
| 431 | |
| 432 | ### Tokens made before scopes |
| 433 | |
| 434 | Tokens and OAuth sign-ins made before tokens had scopes keep full access, |
| 435 | so nothing that uses them stops working. Settings marks each one |
| 436 | **Legacy · full access**, and says to narrow it to what it needs. For a |
| 437 | token, select **Narrow this token**; for an application, **Change access** |
| 438 | in [Connected applications](https://g1t.sh/settings/applications). Then |
| 439 | tick its scopes. A token you make with Full access on purpose is not marked |
| 440 | legacy. |
| 441 | |
| 442 | A token from [signing in from a tool](#signing-in-from-a-tool), such as the |
| 443 | g1t CLI, has full access. |
| 444 | |
| 445 | ### Workspace tokens |
| 446 | |
| 447 | A workspace's own tokens act as the workspace rather than a person. An |
| 448 | owner makes them in the workspace's **Settings → Access tokens**, with the |
| 449 | same checklist and expiry choices; the form starts on the CI preset. A |
| 450 | workspace token reaches all of that workspace's repositories, never |
| 451 | another workspace, and cannot manage people, tokens or workspaces. See |
| 452 | [workspace access tokens](/guides/workspaces/#workspace-access-tokens). |
| 453 | |
| 454 | ## Signing in with OAuth |
| 455 | |
| 456 | Applications that can open your browser, such as an agent connecting to the |
| 457 | [MCP server](/guides/bring-your-own-agent/), sign you in with OAuth 2.1. |
| 458 | You see a page on g1t naming the application and where it will send you |
| 459 | back, and you approve or deny. The application never sees your password and |
| 460 | there is no token to copy. |
| 461 | |
| 462 | The page lists what the application will be able to do, as the same |
| 463 | checklist a token has, with only the scopes it asked for, all ticked. |
| 464 | Untick anything you would rather it could not do, leaving at least one; |
| 465 | you cannot give it more than it asked for. Like a token, it reaches |
| 466 | everything you can. |
| 467 | |
| 468 | An application that asks for no scopes in particular gets the |
| 469 | [Agent preset](#presets): every `read` scope, and `code:write`, |
| 470 | `issues:write`, `pull_requests:write`, `agents:run` and `memory:write`. |
| 471 | It never gets an admin scope unless it asks for one and you leave it |
| 472 | ticked. |
| 473 | |
| 474 | Applications you have approved are listed in |
| 475 | [Settings → Connected applications](https://g1t.sh/settings/applications), |
| 476 | each with its access. Select **Change access** to tick or untick its |
| 477 | scopes, then **Save access**: it stays signed in, the change applies at |
| 478 | once, and its next refresh keeps it. Select **Sign out** to end its access |
| 479 | at once. |
| 480 | |
| 481 | For people building a client: |
| 482 | |
| 483 | | | | |
| 484 | | --- | --- | |
| 485 | | Metadata | `https://api.g1t.sh/.well-known/oauth-authorization-server` | |
| 486 | | Authorization | `https://g1t.sh/oauth/authorize` | |
| 487 | | Token | `https://api.g1t.sh/oauth/token` | |
| 488 | | Registration | `https://api.g1t.sh/oauth/register` | |
| 489 | |
| 490 | - The flow is authorization code with PKCE. `S256` is required. |
| 491 | - Clients are public: there are no client secrets. |
| 492 | - Register with `client_name` and `redirect_uris`. A redirect address is an |
| 493 | `https` URL, `http` on `localhost`, or the application's own scheme. A |
| 494 | client on `localhost` may use any port. |
| 495 | - Registration stores nothing. The client id it returns encodes what was |
| 496 | registered, so it cannot be used to fill g1t with junk. |
| 497 | - Ask for scopes with `scope` on the authorization request, separated by |
| 498 | spaces, such as `scope=repo:read issues:write pull_requests:write`. |
| 499 | Names g1t does not know are left out. Leave `scope` out for the Agent |
| 500 | preset. The authorization server's metadata and |
| 501 | `https://mcp.g1t.sh/.well-known/oauth-protected-resource` list every |
| 502 | scope in `scopes_supported`. |
| 503 | - The token response's `scope` holds the scopes the person granted, |
| 504 | separated by spaces, or `*` for a sign-in with full access. Refreshing |
| 505 | keeps them. |
| 506 | - An access token lasts 30 days. The refresh token returned with it works |
| 507 | once and returns the next pair; the previous access token stops working. |
| 508 | - An authorization code lasts five minutes and works once. |
| 509 | |
| 510 | ## Signing in from a tool |
| 511 | |
| 512 | A tool that cannot receive a redirect, such as a script on a remote machine, |
| 513 | gets a token without ever handling your password: |
| 514 | |
| 515 | 1. The tool asks g1t for a code and shows you a link and a short code such |
| 516 | as `WDJB-MJHT`. |
| 517 | 2. You open the link, sign in (or create an account), check that the code |
| 518 | matches, and approve. |
| 519 | 3. The tool collects its token. |
| 520 | |
| 521 | ```sh |
| 522 | # 1. The tool starts a sign-in. |
| 523 | curl -X POST https://api.g1t.sh/device/code -H "Content-Type: application/json" -d '{"client_name": "my-tool"}' |
| 524 | |
| 525 | # 2. You open verification_uri_complete from the response and approve. |
| 526 | |
| 527 | # 3. The tool polls, no faster than "interval" seconds, until it is approved. |
| 528 | curl -X POST https://api.g1t.sh/device/token -H "Content-Type: application/json" -d '{"device_code": "…"}' |
| 529 | ``` |
| 530 | |
| 531 | The poll answers with a `status` of `pending`, `approved`, `denied` or |
| 532 | `expired`. An approved answer carries the token, once. Codes expire after 15 |
| 533 | minutes. The token appears in |
| 534 | [Settings → Access tokens](https://g1t.sh/settings/tokens) under the tool's name, where you |
| 535 | can delete it. |
| 536 | |
| 537 | Only approve a code you asked for. The token has full access: it can do |
| 538 | everything you can. To give a tool less, make an |
| 539 | [access token](#create-a-token) with only the scopes it needs instead. |
| 540 | |
| 541 | ## Resetting your password |
| 542 | |
| 543 | Use [g1t.sh/forgot](https://g1t.sh/forgot) and enter any confirmed |
| 544 | address of your account. The link goes to that address and works for one |
| 545 | hour; your primary and backup addresses are told a reset was asked for |
| 546 | when it went elsewhere. A new account that has not confirmed its address |
| 547 | yet can use that address, and following the link confirms it. |
| 548 | |
| 549 | The page answers the same way whether or not the address has an account. |
| 550 | g1t sends at most 5 reset links an hour to one address. |
| 551 | |
| 552 | Setting a new password signs you out everywhere and emails your primary |
| 553 | and backup addresses. |
| 554 | |
| 555 | ## Too many attempts |
| 556 | |
| 557 | g1t counts wrong passwords, on the sign-in page, for git over HTTPS and |
| 558 | when confirming it is you, against the account and against where they come |
| 559 | from. After 10 wrong passwords for one account in an hour, or 30 from one |
| 560 | place, g1t stops checking passwords for it for a minute, then twice as long |
| 561 | after each further wrong password, up to an hour. While it waits, every |
| 562 | attempt gets the same answer: "Too many attempts". The account's primary |
| 563 | and backup addresses are told the first time. Signing in with the right |
| 564 | password, or resetting it, clears the count. Access tokens, SSH keys and |
| 565 | GitHub sign-in are not affected. |
| 566 | |
| 567 | ## Security log |
| 568 | |
| 569 | [Settings → Security log](https://g1t.sh/settings/security-log) lists what |
| 570 | happened to your account: addresses added, confirmed, removed or made |
| 571 | primary, your backup and privacy settings, password changes, and pauses |
| 572 | after too many wrong passwords. Changes g1t staff made, such as removing an |
| 573 | address someone else needed, say so and why. |
| 574 | |
| 575 | ## What g1t stores |
| 576 | |
| 577 | Passwords are stored as salted PBKDF2-SHA256 hashes. Sessions and tokens are |
| 578 | stored as SHA-256 hashes. Neither can be read back. |