Skip to content
968 linesCodeBlameRaw
1---
2title: Accounts and authentication
3description: Accounts, invites, email addresses, confirming them, two-factor authentication and recovery codes, fine-grained and classic personal access tokens, scopes and permissions, a workspace's rules for tokens, 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
14Before you can do anything else, you [confirm your email
15address](#confirming-your-email-address) with the code g1t emails you.
16
17Accounts can only be created in a browser. There is no API for it, by
18design: it keeps passwords out of scripts and agents, and lets g1t protect
19the one place accounts are made.
20
21## Your settings
22
23Your own settings are at [g1t.sh/settings](https://g1t.sh/settings), one
24page each. Open them from your account menu at the bottom of the sidebar,
25under **Your settings**; the sidebar then lists every page.
26
27| Page | Address | What is on it |
28| --- | --- | --- |
29| Profile | [`/settings/profile`](https://g1t.sh/settings/profile) | Your picture, and your [public profile](/guides/workspaces/#profiles): name, pronouns, bio, location and website. |
30| 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). |
31| Invites | [`/settings/invites`](https://g1t.sh/settings/invites) | [Making, copying and revoking invites](#invites). |
32| 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. |
33| Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens): fine-grained and classic. |
34| GitHub | [`/settings/github`](https://g1t.sh/settings/github) | [Linking and unlinking GitHub](/guides/github/#link-and-unlink-github). |
35| 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. |
36| Two-factor authentication | [`/settings/two-factor`](https://g1t.sh/settings/two-factor) | [An authenticator app and recovery codes](#two-factor-authentication). |
37| Security log | [`/settings/security-log`](https://g1t.sh/settings/security-log) | [What happened to your account](#security-log). |
38
39`g1t.sh/settings` opens Profile.
40
41## Signing in with GitHub
42
43**Continue with GitHub** on the sign-in and sign-up pages signs you in with
44your GitHub account, and makes a g1t account the first time. Link or
45unlink GitHub in [Settings → GitHub](https://g1t.sh/settings/github). See
46[GitHub](/guides/github/#sign-in-with-github).
47
48Making an account with GitHub needs an invite too: start from your invite
49link, or enter the code when g1t asks for it after GitHub.
50
51With [two-factor authentication](#two-factor-authentication) on, signing in
52with GitHub asks for a code from your app as well.
53
54## Two-factor authentication
55
56Two-factor authentication asks for a code from an authenticator app on
57your phone each time you sign in with your password or with GitHub, so a
58stolen password is not enough. Any app that reads a time-based one-time
59password (TOTP) QR code works, such as 1Password, Google Authenticator or
60Authy.
61
62### Turn it on
63
641. Open [Settings → Two-factor authentication](https://g1t.sh/settings/two-factor)
65 and choose **Set up**. g1t asks for your password if you have not
66 signed in in the last 10 minutes.
672. Scan the QR code with your app, or type the key shown under it.
683. Enter the six-digit code the app shows, and choose **Turn on**.
694. Save the ten recovery codes g1t shows. They are shown only then.
70
71### Signing in with it on
72
73After your password (or GitHub), g1t asks for the code from your app. A
74code works for 30 seconds, and the one before and after it are accepted
75too, for a phone clock a little off. Each code works once. After five wrong
76codes, or ten minutes, start the sign-in again.
77
78Lost your phone? Enter a recovery code instead of the app's code. Each
79works once, and your security log records its use.
80
81Git over HTTPS never takes your password while two-factor authentication
82is on: use a [personal access token](#access-tokens) as the password, or
83[SSH](/guides/git/). Access tokens, SSH keys and OAuth applications are
84not affected.
85
86### Recovery codes, and turning it off
87
88On the same page:
89
90- **Make new recovery codes** replaces all ten; the old ones stop working.
91- **Turn off** needs a code from your app or a recovery code, and your
92 password if you have not signed in in the last 10 minutes.
93
94You cannot turn it off while you own a workspace that
95[requires it](/guides/workspaces/#require-two-factor-authentication): stop
96requiring it there first, or hand the workspace to another owner. In a
97workspace that requires it, turning it off holds you out of that workspace
98until you turn it on again.
99
100Turning it on or off, and making new recovery codes, are emailed to your
101primary and backup addresses, written to your [security log](#security-log),
102and recorded in the [audit log](/guides/audit-log/) of each of your
103workspaces as `two_factor.enabled` and `two_factor.disabled`.
104
105### Require two-factor authentication
106
107An owner can require it of everyone with access to a workspace. See
108[Workspaces](/guides/workspaces/#require-two-factor-authentication).
109
110Passkeys are not supported yet; they are next.
111
112## Invites
113
114While g1t is invite-only, every new account needs an invite code, such as
115`g1t-k7m2-q9xd-…`. People already on g1t make them, and g1t sends them to
116people who [asked for access](#asking-for-access). An invite:
117
118- works once, for one new account;
119- works for 30 days;
120- when it was made for an email address, works only with that address;
121- can be revoked by whoever made it until it is used, and after that until
122 the new account [confirms its email address](#confirming-your-email-address).
123
124### Using an invite
125
126Every invite email links to `g1t.sh/invite/<code>`. That one page shows
127who sent it and what it is for (joining a workspace, collaborating on a
128repository, or just making an account), and finishes the job there:
129
1301. **No account yet**: sign up on the page. When the invite was sent to
131 your address, the email field is filled in and locked. Choose a
132 username (one is suggested from your address) and a password, then
133 [confirm the address](#confirming-your-email-address) with the code g1t
134 emails it, even though the invite came there: an invite link can be
135 forwarded, so it does not prove the inbox is yours. Or select
136 **Continue with GitHub**: the invite rides along, and the account uses
137 the invited address when GitHub has verified it too, in which case no
138 confirmation is needed.
1392. **The address already has an account**: select **Sign in to accept**.
140 After you sign in, the invite is accepted for you.
1413. **Signed in as someone else**: an invite sent to one address works only
142 for an account that has confirmed that address. The page says so and
143 offers **Sign out and continue**.
144
145Once you have signed in, or your new account has confirmed its address,
146you land in the workspace (or the repository) the invite was for, already
147a member, with a one-time "You're in" banner, and it becomes the workspace
148your sidebar shows.
149
150Signing up spends the invite at once, so nobody else can use it while you
151confirm your address, but you join its workspace only when you confirm, in
152the same step. Until then the invite shows as **confirming their email** to
153whoever made it, and they can still revoke it. If the invite is revoked or
154expires, or its workspace is deleted, before you confirm, your address is
155confirmed all the same and g1t tells you the invite no longer applies: ask
156whoever invited you to add you again. A
157code typed at [g1t.sh/register](https://g1t.sh/register) goes to the
158same page.
159
160An expired, revoked or used invite says which, and who sent it, so you
161can ask them for a new one; or ask for access from the same page.
162
163### Making invites
164
1651. Open [Settings → Invites](https://g1t.sh/settings/invites).
1662. Optionally enter the email address of the person you are inviting.
167 With one, g1t emails them the invite, and only that address can use it.
168 Without one, anyone with the link can, once.
1693. Select **Create invite**, then copy the link.
170
171Each person can have **5** invites out at a time. Pending and used invites
172count; an invite you revoke, or one that expires before anyone uses it,
173comes back to you. The list under the form shows each invite's state:
174pending, confirming their email (used to sign up by someone who has not
175confirmed their address yet), joined (with the username of who joined),
176expired or revoked. You
177must confirm your email before you can make invites. An agent's token and
178a workspace's token cannot make them.
179
180### Inviting someone into a workspace
181
182An owner can invite an email address straight into a workspace from its
183People page; see [members and roles](/guides/workspaces/#members-and-roles).
184When the address has no g1t account, the invite makes the account, which
185joins the workspace once it confirms its email address, and it uses one
186invite. Inviting someone who is
187already on g1t costs nothing.
188
189### Need more invites?
190
191Write to [hey@flagon.io](mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20)
192with the subject `[g1t Invites]` and say who you would like to bring. g1t
193can give more invites to you, or to a workspace, whose owners then share
194them. Invites given to a workspace appear under
195[Settings → Invites](https://g1t.sh/settings/invites) for
196each of its owners, as a choice of whose invites to use.
197
198### Asking for access
199
200Without an invite, [g1t.sh/register](https://g1t.sh/register) asks for your
201email address and, if you like, what you will build. g1t emails that
202address once to confirm you are on the list, and staff see the request
203straight away. When they approve it, the invite comes to the same address,
204sometimes with a note, and its link opens sign-up with the address filled
205in. There is no fixed date: g1t opens up a few people at a time. Asking
206again with the same address updates your request without another email; it
207does not move you down the list.
208
209### Invites through the API
210
211| Route | MCP tool and action | What it does |
212| --- | --- | --- |
213| [`GET /user/invites`](/reference/api/invites/list-invites/) | `account` `list_invites` | Your invites and how many you have left |
214| [`POST /user/invites`](/reference/api/invites/create-invite/) | `account` `create_invite` | Make an invite, optionally for one `email` |
215| [`DELETE /user/invites/{id}`](/reference/api/invites/revoke-invite/) | `account` `revoke_invite` | Revoke a pending invite, or one whose new account has not confirmed its address |
216| [`POST /workspaces/{workspace}/invitations`](/reference/api/invites/invite-member/) | `workspace` `invite_member` | Invite an address into a workspace. Owners only. |
217
218## Confirming your email address
219
220A new account confirms its email address before it can do anything else on
221g1t. Right after you sign up, g1t emails the address from `noreply@g1t.sh`
222with two ways to confirm it, either one enough:
223
224- a **six-digit code**, shown large in the email (and in its subject, so a
225 phone's notification shows it). Type it on the **Confirm your email**
226 page g1t takes you to. On a phone, the keyboard offers it from the
227 message.
228- a **link**, for when you would rather click than type. It works whether
229 or not you are signed in, in any browser.
230
231The code and the link work for **60 minutes**, once. Using either ends the
232other. **Send a new code** on the confirmation page sends a fresh code and
233link, at most once a minute and 10 times an hour, and the ones before stop
234working.
235
236| On the confirmation page | What it does |
237| --- | --- |
238| **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. |
239| **Send a new code** | A new code and link; the ones before stop working. |
240| **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. |
241| **Sign out** | Signs out. Sign in again to come back to the page. |
242
243### Until you confirm
244
245An account that has not confirmed its address can only confirm it:
246
247- **The site** sends every page to the confirmation page, and back to where
248 you were going once you confirm. Signing in and out, password resets,
249 the confirmation link, and g1t's [policies](https://g1t.sh/policies),
250 security, support, status and pricing pages stay open.
251- **The API** answers `403` with a message saying to confirm your address,
252 except for [`GET /user`](/reference/api/accounts/whoami/),
253 [`GET /user/emails`](/reference/api/accounts/list-emails/) and
254 [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/).
255- **The MCP server** answers `403` with the same message.
256- **Git** over HTTPS refuses pushes and fetches with your credentials, with
257 the same message. Package registries treat them as wrong credentials.
258- You cannot create a workspace, join the one your invite named, make
259 invites or tokens, or approve a tool's sign-in.
260
261You cannot make a token before you confirm, so the API and MCP refusals
262matter only for an account that made one before this rule existed.
263
264### Addresses GitHub has confirmed
265
266An account made with **Continue with GitHub** starts confirmed: its address
267is one GitHub has verified, so GitHub has already proved the inbox is
268yours, and no code is sent.
269
270### Accounts that never confirmed
271
272Accounts are confirmed once and stay confirmed. An account made before this
273rule that never confirmed its address, or whose address another account
274confirmed first, is held at the confirmation page the same way the next
275time it signs in; **Send a new code** gets it a code, and **Change it**
276gives it a new address.
277
278### Confirming through the API
279
280| Route | MCP tool and action | What it does |
281| --- | --- | --- |
282| [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/) | `account` `confirm_email` | Confirm an address with the `code` from its email |
283
284The answer says whether the account is now confirmed (`verified`), the
285workspace confirming joined it to (`joined`), or why its invite no longer
286applies (`invite_lapsed`).
287
288## Email addresses
289
290An account can have up to 10 email addresses. Manage them in
291[Settings → Emails](https://g1t.sh/settings/emails).
292
293| An address that is | Can |
294| --- | --- |
295| Primary | Get account mail and password reset links. Exactly one, always confirmed once any address is. |
296| Confirmed | Sign you in (type it instead of your username), ask for a password reset, and mark commits that carry it as yours. |
297| Backup | Get security notices as well as the primary. Optional, and a confirmed address other than the primary. |
298| Unconfirmed | Nothing yet. It is not yours until you enter the code or follow the link g1t sent it. |
299
300A confirmed address belongs to one account. Anyone can add an address they
301have not confirmed; the first account to confirm it keeps it, and the
302address leaves every other account that added it. An address another
303account has confirmed cannot be added.
304
305### Add an address
306
3071. Open [Settings → Emails](https://g1t.sh/settings/emails).
3082. Enter the address under **Add an email address** and select **Add**.
3093. Enter the code g1t emails it, or follow the link in the same email.
310 Both work for 60 minutes; **Resend link** sends a new code and link, at
311 most once a minute and 10 times an hour, and ends the ones before.
312
313If your account had no confirmed address yet, the first one you confirm
314becomes your primary.
315
316### Choose your primary and backup
317
318Select **Make primary** beside a confirmed address. Under **Backup
319address**, choose a confirmed address to get security notices too, or
320**Primary address only**.
321
322### Remove an address
323
324Select **Remove** beside it. You cannot remove your primary address (make
325another one primary first) or your last confirmed address.
326
327### Confirming it is you
328
329Adding or removing an address, changing your primary or backup, and
330turning two-factor authentication on or off, need proof that it is you: a
331sign-in in the last 10 minutes, or your password,
332which g1t asks for on the page. After you enter it, g1t does not ask again
333for 10 minutes. An account that signs in only with GitHub signs out and in
334with GitHub again, or sets a password with
335[Forgot your password](https://g1t.sh/forgot).
336
337Each of these changes is emailed to every confirmed address on the account,
338including an address that was just removed, and written to your
339[security log](#security-log).
340
341### Keeping your address private
342
343**Keep my email address private** is on for every account unless you turn
344it off. While it is on, commits g1t makes for you (merging a pull request
345on the web, catching a branch up, and commits an agent makes for you) carry
346your noreply address instead of your primary:
347
348```
349<8 characters of your account id>+<username>@users.noreply.g1t.sh
350```
351
352The page shows yours. It never receives mail. Turn the setting off to put
353your primary address on those commits instead.
354
355**Block pushes that expose my email** refuses a push that would publish one
356of your addresses while you keep it private. When both settings are on,
357g1t reads the new commits in each push you make, and declines the push if
358any of them has one of your confirmed addresses as its author or committer
359address. git shows why, with the address masked:
360
361```
362remote: push declined: commit 3f9a1c2 would publish s***@gmail.com while your email is private.
363remote: Commit with 6c1d0efg+sam@users.noreply.g1t.sh (git config user.email 6c1d0efg+sam@users.noreply.g1t.sh) and amend,
364remote: or change this in g1t.sh/settings/emails.
365```
366
367To push those commits:
368
3691. Set your noreply address for the repository:
370 `git config user.email <your noreply address>`.
3712. Rewrite the commits with it. For the last commit,
372 `git commit --amend --reset-author --no-edit`; for several,
373 `git rebase <base> --exec "git commit --amend --reset-author --no-edit"`.
3743. Push again.
375
376Only your own addresses are checked: commits by other people in the same
377push go through, and so does your noreply address. A push an agent makes
378for you follows your settings.
379
380### How commits are attributed
381
382g1t shows a commit as yours, with your picture and a link to your profile,
383when its author address is one of your confirmed addresses or your noreply
384address. Commits that g1t made for you before noreply addresses existed
385(`<username>@users.g1t.sh`) count as yours too. An unconfirmed address
386never attributes a commit, so nobody can claim your commits by adding your
387address. Commits whose address matches no account show the name in the
388commit.
389
390### Email addresses through the API
391
392| Route | MCP tool and action | What it does |
393| --- | --- | --- |
394| [`GET /user/emails`](/reference/api/accounts/list-emails/) | `account` `list_emails` | Your addresses and email settings |
395| [`POST /user/emails`](/reference/api/accounts/add-email/) | `account` `add_email` | Add an address; takes `email` and `password` |
396| [`POST /user/emails/confirm`](/reference/api/accounts/confirm-email/) | `account` `confirm_email` | Confirm an address with the `code` from its email |
397| [`DELETE /user/emails/{email}`](/reference/api/accounts/remove-email/) | `account` `remove_email` | Remove an address; takes `password` |
398| [`PATCH /user/email-settings`](/reference/api/accounts/update-email-settings/) | `account` `update_email_settings` | Change `primary`, `backup`, `private_email` or `block_private_pushes` |
399
400Through the API, `password` is the proof a sensitive change needs. Without
401it, or with the wrong one, the answer is `403` with the code
402`reauth_required`. Only a person's own token can use these: an agent's
403token and a workspace's token are refused.
404
405## Workspaces
406
407Your account does not own repositories itself: a workspace does. After
408confirming your email, the first thing you do is create one. Workspaces,
409their members and roles, and the access tokens that belong to a workspace
410are covered in [workspaces](/guides/workspaces/).
411
412## Access tokens
413
414A token stands in for your password everywhere outside the website:
415
416| Where | How to send it |
417| --- | --- |
418| git | As the password, with your username. |
419| API | `Authorization: Bearer g1t_…` |
420| MCP | The same header, set when you add the server. |
421
422A token is shown once, when it is created; g1t stores only a hash of it.
423If you lose one, delete it and create another. Delete a token the moment
424you think someone else has seen it.
425
426There are two kinds of personal access token, on two tabs of
427[Settings → Access tokens](https://g1t.sh/settings/tokens):
428
429| | Fine-grained token | Classic token |
430| --- | --- | --- |
431| Reaches | One resource owner: one workspace you belong to, or your own account | Every workspace and repository you can reach, including ones you join later |
432| Repositories | All of the workspace's, the ones you choose (up to 50), or public ones only | All you can reach |
433| What it may do | A level for each [permission](#permissions) | Its [scopes](#scopes) |
434| Expires | Always, within 366 days | 7 days to 1 year, or never |
435| A workspace can | Require an owner's approval first, or keep them out | Keep them out |
436
437Both never do more than you could on the website, and both are sent the
438same way. Prefer a fine-grained token: it reaches only what it needs.
439
440For CI and integrations that work for a team, a workspace can have tokens
441of its own that act as the workspace and keep working when their creator
442leaves. See [workspace tokens](#workspace-tokens).
443
444### Create a fine-grained token
445
4461. Open [Settings → Access tokens](https://g1t.sh/settings/tokens). The
447 **Fine-grained tokens** tab is first.
4482. Under **New fine-grained token**, give it a **Token name** after what
449 will use it, and optionally a **Description**, which a workspace's
450 owners see if they review it.
4513. Choose the **Resource owner**: a workspace you belong to, or **Your
452 account**. A workspace that does not allow fine-grained tokens cannot be
453 chosen.
4544. Choose its **Expiration**: 7, 30, 60, 90 or 180 days, or 1 year, or
455 less when the workspace sets a shorter limit.
4565. Under **Repository access**, choose **Public repositories** (read-only),
457 **All repositories** of the workspace (including ones made later), or
458 **Only select repositories**, and tick up to 50.
4596. Under **Permissions**, set each one the token needs to **Read-only** or
460 **Read and write** (and **Admin** for packages). **Metadata** is always
461 read-only. Each row shows the g1t scopes its level gives.
4627. Select **Generate token**, and copy it. It is not shown again.
463
464When the workspace [requires approval](#a-workspaces-rules-for-tokens) and
465you are not one of its owners, the token is made **Pending approval**: it
466works at once, but reads public repositories only until an owner approves
467it. The owners hear of it in their [inbox](/guides/inbox/), and you hear of
468their answer in yours. An owner's own token never waits.
469
470Select **Edit** on a token to change its name, description, repositories
471or permissions. The token stays the same. Widening it in a workspace that
472requires approval asks again. Its resource owner and expiry cannot change;
473make a new token instead.
474
475The list shows each token's status (pending, denied or revoked, with the
476owner's note), what it reaches, its permissions, and when it was made, last
477used and expires.
478
479### Permissions
480
481Each level of a fine-grained token's permissions gives g1t
482[scopes](#scopes), and the token is checked by those scopes
483exactly as a classic token is. Where two permissions give the same scopes
484(Checks and Commit statuses; Secrets and Variables; Deployments and Pages),
485giving either gives both.
486
487Repository permissions, for a workspace as the resource owner:
488
489| Permission | Levels | What it covers | g1t scopes it gives |
490| --- | --- | --- | --- |
491| `actions` (Actions) | read, write | Workflow runs, jobs, logs and artifacts: reading them, and running, cancelling and rerunning workflows | read: `workflows:read`; write: `workflows:write` |
492| `administration` (Administration) | read, write | Repository settings, rulesets, who has access and deploy keys; renaming, archiving, transferring and deleting | read: `repo:read`, `access:read`; write: `repo:admin`, `access:admin` |
493| `agents` (g1t agents) | write | Putting g1t's agents to work and messaging them, which uses the workspace's money | write: `agents:run` |
494| `checks` (Checks) | read, write | Check runs and check suites on commits. Shares its scopes with Commit statuses | read: `checks:read`; write: `checks:write` |
495| `contents` (Contents) | read, write | Code, branches, commits and releases: cloning and fetching, pushing, and publishing releases | read: `code:read`; write: `code:write`, `repo:write` |
496| `deployments` (Deployments) | read, write | Deployments and their statuses | read: `deployments:read`; write: `deployments:write` |
497| `environments` (Environments) | read, write | Environments, and their secrets and variables | read: `deployments:read`, `secrets:read`; write: `secrets:admin` |
498| `issues` (Issues) | read, write | Issues, their comments, labels and milestones, and plans | read: `issues:read`; write: `issues:write` |
499| `memory` (Memory and context) | read, write | Recalling memory and searching the workspace's context, and saving memory for the next agent | read: `memory:read`; write: `memory:write` |
500| `metadata` (Metadata) | read | Seeing repositories and searching them. Always read | read: `repo:read` |
501| `packages` (Packages) | read, write, admin | Pulling private packages, publishing them, and (admin) deleting packages and versions | read: `packages:read`; write: `packages:write`; admin: `packages:delete` |
502| `pages` (Pages) | read, write | Deployments on g1t.page. Shares its scopes with Deployments | read: `deployments:read`; write: `deployments:write` |
503| `pull_requests` (Pull requests) | read, write | Pull requests, their reviews, changes, sessions and merge queues | read: `pull_requests:read`; write: `pull_requests:write` |
504| `secrets` (Secrets) | read, write | Actions secrets: listing them (never their values), setting and deleting them. Shares its scopes with Variables | read: `secrets:read`; write: `secrets:admin` |
505| `security_events` (Security events and alerts) | read, write | Code scanning, secret scanning and vulnerability alerts, SARIF uploads and security settings | read: `security:read`; write: `security:write` |
506| `statuses` (Commit statuses) | read, write | Statuses on commits. Shares its scopes with Checks | read: `checks:read`; write: `checks:write` |
507| `variables` (Variables) | read, write | Actions variables: reading, setting and deleting them. Shares its scopes with Secrets | read: `secrets:read`; write: `secrets:admin` |
508| `webhooks` (Webhooks) | read, write | Webhooks and their deliveries | read: `webhooks:read`; write: `webhooks:admin` |
509| `workflows` (Workflows) | write | Adding, changing and deleting workflow files under .g1t/workflows and .github/workflows. Write only | write: `workflow_files:write` |
510
511Workspace permissions, for a workspace as the resource owner:
512
513| Permission | Levels | What it covers | g1t scopes it gives |
514| --- | --- | --- | --- |
515| `members` (Members) | read, write | The workspace's people, invitations and teams | read: `workspace:read`; write: `workspace:admin` |
516| `workspace_administration` (Administration) | read, write | The workspace's settings, integrations, rulesets and base permission | read: `workspace:read`, `access:read`; write: `workspace:admin`, `access:admin` |
517| `workspace_billing` (Billing) | read, write | Usage, budget, AI credit and invoices, and (write) changing the budget and buying credit | read: `billing:read`; write: `billing:write` |
518| `models` (AI Gateway) | read, write | AI Gateway requests: seeing them, and sending requests, which uses the workspace's AI credit | read: `models:read`; write: `models:write` |
519| `self_hosted_runners` (Self-hosted runners) | read, write | Runners, their groups and settings | read: `runners:read`; write: `runners:admin` |
520| `workspace_secrets` (Secrets) | read, write | The workspace's Actions secrets. Shares its scopes with the repository Secrets permission | read: `secrets:read`; write: `secrets:admin` |
521| `workspace_webhooks` (Webhooks) | read, write | The workspace's webhooks. Shares its scopes with the repository Webhooks permission | read: `webhooks:read`; write: `webhooks:admin` |
522
523Account permissions, for your own account as the resource owner:
524
525| Permission | Levels | What it covers | g1t scopes it gives |
526| --- | --- | --- | --- |
527| `email_addresses` (Email addresses) | read, write | Your email addresses and email settings, invites and invitations | read: `account:read`; write: `account:write` |
528| `starring` (Starring) | read, write | Stars and pinned projects. Shares its scopes with Email addresses | read: `account:read`; write: `account:write` |
529| `notifications` (Notifications) | read, write | Your inbox, subscriptions and watched repositories | read: `notifications:read`; write: `notifications:write` |
530
531### What a fine-grained token reaches
532
533- **In its workspace**, what your role allows, in the repositories it
534 reaches, and only what its permissions give.
535- **Elsewhere**, public repositories, read-only, as anyone can. It cannot
536 comment, open issues or push there.
537- **With your account as its resource owner**, public repositories,
538 read-only, and what its account permissions give.
539- **While pending, denied or revoked**, public repositories, read-only.
540
541A request it cannot make answers `403` naming why: the scope it lacks, or
542`This fine-grained token's resource owner is the workspace acme: it can only
543read public repositories elsewhere, …`. A repository outside its selection
544answers as if it did not exist.
545
546### Create a classic token
547
5481. Open [Settings → Access tokens](https://g1t.sh/settings/tokens), and
549 select the **Tokens (classic)** tab.
5502. Under **New classic token**, give it a **Name** after what will use it.
5513. Choose when it **Expires**: 7 days, 30 days, 90 days (the default),
552 1 year, or No expiry. An expired token stops working; make a new one.
553 No expiry shows a warning: the token works until someone deletes it.
5544. Under **Scopes**, tick the boxes for what it may do. They are grouped
555 by area. The form starts on the **Agent** [preset](#presets); select
556 another preset to tick its boxes instead.
5575. Select **Create token**, and copy the token. It is not shown again.
558
559The list shows each token's name, when it was made and last used, when it
560expires, and its access: a preset's name, its scopes, or Full access. To
561change what a token may do, select **Edit access**, tick or untick boxes,
562and select **Save access**. The token stays the same; the change applies
563from its next request.
564
565A classic token reaches every workspace you belong to unless the
566workspace's [rules](#a-workspaces-rules-for-tokens) keep it out: one that
567does not allow classic tokens, one whose longest lifetime this token
568exceeds, or one whose owner revoked it there. It keeps working everywhere
569else.
570
571## Scopes
572
573A scope is a resource and a level, written `resource:level`, such as
574`issues:write`. A higher level includes the lower ones of the same
575resource: `repo:admin` includes `repo:write`, which includes `repo:read`.
576It never includes another resource: `repo:admin` does not let a token push,
577which is `code:write`.
578
579On the form, scopes are a checklist grouped by area:
580
581| Group | Scopes |
582| --- | --- |
583| Repositories & code | `repo:read`, `repo:write`, `code:read`, `code:write` |
584| Packages | `packages:read`, `packages:write` |
585| Issues & pull requests | `issues:read`, `issues:write`, `pull_requests:read`, `pull_requests:write` |
586| Agents | `agents:run` |
587| Workflows | `workflows:read`, `workflows:write`, `workflow_files:write` |
588| Checks | `checks:read`, `checks:write` |
589| Deployments | `deployments:read`, `deployments:write` |
590| Memory & search | `memory:read`, `memory:write` |
591| Account | `account:read`, `account:write` |
592| Notifications | `notifications:read`, `notifications:write` |
593| Security | `security:read`, `security:write` |
594| Workspace | `workspace:read`, `access:read`, `webhooks:read`, `secrets:read` |
595| Billing | `billing:read`, `billing:write` |
596| Runners | `runners:read` |
597| AI Gateway | `models:read`, `models:write` |
598| Dangerous | `repo:admin`, `packages:delete`, `workspace:admin`, `access:admin`, `webhooks:admin`, `secrets:admin`, `runners:admin` |
599
600Ticking a higher level ticks the lower ones of its resource and greys
601them out: tick `issues:write` and `issues:read` is ticked too. Untick
602`issues:write` and `issues:read` stays ticked.
603
604| Scope | What it lets a token do |
605| --- | --- |
606| `repo:read` | See repositories, their settings, labels, timelines, releases, languages, contributors and security alerts, and search |
607| `repo:write` | Create repositories, rename branches, change how pull requests merge and publish releases |
608| `repo:admin` | Rename, archive, transfer, delete or change who can see a repository, and dismiss security alerts |
609| `code:read` | Clone and fetch private repositories with git |
610| `code:write` | Push commits with git |
611| `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 |
612| `security:write` | Dismiss and reopen alerts, bypass push protection, review bypass requests, manage custom patterns, upload SARIF and change security settings |
613| `packages:read` | Pull container images and install private [packages](/guides/packages/). Public ones need no scope. |
614| `packages:write` | Push container images and publish packages; with the Admin role on a package, change its settings |
615| `packages:delete` | Delete and restore packages and their versions |
616| `issues:read` | Read issues, comments and plans |
617| `issues:write` | Open, edit, close and comment on issues |
618| `pull_requests:read` | Read pull requests, their changes, sessions and merge queues |
619| `pull_requests:write` | Open, review, close and merge pull requests |
620| `agents:run` | Put g1t to work and message it, which uses the workspace's money |
621| `workflows:read` | Read workflows, runs and logs |
622| `workflows:write` | Run, cancel, rerun and turn workflows on or off |
623| `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 but full access. |
624| `checks:read` | Read commits' statuses, check runs, check suites and annotations |
625| `checks:write` | Report [statuses and check runs](/guides/checks/) on commits, and ask for checks to run again |
626| `deployments:read` | See [deployments](/guides/deployments-api/), their statuses and environments |
627| `deployments:write` | Report deployments and their statuses, from any CI |
628| `memory:read` | Recall memory and search the workspace's context |
629| `memory:write` | Save memory for the next agent |
630| `account:read` | Read your email addresses, invites, invitations, pinned projects and stars |
631| `account:write` | Change your email addresses, make invites, answer invitations, pin projects and star repositories |
632| `notifications:read` | See your [inbox](/guides/inbox/), its threads, and what you subscribe to and watch |
633| `notifications:write` | Mark notifications read, done, saved or snoozed, subscribe to threads and watch repositories |
634| `workspace:read` | Read workspace settings, invites, integrations, model routes and [teams](/guides/teams/) |
635| `workspace:admin` | Create and delete workspaces, invite members, manage teams, connect integrations |
636| `billing:read` | See a workspace's [usage, budget, AI credit and invoices](/guides/usage-and-billing/) |
637| `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. |
638| `access:read` | See who has access to repositories |
639| `access:admin` | Give people and teams access to repositories, and take it away |
640| `webhooks:read` | See webhooks and their deliveries |
641| `webhooks:admin` | Create, change and delete webhooks |
642| `secrets:read` | List secrets (never their values) and read variables |
643| `secrets:admin` | Set and delete secrets and variables |
644| `runners:read` | See [self-hosted runners](/guides/self-hosted-runners/), their groups and where agents run. Not in the Agent preset. |
645| `runners:admin` | Register and remove self-hosted runners, change their groups and settings |
646| `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status |
647| `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. |
648
649Every operation of the API and the MCP server needs exactly one of these,
650except `whoami` (`GET /user`), which any token may use. Each endpoint's page
651in the [API reference](/reference/api/) names its scope, and so does each
652action in [MCP tools](/reference/mcp/). A few calls need a second scope for
653what they ask:
654
655| Call | Also needs |
656| --- | --- |
657| `delegate` (`POST /repos/{owner}/{name}/issues/delegate`, the `agent` tool's `delegate`), which opens an issue | `issues:write`, beside `agents:run` |
658| `apply_plan` or `import_issue` (the `plan` tool's `apply`, the `issue` tool's `import`) with `assign: true` | `agents:run` |
659| `update_repo` with `private` or `default_branch` | `repo:admin` |
660
661### What a token can do
662
663What a request may do is where these overlap:
664
6651. **Your role.** A token never does more than you could on the website. A
666 token with `repo:admin` still cannot delete a repository unless you are
667 an owner of its workspace. See [access and roles](/guides/access-and-roles/).
6682. **What it reaches.** A classic token, every workspace and repository you
669 can reach, including ones you join later, unless a workspace's
670 [rules](#a-workspaces-rules-for-tokens) keep it out. A fine-grained
671 token, its [resource owner](#what-a-fine-grained-token-reaches) only.
6723. **Its scopes.** What kinds of thing it may do: chosen directly on a
673 classic token, given by its permissions on a fine-grained one.
674
675To keep a token away from other workspaces, make a fine-grained one, or use
676a [workspace token](#workspace-tokens): it reaches only its own workspace.
677
678### Presets
679
680A preset ticks a starting set of boxes. Select one, then tick or untick
681any box.
682
683| Preset | Scopes |
684| --- | --- |
685| Read only | Every `read` scope. Changes nothing. |
686| 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. |
687| CI | `repo:read`, `code:read`, `code:write`, `packages:read`, `packages:write`, `workflows:read`, `workflows:write`, `checks:read`, `checks:write`, `deployments:read` and `deployments:write`. Clones and pushes code, pushes and pulls packages, runs workflows, and reports [checks](/guides/checks/) and deployments. |
688| Full access | Everything you can do, including deleting repositories and changing who has access. Marked **Dangerous**. |
689
690Admin scopes change things that are hard to undo, or decide who can reach
691what. They are under **Dangerous**, with a warning. Give them only to
692something you trust as much as yourself.
693
694### Git and scopes
695
696Over HTTPS, git checks the same token:
697
698| To | Needs |
699| --- | --- |
700| Clone or fetch a public repository | No scope |
701| Clone or fetch a private repository | `code:read` |
702| Push | `code:write` |
703| Push commits that add, change or delete [workflow files](#workflow-files) | `code:write` and `workflow_files:write` |
704
705Your role on the repository applies too, as on the website. A refused push
706or clone says which scope is missing.
707
708### Workflow files
709
710A workflow runs with its repository's secrets and a token of its own, so
711changing one is as powerful as holding those. A token therefore needs
712`workflow_files:write` (a fine-grained token's **Workflows** permission) to
713add, change or delete any file under `.g1t/workflows/` or
714`.github/workflows/`, besides `code:write`:
715
716- **With git**, every commit a push adds is compared with its parent, and a
717 push that changes a workflow file is declined, naming it:
718
719 ```text
720 remote: This access token cannot change the workflow file .github/workflows/ci.yml: it needs the workflow_files:write scope.
721 remote: Push with a token that has the workflow_files:write scope, or make the change signed in on g1t.sh.
722 ```
723
724 A push too large for g1t to read whole is declined for such a token too,
725 since it cannot be checked; push it in smaller parts.
726- **Through g1t**, a file written for a token (such as a starter workflow)
727 is refused the same way.
728- **A workflow job's token** never may, whatever its `permissions:` say.
729 See [the job's token](/guides/actions/#the-jobs-token).
730- **Signed in on g1t.sh**, your role decides, as for any file.
731
732Full-access tokens, and tokens made before scopes, include it. A
733[deploy key](/guides/git/#deploy-keys) with write access may change
734workflow files.
735
736### When a token lacks a scope
737
738The API answers `403` with the scope that was missing in `needed_scope`:
739
740```json
741{
742 "error": {
743 "code": "forbidden",
744 "message": "This access token needs the issues:write scope to use create_issue.",
745 "needed_scope": "issues:write"
746 }
747}
748```
749
750Through MCP the same message comes back as a tool result with `isError`
751set. Give the token that scope with **Edit access**, or make a new token.
752
753### Tokens made before scopes
754
755Tokens and OAuth sign-ins made before tokens had scopes keep full access,
756so nothing that uses them stops working. Settings marks each one
757**Legacy · full access**, and says to narrow it to what it needs. For a
758token, select **Narrow this token**; for an application, **Change access**
759in [Connected applications](https://g1t.sh/settings/applications). Then
760tick its scopes. A token you make with Full access on purpose is not marked
761legacy.
762
763A token from [signing in from a tool](#signing-in-from-a-tool), such as the
764g1t CLI, has full access.
765
766### Workspace tokens
767
768A workspace's own tokens act as the workspace rather than a person. An
769owner makes them in the workspace's **Settings → Access tokens**, with the
770same checklist and expiry choices; the form starts on the CI preset. A
771workspace token reaches all of that workspace's repositories, never
772another workspace, and cannot manage people, tokens or workspaces.
773
774It has the Write role on the workspace's repositories, as a member does:
775it pushes, merges and works on issues and pull requests, within its scopes.
776Tick **Admin on the workspace's repositories** when making it to give it
777Admin instead, so it can also manage webhooks, secrets, deploy keys and who
778has access, and manage teams as an owner would. Only an owner can, and only
779when making it. See
780[workspace access tokens](/guides/workspaces/#workspace-access-tokens).
781
782## A workspace's rules for tokens
783
784An owner decides which of the members' own personal tokens reach the
785workspace, under its **Settings → Personal access tokens**
786(`g1t.sh/<workspace>/-/personal-access-tokens`). The rules apply from each
787token's next request, to tokens made before them too. A token they keep out
788keeps working everywhere else, and reads the workspace's public
789repositories as anyone can.
790
791| Rule | Default | What it does |
792| --- | --- | --- |
793| Allow fine-grained personal access tokens | On | Off: no fine-grained token can name the workspace as its resource owner, and existing ones stop reaching it. |
794| Require approval of fine-grained tokens | On | A member's fine-grained token naming the workspace waits for an owner's approval, and again when it is widened. Owners' own tokens never wait. |
795| Allow classic personal access tokens | On | Off: classic tokens no longer reach the workspace. |
796| Tokens must expire | Off | On: a token that never expires does not reach the workspace. |
797| 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. Fine-grained tokens for it cannot be made longer. |
798
799The same page lists:
800
801- **Waiting for approval.** Each pending fine-grained token with its owner,
802 permissions, repositories and expiry. Add an optional note, then select
803 **Approve** or **Deny**. Its owner hears of it in their inbox, with the
804 note.
805- **Tokens that can reach the workspace.** Every fine-grained token naming
806 it, and every classic token of its members and outside collaborators that
807 has not expired, with its owner, permissions or scopes, last use and
808 expiry, and whether it reaches the workspace now (and if not, why). Never
809 the token itself. Select **Revoke** to take one out: a fine-grained token
810 stops reaching the workspace for good; a classic token keeps working
811 everywhere else, but never reaches this workspace again.
812
813Approvals, denials, revocations and rule changes are
814[audit log](/guides/audit-log/) entries: `token.approval_requested`,
815`token.approved`, `token.denied`, `token.revoked` and
816`token.policy_changed`.
817
818### A workspace's rules through the API
819
820Owners, as people (a personal token with the scope works; a workspace's own
821token does not):
822
823| Route | MCP tool and action | What it does | Scope |
824| --- | --- | --- | --- |
825| [`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` |
826| [`PATCH /workspaces/{workspace}/personal-access-token-policy`](/reference/api/personal-access-tokens/set-token-policy/) | `workspace` `set_token_policy` | Change `allow_classic`, `allow_fine_grained`, `require_approval`, `max_lifetime_days` (0 for no limit) or `forbid_no_expiry` | `workspace:admin` |
827| [`GET /workspaces/{workspace}/personal-access-tokens`](/reference/api/personal-access-tokens/list-member-tokens/) | `workspace` `list_member_tokens` | The tokens that can reach it; `kind` is `classic` or `fine_grained` | `access:read` |
828| [`GET /workspaces/{workspace}/personal-access-token-requests`](/reference/api/personal-access-tokens/list-token-requests/) | `workspace` `list_token_requests` | The fine-grained tokens waiting for approval | `access:read` |
829| [`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` |
830| [`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` |
831
832## Signing in with OAuth
833
834Applications that can open your browser, such as an agent connecting to the
835[MCP server](/guides/bring-your-own-agent/), sign you in with OAuth 2.1.
836You see a page on g1t naming the application and where it will send you
837back, and you approve or deny. The application never sees your password and
838there is no token to copy.
839
840The page lists what the application will be able to do, as the same
841checklist a token has, with only the scopes it asked for, all ticked.
842Untick anything you would rather it could not do, leaving at least one;
843you cannot give it more than it asked for. Like a token, it reaches
844everything you can.
845
846An application that asks for no scopes in particular gets the
847[Agent preset](#presets): every `read` scope except `runners:read`, and `code:write`,
848`issues:write`, `pull_requests:write`, `agents:run`, `memory:write` and
849`notifications:write`.
850It never gets an admin scope unless it asks for one and you leave it
851ticked.
852
853Applications you have approved are listed in
854[Settings → Connected applications](https://g1t.sh/settings/applications),
855each with its access. Select **Change access** to tick or untick its
856scopes, then **Save access**: it stays signed in, the change applies at
857once, and its next refresh keeps it. Select **Sign out** to end its access
858at once.
859
860For people building a client:
861
862| | |
863| --- | --- |
864| Metadata | `https://api.g1t.sh/.well-known/oauth-authorization-server` |
865| Authorization | `https://g1t.sh/oauth/authorize` |
866| Token | `https://api.g1t.sh/oauth/token` |
867| Registration | `https://api.g1t.sh/oauth/register` |
868
869- The flow is authorization code with PKCE. `S256` is required.
870- Clients are public: there are no client secrets.
871- Register with `client_name` and `redirect_uris`. A redirect address is an
872 `https` URL, `http` on `localhost`, or the application's own scheme. A
873 client on `localhost` may use any port.
874- Registration stores nothing. The client id it returns encodes what was
875 registered, so it cannot be used to fill g1t with junk.
876- Ask for scopes with `scope` on the authorization request, separated by
877 spaces, such as `scope=repo:read issues:write pull_requests:write`.
878 Names g1t does not know are left out. Leave `scope` out for the Agent
879 preset. The authorization server's metadata and
880 `https://mcp.g1t.sh/.well-known/oauth-protected-resource` list every
881 scope in `scopes_supported`.
882- The token response's `scope` holds the scopes the person granted,
883 separated by spaces, or `*` for a sign-in with full access. Refreshing
884 keeps them.
885- An access token lasts 30 days. The refresh token returned with it works
886 once and returns the next pair; the previous access token stops working.
887- An authorization code lasts five minutes and works once.
888
889## Signing in from a tool
890
891A tool that cannot receive a redirect, such as a script on a remote machine,
892gets a token without ever handling your password:
893
8941. The tool asks g1t for a code and shows you a link and a short code such
895 as `WDJB-MJHT`.
8962. You open the link, sign in (or create an account), check that the code
897 matches, and approve.
8983. The tool collects its token.
899
900```sh
901# 1. The tool starts a sign-in.
902curl -X POST https://api.g1t.sh/device/code -H "Content-Type: application/json" -d '{"client_name": "my-tool"}'
903
904# 2. You open verification_uri_complete from the response and approve.
905
906# 3. The tool polls, no faster than "interval" seconds, until it is approved.
907curl -X POST https://api.g1t.sh/device/token -H "Content-Type: application/json" -d '{"device_code": "…"}'
908```
909
910The poll answers with a `status` of `pending`, `approved`, `denied` or
911`expired`. An approved answer carries the token, once. Codes expire after 15
912minutes. The token appears in
913[Settings → Access tokens](https://g1t.sh/settings/tokens) under the tool's name, where you
914can delete it.
915
916Only approve a code you asked for. The token has full access: it can do
917everything you can. To give a tool less, make an
918[access token](#create-a-fine-grained-token) with only the scopes it needs instead.
919
920## Resetting your password
921
922Use [g1t.sh/forgot](https://g1t.sh/forgot) and enter any confirmed
923address of your account. The link goes to that address and works for one
924hour; your primary and backup addresses are told a reset was asked for
925when it went elsewhere. A new account that has not confirmed its address
926yet can use that address, and following the link confirms it.
927
928The page answers the same way whether or not the address has an account.
929g1t sends at most 5 reset links an hour to one address. If g1t cannot
930take the request at all, the page says so and keeps what you typed, so you
931can try again.
932
933Setting a new password signs you out everywhere and emails your primary
934and backup addresses.
935
936## Too many attempts
937
938g1t counts wrong passwords, on the sign-in page, for git over HTTPS and
939when confirming it is you, against the account and against where they come
940from. After 10 wrong passwords for one account in an hour, or 30 from one
941place, g1t stops checking passwords for it for a minute, then twice as long
942after each further wrong password, up to an hour. While it waits, every
943attempt gets the same answer: "Too many attempts". The account's primary
944and backup addresses are told the first time. Signing in with the right
945password, or resetting it, clears the count. Access tokens, SSH keys and
946GitHub sign-in are not affected.
947
948## Security log
949
950[Settings → Security log](https://g1t.sh/settings/security-log) lists what
951happened to your account: addresses added, confirmed, removed or made
952primary, your backup and privacy settings, password changes, pauses after
953too many wrong passwords, two-factor authentication turned on or off and
954recovery codes made or used, personal access tokens created, deleted or
955given new scopes, SSH keys added or removed, and applications authorized,
956changed or revoked. Changes g1t staff made, such as removing an address
957someone else needed, say so and why.
958
959Token, SSH key, application and two-factor changes are also recorded in the
960[audit log](/guides/audit-log/) of each workspace you belong to, where its
961owners see them.
962
963## What g1t stores
964
965Passwords are stored as salted PBKDF2-SHA256 hashes. Sessions and tokens are
966stored as SHA-256 hashes. Neither can be read back. A two-factor secret is
967encrypted (AES-256-GCM) and bound to your account, and recovery codes are
968kept as SHA-256 hashes.