Skip to content

g1t/apps/docs/src/content/docs/guides/authentication.md

603 lines30,358 bytesCodeBlame
1---
2title: Accounts and authentication
3description: 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
8g1t 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
11on the same page. Usernames are lowercase letters, digits and single
12hyphens, up to 39 characters.
13
14Accounts can only be created in a browser. There is no API for it, by
15design: it keeps passwords out of scripts and agents, and lets g1t protect
16the one place accounts are made.
17
18## Your settings
19
20Your own settings are at [g1t.sh/settings](https://g1t.sh/settings), one
21page each. Open them from your account menu at the bottom of the sidebar,
22under **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
40your GitHub account, and makes a g1t account the first time. Link or
41unlink GitHub in [Settings → GitHub](https://g1t.sh/settings/github). See
42[GitHub](/guides/github/#sign-in-with-github).
43
44Making an account with GitHub needs an invite too: start from your invite
45link, or enter the code when g1t asks for it after GitHub.
46
47## Invites
48
49While 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
51people 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
60Every invite email links to `g1t.sh/invite/<code>`. That one page shows
61who sent it and what it is for (joining a workspace, collaborating on a
62repository, or just making an account), and finishes the job there:
63
641. **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.
702. **The address already has an account**: select **Sign in to accept**.
71 After you sign in, the invite is accepted for you.
723. **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
76Once 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
79code typed at [g1t.sh/register](https://g1t.sh/register) goes to the
80same page.
81
82An expired, revoked or used invite says which, and who sent it, so you
83can ask them for a new one; or ask for access from the same page.
84
85### Making invites
86
871. Open [Settings → Invites](https://g1t.sh/settings/invites).
882. 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.
913. Select **Create invite**, then copy the link.
92
93Each person can have **5** invites out at a time. Pending and used invites
94count; an invite you revoke, or one that expires before anyone uses it,
95comes back to you. The list under the form shows each invite's state:
96pending, joined (with the username of who joined), expired or revoked. You
97must confirm your email before you can make invites. An agent's token and
98a workspace's token cannot make them.
99
100### Inviting someone into a workspace
101
102An owner can invite an email address straight into a workspace from its
103People page; see [members and roles](/guides/workspaces/#members-and-roles).
104When the address has no g1t account, accepting makes the account and joins
105the workspace in one step, and it uses one invite. Inviting someone who is
106already on g1t costs nothing.
107
108### Need more invites?
109
110Write to [hey@flagon.io](mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20)
111with the subject `[g1t Invites]` and say who you would like to bring. g1t
112can give more invites to you, or to a workspace, whose owners then share
113them. Invites given to a workspace appear under
114[Settings → Invites](https://g1t.sh/settings/invites) for
115each of its owners, as a choice of whose invites to use.
116
117### Asking for access
118
119Without an invite, [g1t.sh/register](https://g1t.sh/register) asks for your
120email address and, if you like, what you will build. g1t emails that
121address once to confirm you are on the list, and staff see the request
122straight away. When they approve it, the invite comes to the same address,
123sometimes with a note, and its link opens sign-up with the address filled
124in. There is no fixed date: g1t opens up a few people at a time. Asking
125again with the same address updates your request without another email; it
126does 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
139g1t sends a confirmation link from `noreply@g1t.sh`. It works for 24 hours.
140
141Until you follow it you can sign in and look around, but you cannot create
142repositories, push, or open issues and pull requests. Those requests fail with `403` and a
143message telling you to confirm your address. To get a new link, sign in and
144use the banner at the top of the site.
145
146## Email addresses
147
148An 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
158A confirmed address belongs to one account. Anyone can add an address they
159have not confirmed; the first account to follow its link keeps it, and the
160address leaves every other account that added it. An address another
161account has confirmed cannot be added.
162
163### Add an address
164
1651. Open [Settings → Emails](https://g1t.sh/settings/emails).
1662. Enter the address under **Add an email address** and select **Add**.
1673. 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
170If your account had no confirmed address yet, the first one you confirm
171becomes your primary.
172
173### Choose your primary and backup
174
175Select **Make primary** beside a confirmed address. Under **Backup
176address**, choose a confirmed address to get security notices too, or
177**Primary address only**.
178
179### Remove an address
180
181Select **Remove** beside it. You cannot remove your primary address (make
182another one primary first) or your last confirmed address.
183
184### Confirming it is you
185
186Adding or removing an address, and changing your primary or backup, need
187proof that it is you: a sign-in in the last 10 minutes, or your password,
188which g1t asks for on the page. After you enter it, g1t does not ask again
189for 10 minutes. An account that signs in only with GitHub signs out and in
190with GitHub again, or sets a password with
191[Forgot your password](https://g1t.sh/forgot).
192
193Each of these changes is emailed to every confirmed address on the account,
194including 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
200it off. While it is on, commits g1t makes for you (merging a pull request
201on the web, catching a branch up, and commits an agent makes for you) carry
202your noreply address instead of your primary:
203
204```
205<8 characters of your account id>+<username>@users.noreply.g1t.sh
206```
207
208The page shows yours. It never receives mail. Turn the setting off to put
209your primary address on those commits instead.
210
211**Block pushes that expose my email** refuses a push that would publish one
212of your addresses while you keep it private. When both settings are on,
213g1t reads the new commits in each push you make, and declines the push if
214any of them has one of your confirmed addresses as its author or committer
215address. git shows why, with the address masked:
216
217```
218remote: push declined: commit 3f9a1c2 would publish s***@gmail.com while your email is private.
219remote: Commit with 6c1d0efg+sam@users.noreply.g1t.sh (git config user.email 6c1d0efg+sam@users.noreply.g1t.sh) and amend,
220remote: or change this in g1t.sh/settings/emails.
221```
222
223To push those commits:
224
2251. Set your noreply address for the repository:
226 `git config user.email <your noreply address>`.
2272. 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"`.
2303. Push again.
231
232Only your own addresses are checked: commits by other people in the same
233push go through, and so does your noreply address. A push an agent makes
234for you follows your settings.
235
236### How commits are attributed
237
238g1t shows a commit as yours, with your picture and a link to your profile,
239when its author address is one of your confirmed addresses or your noreply
240address. Commits that g1t made for you before noreply addresses existed
241(`<username>@users.g1t.sh`) count as yours too. An unconfirmed address
242never attributes a commit, so nobody can claim your commits by adding your
243address. Commits whose address matches no account show the name in the
244commit.
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
255Through the API, `password` is the proof a sensitive change needs. Without
256it, 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
258token and a workspace's token are refused.
259
260## Workspaces
261
262Your account does not own repositories itself: a workspace does. After
263confirming your email, the first thing you do is create one. Workspaces,
264their members and roles, and the access tokens that belong to a workspace
265are covered in [workspaces](/guides/workspaces/).
266
267## Access tokens
268
269A 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
277A token is shown once, when it is created; g1t stores only a hash of it.
278If you lose one, delete it and create another. Delete a token the moment
279you think someone else has seen it.
280
281A token reaches everything you can reach, and its [scopes](#scopes) say
282what it may do there. Give each token only the scopes the thing using it
283needs.
284
285For CI and integrations that work for a team, a workspace can have tokens
286of its own that act as the workspace and keep working when their creator
287leaves. See [workspace tokens](#workspace-tokens).
288
289### Create a token
290
2911. Open [Settings → Access tokens](https://g1t.sh/settings/tokens).
2922. Under **New token**, give it a **Name** after what will use it.
2933. 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.
2964. 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.
2995. Select **Create token**, and copy the token. It is not shown again.
300
301The list shows each token's name, when it was made and last used, when it
302expires, and its access: a preset's name, its scopes, or Full access. To
303change what a token may do, select **Edit access**, tick or untick boxes,
304and select **Save access**. The token stays the same; the change applies
305from its next request.
306
307## Scopes
308
309A 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
311resource: `repo:admin` includes `repo:write`, which includes `repo:read`.
312It never includes another resource: `repo:admin` does not let a token push,
313which is `code:write`.
314
315On 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| Packages | `packages:read`, `packages:write` |
321| Issues & pull requests | `issues:read`, `issues:write`, `pull_requests:read`, `pull_requests:write` |
322| Agents | `agents:run` |
323| Workflows | `workflows:read`, `workflows:write` |
324| Deployments | `deployments:read`, `deployments:write` |
325| Memory & search | `memory:read`, `memory:write` |
326| Account | `account:read`, `account:write` |
327| Notifications | `notifications:read`, `notifications:write` |
328| Security | `security:read`, `security:write` |
329| Workspace | `workspace:read`, `access:read`, `webhooks:read`, `secrets:read` |
330| Billing | `billing:read`, `billing:write` |
331| Runners | `runners:read` |
332| AI Gateway | `models:read`, `models:write` |
333| Dangerous | `repo:admin`, `packages:delete`, `workspace:admin`, `access:admin`, `webhooks:admin`, `secrets:admin`, `runners:admin` |
334
335Ticking a higher level ticks the lower ones of its resource and greys
336them out: tick `issues:write` and `issues:read` is ticked too. Untick
337`issues:write` and `issues:read` stays ticked.
338
339| Scope | What it lets a token do |
340| --- | --- |
341| `repo:read` | See repositories, their settings, labels, timelines, releases, languages, contributors and security alerts, and search |
342| `repo:write` | Create repositories, rename branches, change how pull requests merge and publish releases |
343| `repo:admin` | Rename, archive, transfer, delete or change who can see a repository, and dismiss security alerts |
344| `code:read` | Clone and fetch private repositories with git |
345| `code:write` | Push commits with git |
346| `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 |
347| `security:write` | Dismiss and reopen alerts, bypass push protection, review bypass requests, manage custom patterns, upload SARIF and change security settings |
348| `packages:read` | Pull container images and install private [packages](/guides/packages/). Public ones need no scope. |
349| `packages:write` | Push container images and publish packages |
350| `packages:delete` | Delete packages and their versions |
351| `issues:read` | Read issues, comments and plans |
352| `issues:write` | Open, edit, close and comment on issues |
353| `pull_requests:read` | Read pull requests, their changes, sessions and merge queues |
354| `pull_requests:write` | Open, review, close and merge pull requests |
355| `agents:run` | Put g1t to work and message it, which uses the workspace's money |
356| `workflows:read` | Read workflows, runs and logs |
357| `workflows:write` | Run, cancel, rerun and turn workflows on or off |
358| `deployments:read` | See [deployments](/guides/deployments-api/), their statuses and environments |
359| `deployments:write` | Report deployments and their statuses, from any CI |
360| `memory:read` | Recall memory and search the workspace's context |
361| `memory:write` | Save memory for the next agent |
362| `account:read` | Read your email addresses, invites, invitations, pinned projects and stars |
363| `account:write` | Change your email addresses, make invites, answer invitations, pin projects and star repositories |
364| `notifications:read` | See your [inbox](/guides/inbox/), its threads, and what you subscribe to and watch |
365| `notifications:write` | Mark notifications read, done, saved or snoozed, subscribe to threads and watch repositories |
366| `workspace:read` | Read workspace settings, invites, integrations, model routes and [teams](/guides/teams/) |
367| `workspace:admin` | Create and delete workspaces, invite members, manage teams, connect integrations |
368| `billing:read` | See a workspace's [usage, budget, AI credit and invoices](/guides/usage-and-billing/) |
369| `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 but full access. |
370| `access:read` | See who has access to repositories |
371| `access:admin` | Give people and teams access to repositories, and take it away |
372| `webhooks:read` | See webhooks and their deliveries |
373| `webhooks:admin` | Create, change and delete webhooks |
374| `secrets:read` | List secrets (never their values) and read variables |
375| `secrets:admin` | Set and delete secrets and variables |
376| `runners:read` | See [self-hosted runners](/guides/self-hosted-runners/), their groups and where agents run. Not in the Agent preset. |
377| `runners:admin` | Register and remove self-hosted runners, change their groups and settings |
378| `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status |
379| `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 but full access. |
380
381Every operation of the API and the MCP server needs exactly one of these,
382except `whoami` (`GET /user`), which any token may use. Each endpoint's page
383in the [API reference](/reference/api/) names its scope, and so does each
384action in [MCP tools](/reference/mcp/). A few calls need a second scope for
385what they ask:
386
387| Call | Also needs |
388| --- | --- |
389| `delegate` (`POST /repos/{owner}/{name}/issues/delegate`, the `agent` tool's `delegate`), which opens an issue | `issues:write`, beside `agents:run` |
390| `apply_plan` or `import_issue` (the `plan` tool's `apply`, the `issue` tool's `import`) with `assign: true` | `agents:run` |
391| `update_repo` with `private` or `default_branch` | `repo:admin` |
392
393### What a token can do
394
395What a request may do is where two things overlap:
396
3971. **Your role.** A token reaches every workspace and repository you can,
398 including ones you join later, and never does more there than you could
399 on the website. A token with `repo:admin` still cannot delete a
400 repository unless you are an owner of its workspace. See
401 [access and roles](/guides/access-and-roles/).
4022. **Its scopes.** What kinds of thing it may do.
403
404To keep a token away from a workspace, use a
405[workspace token](#workspace-tokens) instead: it reaches only its own
406workspace.
407
408### Presets
409
410A preset ticks a starting set of boxes. Select one, then tick or untick
411any box.
412
413| Preset | Scopes |
414| --- | --- |
415| Read only | Every `read` scope. Changes nothing. |
416| Agent | Every `read` scope except `runners:read`, and `code:write`, `issues:write`, `pull_requests:write`, `agents:run`, `memory:write` and `notifications:write`. Reads everything, works on issues and pull requests, pushes code, puts g1t to work, and answers your inbox. No admin scope. |
417| CI | `repo:read`, `code:read`, `code:write`, `packages:read`, `packages:write`, `workflows:read`, `workflows:write`, `deployments:read` and `deployments:write`. Clones and pushes code, pushes and pulls packages, runs workflows and reports deployments. |
418| Full access | Everything you can do, including deleting repositories and changing who has access. Marked **Dangerous**. |
419
420Admin scopes change things that are hard to undo, or decide who can reach
421what. They are under **Dangerous**, with a warning. Give them only to
422something you trust as much as yourself.
423
424### Git and scopes
425
426Over HTTPS, git checks the same token:
427
428| To | Needs |
429| --- | --- |
430| Clone or fetch a public repository | No scope |
431| Clone or fetch a private repository | `code:read` |
432| Push | `code:write` |
433
434Your role on the repository applies too, as on the website. A refused push
435or clone says which scope is missing.
436
437### When a token lacks a scope
438
439The API answers `403` with the scope that was missing in `needed_scope`:
440
441```json
442{
443 "error": {
444 "code": "forbidden",
445 "message": "This access token needs the issues:write scope to use create_issue.",
446 "needed_scope": "issues:write"
447 }
448}
449```
450
451Through MCP the same message comes back as a tool result with `isError`
452set. Give the token that scope with **Edit access**, or make a new token.
453
454### Tokens made before scopes
455
456Tokens and OAuth sign-ins made before tokens had scopes keep full access,
457so nothing that uses them stops working. Settings marks each one
458**Legacy · full access**, and says to narrow it to what it needs. For a
459token, select **Narrow this token**; for an application, **Change access**
460in [Connected applications](https://g1t.sh/settings/applications). Then
461tick its scopes. A token you make with Full access on purpose is not marked
462legacy.
463
464A token from [signing in from a tool](#signing-in-from-a-tool), such as the
465g1t CLI, has full access.
466
467### Workspace tokens
468
469A workspace's own tokens act as the workspace rather than a person. An
470owner makes them in the workspace's **Settings → Access tokens**, with the
471same checklist and expiry choices; the form starts on the CI preset. A
472workspace token reaches all of that workspace's repositories, never
473another workspace, and cannot manage people, tokens or workspaces. See
474[workspace access tokens](/guides/workspaces/#workspace-access-tokens).
475
476## Signing in with OAuth
477
478Applications that can open your browser, such as an agent connecting to the
479[MCP server](/guides/bring-your-own-agent/), sign you in with OAuth 2.1.
480You see a page on g1t naming the application and where it will send you
481back, and you approve or deny. The application never sees your password and
482there is no token to copy.
483
484The page lists what the application will be able to do, as the same
485checklist a token has, with only the scopes it asked for, all ticked.
486Untick anything you would rather it could not do, leaving at least one;
487you cannot give it more than it asked for. Like a token, it reaches
488everything you can.
489
490An application that asks for no scopes in particular gets the
491[Agent preset](#presets): every `read` scope except `runners:read`, and `code:write`,
492`issues:write`, `pull_requests:write`, `agents:run`, `memory:write` and
493`notifications:write`.
494It never gets an admin scope unless it asks for one and you leave it
495ticked.
496
497Applications you have approved are listed in
498[Settings → Connected applications](https://g1t.sh/settings/applications),
499each with its access. Select **Change access** to tick or untick its
500scopes, then **Save access**: it stays signed in, the change applies at
501once, and its next refresh keeps it. Select **Sign out** to end its access
502at once.
503
504For people building a client:
505
506| | |
507| --- | --- |
508| Metadata | `https://api.g1t.sh/.well-known/oauth-authorization-server` |
509| Authorization | `https://g1t.sh/oauth/authorize` |
510| Token | `https://api.g1t.sh/oauth/token` |
511| Registration | `https://api.g1t.sh/oauth/register` |
512
513- The flow is authorization code with PKCE. `S256` is required.
514- Clients are public: there are no client secrets.
515- Register with `client_name` and `redirect_uris`. A redirect address is an
516 `https` URL, `http` on `localhost`, or the application's own scheme. A
517 client on `localhost` may use any port.
518- Registration stores nothing. The client id it returns encodes what was
519 registered, so it cannot be used to fill g1t with junk.
520- Ask for scopes with `scope` on the authorization request, separated by
521 spaces, such as `scope=repo:read issues:write pull_requests:write`.
522 Names g1t does not know are left out. Leave `scope` out for the Agent
523 preset. The authorization server's metadata and
524 `https://mcp.g1t.sh/.well-known/oauth-protected-resource` list every
525 scope in `scopes_supported`.
526- The token response's `scope` holds the scopes the person granted,
527 separated by spaces, or `*` for a sign-in with full access. Refreshing
528 keeps them.
529- An access token lasts 30 days. The refresh token returned with it works
530 once and returns the next pair; the previous access token stops working.
531- An authorization code lasts five minutes and works once.
532
533## Signing in from a tool
534
535A tool that cannot receive a redirect, such as a script on a remote machine,
536gets a token without ever handling your password:
537
5381. The tool asks g1t for a code and shows you a link and a short code such
539 as `WDJB-MJHT`.
5402. You open the link, sign in (or create an account), check that the code
541 matches, and approve.
5423. The tool collects its token.
543
544```sh
545# 1. The tool starts a sign-in.
546curl -X POST https://api.g1t.sh/device/code -H "Content-Type: application/json" -d '{"client_name": "my-tool"}'
547
548# 2. You open verification_uri_complete from the response and approve.
549
550# 3. The tool polls, no faster than "interval" seconds, until it is approved.
551curl -X POST https://api.g1t.sh/device/token -H "Content-Type: application/json" -d '{"device_code": "…"}'
552```
553
554The poll answers with a `status` of `pending`, `approved`, `denied` or
555`expired`. An approved answer carries the token, once. Codes expire after 15
556minutes. The token appears in
557[Settings → Access tokens](https://g1t.sh/settings/tokens) under the tool's name, where you
558can delete it.
559
560Only approve a code you asked for. The token has full access: it can do
561everything you can. To give a tool less, make an
562[access token](#create-a-token) with only the scopes it needs instead.
563
564## Resetting your password
565
566Use [g1t.sh/forgot](https://g1t.sh/forgot) and enter any confirmed
567address of your account. The link goes to that address and works for one
568hour; your primary and backup addresses are told a reset was asked for
569when it went elsewhere. A new account that has not confirmed its address
570yet can use that address, and following the link confirms it.
571
572The page answers the same way whether or not the address has an account.
573g1t sends at most 5 reset links an hour to one address. If g1t cannot
574take the request at all, the page says so and keeps what you typed, so you
575can try again.
576
577Setting a new password signs you out everywhere and emails your primary
578and backup addresses.
579
580## Too many attempts
581
582g1t counts wrong passwords, on the sign-in page, for git over HTTPS and
583when confirming it is you, against the account and against where they come
584from. After 10 wrong passwords for one account in an hour, or 30 from one
585place, g1t stops checking passwords for it for a minute, then twice as long
586after each further wrong password, up to an hour. While it waits, every
587attempt gets the same answer: "Too many attempts". The account's primary
588and backup addresses are told the first time. Signing in with the right
589password, or resetting it, clears the count. Access tokens, SSH keys and
590GitHub sign-in are not affected.
591
592## Security log
593
594[Settings → Security log](https://g1t.sh/settings/security-log) lists what
595happened to your account: addresses added, confirmed, removed or made
596primary, your backup and privacy settings, password changes, and pauses
597after too many wrong passwords. Changes g1t staff made, such as removing an
598address someone else needed, say so and why.
599
600## What g1t stores
601
602Passwords are stored as salted PBKDF2-SHA256 hashes. Sessions and tokens are
603stored as SHA-256 hashes. Neither can be read back.