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