Skip to content

Commit

Docs and plan: fine-grained tokens, workspace token rules, workflow files, workspace token Write

syntaqxcommitted Parent75759ecBrowse files
8 files+341−350/8 viewed
+9−0
384384 g1t is invite-only for now. See [Invites](/guides/authentication/#invites).
385385 **Status.** Opening sign-up is planned.
386386
387+### Fine-grained tokens for workspaces you belong to
388+
389+A fine-grained personal access token can name a workspace as its resource
390+owner only when you are a member of it. For a repository where you are an
391+outside collaborator, use a classic token. A workspace's
392+[rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens)
393+cover personal access tokens only, not applications you signed in to with
394+OAuth. **Status.** Planned.
395+
387396 ### No uptime commitment during the beta
388397
389398 g1t does not promise a particular uptime or offer a service level agreement
+13−3
7070 it comes from.
7171
7272 A workspace's own [access token](/guides/workspaces/#workspace-access-tokens)
73−has Admin on its workspace's repositories, and none on any other.
74−What is for people only, such as transferring or deleting a repository,
75−still needs a person.
73+has Write on its workspace's repositories, as a member does, and none on any
74+other. An owner can give one Admin instead, only when making it. A workflow
75+job's token and a [deploy key](/guides/git/#deploy-keys) have Write at most,
76+on their one repository. What is for people only, such as transferring or
77+deleting a repository, still needs a person.
78+
79+A [fine-grained personal access token](/guides/authentication/#create-a-fine-grained-token)
80+has your role only in its resource owner's repositories that it reaches:
81+all of them, the ones chosen, or none. Everywhere else it reads public
82+repositories, as anyone can, and does nothing more. A classic token has
83+your role wherever you have one, unless a workspace's
84+[rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens)
85+keep it out.
7686
7787 ### Private repositories
7888
+12−0
806806 none, so the token cannot even clone a private repository. A reusable
807807 workflow's jobs get no more than the job that calls it.
808808
809+There is no `workflows` permission for a job's token: it can never add,
810+change or delete a file under `.g1t/workflows/` or `.github/workflows/`,
811+even with `contents: write`. A push that does is declined, naming the file,
812+so a workflow cannot rewrite the workflows that run with its repository's
813+secrets. To change workflows from a job, push with a
814+[fine-grained token](/guides/authentication/#workflow-files) that has the
815+Workflows permission, kept as a secret.
816+
817+The job's token is the repository's workspace acting with the Write role
818+at most, never Admin: it cannot manage webhooks, secrets, deploy keys or who
819+has access, whatever it asks for.
820+
809821 **Without `permissions:`** a job gets the repository's default, which
810822 someone with the Admin role sets under **Settings → Actions**:
811823
+3−0
3232 | `repo.invitation_created`, `repo.invitation_revoked` | Someone was invited to it, or an invitation was withdrawn. |
3333 | `repo.deploy_key_added`, `repo.deploy_key_removed` | A [deploy key](/guides/git/#deploy-keys) was added to it, saying whether it may write, or deleted. |
3434 | `workspace.base_permission_changed` | An owner changed what members get on every repository. |
35+| `token.policy_changed` | An owner changed the workspace's [rules for personal access tokens](/guides/authentication/#a-workspaces-rules-for-tokens). |
36+| `token.approval_requested`, `token.approved`, `token.denied` | A member's fine-grained token asked to reach the workspace, and an owner approved or denied it, with their note. |
37+| `token.revoked` | An owner revoked a member's token in the workspace, with their note. |
3538 | `workspace.team_creation_changed` | An owner changed who can create teams. See [who can create teams](/guides/teams/#who-can-create-teams). |
3639 | `team.created`, `team.edited`, `team.deleted` | A [team](/guides/teams/) was created, changed or deleted. |
3740 | `team.member_added`, `team.member_role_changed`, `team.member_removed` | Someone was added to a team, made its maintainer or a member, or taken out of it. |
+229−21
11 ---
22 title: Accounts and authentication
3−description: Accounts, invites, email addresses, confirming them, personal access tokens and their scopes, OAuth, signing in from a tool, password reset and your security log.
3+description: Accounts, invites, email addresses, confirming them, 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.
44 ---
55
66 ## Creating an account
2727 | 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). |
2828 | Invites | [`/settings/invites`](https://g1t.sh/settings/invites) | [Making, copying and revoking invites](#invites). |
2929 | 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. |
30−| Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens). |
30+| Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens): fine-grained and classic. |
3131 | GitHub | [`/settings/github`](https://g1t.sh/settings/github) | [Linking and unlinking GitHub](/guides/github/#link-and-unlink-github). |
3232 | 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. |
3333 | Security log | [`/settings/security-log`](https://g1t.sh/settings/security-log) | [What happened to your account](#security-log). |
278278 If you lose one, delete it and create another. Delete a token the moment
279279 you think someone else has seen it.
280280
281−A token reaches everything you can reach, and its [scopes](#scopes) say
282−what it may do there. Give each token only the scopes the thing using it
283−needs.
281+There are two kinds of personal access token, on two tabs of
282+[Settings → Access tokens](https://g1t.sh/settings/tokens):
283+
284+| | Fine-grained token | Classic token |
285+| --- | --- | --- |
286+| 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 |
287+| Repositories | All of the workspace's, the ones you choose (up to 50), or public ones only | All you can reach |
288+| What it may do | A level for each [permission](#permissions) | Its [scopes](#scopes) |
289+| Expires | Always, within 366 days | 7 days to 1 year, or never |
290+| A workspace can | Require an owner's approval first, or keep them out | Keep them out |
291+
292+Both never do more than you could on the website, and both are sent the
293+same way. Prefer a fine-grained token: it reaches only what it needs.
284294
285295 For CI and integrations that work for a team, a workspace can have tokens
286296 of its own that act as the workspace and keep working when their creator
287297 leaves. See [workspace tokens](#workspace-tokens).
288298
289−### Create a token
299+### Create a fine-grained token
300+
301+1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens). The
302+ **Fine-grained tokens** tab is first.
303+2. Under **New fine-grained token**, give it a **Token name** after what
304+ will use it, and optionally a **Description**, which a workspace's
305+ owners see if they review it.
306+3. Choose the **Resource owner**: a workspace you belong to, or **Your
307+ account**. A workspace that does not allow fine-grained tokens cannot be
308+ chosen.
309+4. Choose its **Expiration**: 7, 30, 60, 90 or 180 days, or 1 year, or
310+ less when the workspace sets a shorter limit.
311+5. Under **Repository access**, choose **Public repositories** (read-only),
312+ **All repositories** of the workspace (including ones made later), or
313+ **Only select repositories**, and tick up to 50.
314+6. Under **Permissions**, set each one the token needs to **Read-only** or
315+ **Read and write** (and **Admin** for packages). **Metadata** is always
316+ read-only. Each row shows the g1t scopes its level gives.
317+7. Select **Generate token**, and copy it. It is not shown again.
318+
319+When the workspace [requires approval](#a-workspaces-rules-for-tokens) and
320+you are not one of its owners, the token is made **Pending approval**: it
321+works at once, but reads public repositories only until an owner approves
322+it. The owners hear of it in their [inbox](/guides/inbox/), and you hear of
323+their answer in yours. An owner's own token never waits.
324+
325+Select **Edit** on a token to change its name, description, repositories
326+or permissions. The token stays the same. Widening it in a workspace that
327+requires approval asks again. Its resource owner and expiry cannot change;
328+make a new token instead.
329+
330+The list shows each token's status (pending, denied or revoked, with the
331+owner's note), what it reaches, its permissions, and when it was made, last
332+used and expires.
333+
334+### Permissions
335+
336+Each level of a fine-grained token's permissions gives g1t
337+[scopes](#scopes), and the token is checked by those scopes
338+exactly as a classic token is. Where two permissions give the same scopes
339+(Checks and Commit statuses; Secrets and Variables; Deployments and Pages),
340+giving either gives both.
290341
291−1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens).
292−2. Under **New token**, give it a **Name** after what will use it.
342+Repository permissions, for a workspace as the resource owner:
343+
344+| Permission | Levels | What it covers | g1t scopes it gives |
345+| --- | --- | --- | --- |
346+| `actions` (Actions) | read, write | Workflow runs, jobs, logs and artifacts: reading them, and running, cancelling and rerunning workflows | read: `workflows:read`; write: `workflows:write` |
347+| `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` |
348+| `agents` (g1t agents) | write | Putting g1t's agents to work and messaging them, which uses the workspace's money | write: `agents:run` |
349+| `checks` (Checks) | read, write | Check runs and check suites on commits. Shares its scopes with Commit statuses | read: `checks:read`; write: `checks:write` |
350+| `contents` (Contents) | read, write | Code, branches, commits and releases: cloning and fetching, pushing, and publishing releases | read: `code:read`; write: `code:write`, `repo:write` |
351+| `deployments` (Deployments) | read, write | Deployments and their statuses | read: `deployments:read`; write: `deployments:write` |
352+| `environments` (Environments) | read, write | Environments, and their secrets and variables | read: `deployments:read`, `secrets:read`; write: `secrets:admin` |
353+| `issues` (Issues) | read, write | Issues, their comments, labels and milestones, and plans | read: `issues:read`; write: `issues:write` |
354+| `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` |
355+| `metadata` (Metadata) | read | Seeing repositories and searching them. Always read | read: `repo:read` |
356+| `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` |
357+| `pages` (Pages) | read, write | Deployments on g1t.page. Shares its scopes with Deployments | read: `deployments:read`; write: `deployments:write` |
358+| `pull_requests` (Pull requests) | read, write | Pull requests, their reviews, changes, sessions and merge queues | read: `pull_requests:read`; write: `pull_requests:write` |
359+| `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` |
360+| `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` |
361+| `statuses` (Commit statuses) | read, write | Statuses on commits. Shares its scopes with Checks | read: `checks:read`; write: `checks:write` |
362+| `variables` (Variables) | read, write | Actions variables: reading, setting and deleting them. Shares its scopes with Secrets | read: `secrets:read`; write: `secrets:admin` |
363+| `webhooks` (Webhooks) | read, write | Webhooks and their deliveries | read: `webhooks:read`; write: `webhooks:admin` |
364+| `workflows` (Workflows) | write | Adding, changing and deleting workflow files under .g1t/workflows and .github/workflows. Write only | write: `workflow_files:write` |
365+
366+Workspace permissions, for a workspace as the resource owner:
367+
368+| Permission | Levels | What it covers | g1t scopes it gives |
369+| --- | --- | --- | --- |
370+| `members` (Members) | read, write | The workspace's people, invitations and teams | read: `workspace:read`; write: `workspace:admin` |
371+| `workspace_administration` (Administration) | read, write | The workspace's settings, integrations, rulesets and base permission | read: `workspace:read`, `access:read`; write: `workspace:admin`, `access:admin` |
372+| `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` |
373+| `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` |
374+| `self_hosted_runners` (Self-hosted runners) | read, write | Runners, their groups and settings | read: `runners:read`; write: `runners:admin` |
375+| `workspace_secrets` (Secrets) | read, write | The workspace's Actions secrets. Shares its scopes with the repository Secrets permission | read: `secrets:read`; write: `secrets:admin` |
376+| `workspace_webhooks` (Webhooks) | read, write | The workspace's webhooks. Shares its scopes with the repository Webhooks permission | read: `webhooks:read`; write: `webhooks:admin` |
377+
378+Account permissions, for your own account as the resource owner:
379+
380+| Permission | Levels | What it covers | g1t scopes it gives |
381+| --- | --- | --- | --- |
382+| `email_addresses` (Email addresses) | read, write | Your email addresses and email settings, invites and invitations | read: `account:read`; write: `account:write` |
383+| `starring` (Starring) | read, write | Stars and pinned projects. Shares its scopes with Email addresses | read: `account:read`; write: `account:write` |
384+| `notifications` (Notifications) | read, write | Your inbox, subscriptions and watched repositories | read: `notifications:read`; write: `notifications:write` |
385+
386+### What a fine-grained token reaches
387+
388+- **In its workspace**, what your role allows, in the repositories it
389+ reaches, and only what its permissions give.
390+- **Elsewhere**, public repositories, read-only, as anyone can. It cannot
391+ comment, open issues or push there.
392+- **With your account as its resource owner**, public repositories,
393+ read-only, and what its account permissions give.
394+- **While pending, denied or revoked**, public repositories, read-only.
395+
396+A request it cannot make answers `403` naming why: the scope it lacks, or
397+`This fine-grained token's resource owner is the workspace acme: it can only
398+read public repositories elsewhere, …`. A repository outside its selection
399+answers as if it did not exist.
400+
401+### Create a classic token
402+
403+1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens), and
404+ select the **Tokens (classic)** tab.
405+2. Under **New classic token**, give it a **Name** after what will use it.
293406 3. Choose when it **Expires**: 7 days, 30 days, 90 days (the default),
294407 1 year, or No expiry. An expired token stops working; make a new one.
295408 No expiry shows a warning: the token works until someone deletes it.
304417 and select **Save access**. The token stays the same; the change applies
305418 from its next request.
306419
420+A classic token reaches every workspace you belong to unless the
421+workspace's [rules](#a-workspaces-rules-for-tokens) keep it out: one that
422+does not allow classic tokens, one whose longest lifetime this token
423+exceeds, or one whose owner revoked it there. It keeps working everywhere
424+else.
425+
307426 ## Scopes
308427
309428 A scope is a resource and a level, written `resource:level`, such as
320439 | Packages | `packages:read`, `packages:write` |
321440 | Issues & pull requests | `issues:read`, `issues:write`, `pull_requests:read`, `pull_requests:write` |
322441 | Agents | `agents:run` |
323−| Workflows | `workflows:read`, `workflows:write` |
442+| Workflows | `workflows:read`, `workflows:write`, `workflow_files:write` |
324443 | Checks | `checks:read`, `checks:write` |
325444 | Deployments | `deployments:read`, `deployments:write` |
326445 | Memory & search | `memory:read`, `memory:write` |
356475 | `agents:run` | Put g1t to work and message it, which uses the workspace's money |
357476 | `workflows:read` | Read workflows, runs and logs |
358477 | `workflows:write` | Run, cancel, rerun and turn workflows on or off |
478+| `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. |
359479 | `checks:read` | Read commits' statuses, check runs, check suites and annotations |
360480 | `checks:write` | Report [statuses and check runs](/guides/checks/) on commits, and ask for checks to run again |
361481 | `deployments:read` | See [deployments](/guides/deployments-api/), their statuses and environments |
395515
396516 ### What a token can do
397517
398−What a request may do is where two things overlap:
518+What a request may do is where these overlap:
399519
400−1. **Your role.** A token reaches every workspace and repository you can,
401− including ones you join later, and never does more there than you could
402− on the website. A token with `repo:admin` still cannot delete a
403− repository unless you are an owner of its workspace. See
404− [access and roles](/guides/access-and-roles/).
405−2. **Its scopes.** What kinds of thing it may do.
520+1. **Your role.** A token never does more than you could on the website. A
521+ token with `repo:admin` still cannot delete a repository unless you are
522+ an owner of its workspace. See [access and roles](/guides/access-and-roles/).
523+2. **What it reaches.** A classic token, every workspace and repository you
524+ can reach, including ones you join later, unless a workspace's
525+ [rules](#a-workspaces-rules-for-tokens) keep it out. A fine-grained
526+ token, its [resource owner](#what-a-fine-grained-token-reaches) only.
527+3. **Its scopes.** What kinds of thing it may do: chosen directly on a
528+ classic token, given by its permissions on a fine-grained one.
406529
407−To keep a token away from a workspace, use a
408−[workspace token](#workspace-tokens) instead: it reaches only its own
409−workspace.
530+To keep a token away from other workspaces, make a fine-grained one, or use
531+a [workspace token](#workspace-tokens): it reaches only its own workspace.
410532
411533 ### Presets
412534
433555 | Clone or fetch a public repository | No scope |
434556 | Clone or fetch a private repository | `code:read` |
435557 | Push | `code:write` |
558+| Push commits that add, change or delete [workflow files](#workflow-files) | `code:write` and `workflow_files:write` |
436559
437560 Your role on the repository applies too, as on the website. A refused push
438561 or clone says which scope is missing.
439562
563+### Workflow files
564+
565+A workflow runs with its repository's secrets and a token of its own, so
566+changing one is as powerful as holding those. A token therefore needs
567+`workflow_files:write` (a fine-grained token's **Workflows** permission) to
568+add, change or delete any file under `.g1t/workflows/` or
569+`.github/workflows/`, besides `code:write`:
570+
571+- **With git**, every commit a push adds is compared with its parent, and a
572+ push that changes a workflow file is declined, naming it:
573+
574+ ```text
575+ remote: This access token cannot change the workflow file .github/workflows/ci.yml: it needs the workflow_files:write scope.
576+ remote: Push with a token that has the workflow_files:write scope, or make the change signed in on g1t.sh.
577+ ```
578+
579+ A push too large for g1t to read whole is declined for such a token too,
580+ since it cannot be checked; push it in smaller parts.
581+- **Through g1t**, a file written for a token (such as a starter workflow)
582+ is refused the same way.
583+- **A workflow job's token** never may, whatever its `permissions:` say.
584+ See [the job's token](/guides/actions/#the-jobs-token).
585+- **Signed in on g1t.sh**, your role decides, as for any file.
586+
587+Full-access tokens, and tokens made before scopes, include it. A
588+[deploy key](/guides/git/#deploy-keys) with write access may change
589+workflow files.
590+
440591 ### When a token lacks a scope
441592
442593 The API answers `403` with the scope that was missing in `needed_scope`:
473624 owner makes them in the workspace's **Settings → Access tokens**, with the
474625 same checklist and expiry choices; the form starts on the CI preset. A
475626 workspace token reaches all of that workspace's repositories, never
476−another workspace, and cannot manage people, tokens or workspaces. See
627+another workspace, and cannot manage people, tokens or workspaces.
628+
629+It has the Write role on the workspace's repositories, as a member does:
630+it pushes, merges and works on issues and pull requests, within its scopes.
631+Tick **Admin on the workspace's repositories** when making it to give it
632+Admin instead, so it can also manage webhooks, secrets, deploy keys and who
633+has access, and manage teams as an owner would. Only an owner can, and only
634+when making it. See
477635 [workspace access tokens](/guides/workspaces/#workspace-access-tokens).
478636
637+## A workspace's rules for tokens
638+
639+An owner decides which of the members' own personal tokens reach the
640+workspace, under its **Settings → Personal access tokens**
641+(`g1t.sh/<workspace>/-/personal-access-tokens`). The rules apply from each
642+token's next request, to tokens made before them too. A token they keep out
643+keeps working everywhere else, and reads the workspace's public
644+repositories as anyone can.
645+
646+| Rule | Default | What it does |
647+| --- | --- | --- |
648+| 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. |
649+| 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. |
650+| Allow classic personal access tokens | On | Off: classic tokens no longer reach the workspace. |
651+| Tokens must expire | Off | On: a token that never expires does not reach the workspace. |
652+| 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. |
653+
654+The same page lists:
655+
656+- **Waiting for approval.** Each pending fine-grained token with its owner,
657+ permissions, repositories and expiry. Add an optional note, then select
658+ **Approve** or **Deny**. Its owner hears of it in their inbox, with the
659+ note.
660+- **Tokens that can reach the workspace.** Every fine-grained token naming
661+ it, and every classic token of its members and outside collaborators that
662+ has not expired, with its owner, permissions or scopes, last use and
663+ expiry, and whether it reaches the workspace now (and if not, why). Never
664+ the token itself. Select **Revoke** to take one out: a fine-grained token
665+ stops reaching the workspace for good; a classic token keeps working
666+ everywhere else, but never reaches this workspace again.
667+
668+Approvals, denials, revocations and rule changes are
669+[audit log](/guides/audit-log/) entries: `token.approval_requested`,
670+`token.approved`, `token.denied`, `token.revoked` and
671+`token.policy_changed`.
672+
673+### A workspace's rules through the API
674+
675+Owners, as people (a personal token with the scope works; a workspace's own
676+token does not):
677+
678+| Route | MCP tool and action | What it does | Scope |
679+| --- | --- | --- | --- |
680+| [`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` |
681+| [`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` |
682+| [`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` |
683+| [`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` |
684+| [`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` |
685+| [`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` |
686+
479687 ## Signing in with OAuth
480688
481689 Applications that can open your browser, such as an agent connecting to the
562770
563771 Only approve a code you asked for. The token has full access: it can do
564772 everything you can. To give a tool less, make an
565−[access token](#create-a-token) with only the scopes it needs instead.
773+[access token](#create-a-fine-grained-token) with only the scopes it needs instead.
566774
567775 ## Resetting your password
568776
+2−2
4444 | Reason | Shown as | Why you were told |
4545 | --- | --- | --- |
4646 | `agent` | agent waiting | An agent is waiting on you: it asked a question, or it stopped until a person steps in. |
47−| `review_requested` | review requested | Someone asked you, or a team you are in, to review a pull request; it changes files you own; or you are one of its reviewers. Also a workflow run waiting for you, as one of an [environment's reviewers](/guides/actions/#environments), to approve its deployment. |
47+| `review_requested` | review requested | Someone asked you, or a team you are in, to review a pull request; it changes files you own; or you are one of its reviewers. Also a workflow run waiting for you, as one of an [environment's reviewers](/guides/actions/#environments), to approve its deployment, and, for a workspace's owners, a member's fine-grained token waiting for [approval](/guides/authentication/#a-workspaces-rules-for-tokens) (in the inbox only, never emailed). |
4848 | `assign` | assigned | You were assigned, or you are an assignee. |
4949 | `mention` | mentioned | Someone mentioned you with `@username`, or you were mentioned on it before. |
5050 | `team_mention` | team mentioned | Someone mentioned a [team](/guides/teams/#mentions) you are in with `@workspace/team`, or a team you are in was mentioned on it before. |
5151 | `ci_activity` | CI activity | A check, workflow or deployment on your work finished badly, or recovered. |
5252 | `security_alert` | security alert | A new secret, code scanning or vulnerability alert on a repository you look after, a push of yours that push protection blocked, or a [bypass request](/guides/security/secret-protection/#delegated-bypass) to review or its answer. The workspace's owners hear of new alerts; watchers who chose **Security alerts** do too, if they can see findings. |
5353 | `state_change` | state changed | It was closed, reopened or merged. |
54−| `author` | your work | You opened it, or you asked g1t for it. |
54+| `author` | your work | You opened it, or you asked g1t for it. Also an owner's answer to your [fine-grained token](/guides/authentication/#create-a-fine-grained-token) waiting for approval, or its revocation. |
5555 | `comment` | commented | You commented on it. |
5656 | `manual` | subscribed | You subscribed to it yourself. |
5757 | `subscribed` | watching | You watch its repository. |
+12−5
509509 | --- | --- | --- |
510510 | Belongs to | You | The workspace |
511511 | Acts as | You | The workspace: its name is the author of what it does |
512−| Can reach | Every workspace you belong to | That workspace only |
513−| Can do | What its [scopes](/guides/authentication/#scopes) allow, never more than you can | What its scopes allow, on the workspace's repositories; it cannot manage people, tokens or workspaces |
514−| Expires | 7, 30 or 90 days (the default), 1 year, or never | The same choices |
512+| Can reach | A classic token, every workspace you belong to; a fine-grained one, the one it names | That workspace only |
513+| Can do | What its [scopes](/guides/authentication/#scopes) or permissions allow, never more than you can | What its scopes allow, with Write on the workspace's repositories (Admin only when an owner gives it that); it cannot manage people, tokens or workspaces |
514+| Expires | A classic token: 7, 30 or 90 days (the default), 1 year, or never. A fine-grained one: within a year | 7, 30 or 90 days, 1 year, or never |
515515 | When its creator leaves | Stops working | Keeps working |
516516 | Created by | You, in [Settings → Access tokens](https://g1t.sh/settings/tokens) | An owner, under the workspace's **Settings → Access tokens** |
517517
523523 Every member can see a workspace's tokens: the name, who created each,
524524 when it was last used and when it expires. Only owners can create or
525525 delete them. An owner creates one with a name, an expiry (No expiry shows
526−a warning) and the same scope checklist as a personal token, starting on
527−the CI preset.
526+a warning) and the same scope checklist as a classic personal token,
527+starting on the CI preset. Each token shows **Write** or **Admin**: tick
528+**Admin on the workspace's repositories** when making it to let it manage
529+webhooks, secrets, deploy keys and who has access, and teams as an owner
530+would. A token made before this choice existed has Write.
531+
532+Which of your members' own personal tokens reach the workspace is set under
533+**Settings → Personal access tokens**; see
534+[a workspace's rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens).
528535
529536 ## Profiles
530537
+61−4
325325 (people, access tokens, settings), which no repository can be named.
326326 - **Workspace access tokens instead of service accounts.** A workspace has
327327 tokens of its own, in the same table and code path as personal ones. One
328− acts as the workspace, with a member's rights in that workspace only,
329− records who made it and when it was last used, and keeps working when
330− that person leaves. CI, integrations and automations use these.
328+ acts as the workspace, with a member's rights in that workspace only (the
329+ Write role on its repositories; Admin only when an owner ticks it at
330+ creation, `access_tokens.admin`, identity/0034), records who made it and
331+ when it was last used, and keeps working when that person leaves. CI,
332+ integrations and automations use these. Until 2026-10-08 the code gave
333+ them Admin on every repository, which the security audit found let any
334+ workspace token manage webhooks; code, this plan and the docs now agree.
331335
332336 ### Portfolio
333337
479483 commands declared in `.g1t/checks.yaml`, run in sandboxes on every pull request
480484 and on every combined state in the landing queue.
481485
486+### Tokens, scopes and packages the GitHub way (built 2026-10-08)
487+
488+> **2026-10-08 (owner):** "emulate all of what GitHub does for scope
489+> mapping and packages." GitHub's current behaviour is the spec.
490+
491+This **reverses identity/0023**, which retired a token's reach to some
492+workspaces or repositories and left classic tokens only. The reason it is
493+reversed: the owner chose GitHub parity, and GitHub has fine-grained tokens
494+beside classic ones, with workspaces (organizations) governing both.
495+
496+- **Fine-grained personal access tokens** (identity/0034,
497+ `services/identity/src/token_reach.rs`, `g1t_contracts::fine_grained`):
498+ one resource owner (a workspace the person belongs to, or their own
499+ account), all, selected (up to 50, by repository id) or only public
500+ repositories, and a level per permission under GitHub's names (contents,
501+ metadata, issues, pull_requests, actions, workflows, checks, statuses,
502+ deployments, pages, environments, secrets, variables, webhooks,
503+ administration, packages, security_events; members,
504+ workspace_administration, self_hosted_runners, workspace_secrets,
505+ workspace_webhooks, workspace_billing, models; email_addresses, starring,
506+ notifications; g1t's agents and memory). Each level maps onto g1t's
507+ scopes, which the token stores, so every check that reads scopes
508+ (`scopes::decide` for the API and MCP, `decide_git`, `decide_packages`)
509+ reads them unchanged. They must expire, within 366 days. On each use,
510+ identity cuts the resolved person down to the token's reach
511+ (`apply_reach`); `access::granted` gives no role outside it, so a public
512+ repository elsewhere still reads and nothing more.
513+- **Governance** (`token_policies`, `token_workspace_revocations`): per
514+ workspace, allow classic, allow fine-grained, require approval (on by
515+ default, as GitHub's; owners' own tokens never wait), the longest
516+ lifetime, and forbidding tokens that never expire. Owners see every
517+ member's token that can reach the workspace, approve or deny pending
518+ fine-grained ones (inbox: `token.approval_requested` and
519+ `token.approval_reviewed`, the inbox's first notices about no
520+ repository), and revoke one there. REST and MCP for owners; audited as
521+ `token.*`.
522+- **Workflow files** need `workflow_files:write` (GitHub's `workflow`
523+ scope; the `workflows` permission) from any token, checked commit by
524+ commit on push (`services/repos/src/workflow_gate.rs`) and on files g1t
525+ writes for a token. A job's token never has it. g1t's agents push with
526+ run credentials, not tokens, and are not gated by it; their work arrives
527+ as pull requests people review.
528+- **Workspace tokens** have Write unless an owner gives Admin at creation.
529+- **Deploy keys** (identity/0035): per repository, read-only unless write
530+ is ticked; resolved to a principal bound to the one repository.
531+ Serving git over SSH is still to come, so nothing uses them yet.
532+- **Packages**: per-package roles with "inherit access from the linked
533+ repository", "Manage Actions access" enforced against job tokens, linking
534+ by `org.opencontainers.image.source`, 30-day soft delete with restore and
535+ a purge, a settings tab, public REST and MCP, and download counts per
536+ version in every registry.
537+
482538 ### Keeping workflow runs safe (built 2026-10-08)
483539
484540 An audit of g1t Actions found a job's token was a full-access workspace
17581814
17591815 1. Deleting a branch once its pull request merges; risk tiers. (Approval
17601816 rules per path are in, as CODEOWNERS.)
1761−2. Scopes on OAuth grants and access tokens.
1817+2. Scopes on OAuth grants and access tokens. (Done, with fine-grained
1818+ tokens and workspace rules for them, 2026-10-08.)
17621819 3. Event storage per the design above: per-repo hot log, Iceberg on R2,
17631820 hash-chained audit.
17641821 4. CLI with Claude Code hooks to record sessions automatically.