One kind of access token; presence and status; usernames keep their case; the tour is a miniature of the real app; icons for password managers
- Tokens: classic and fine-grained are one token with a level per resource (each level is a scope, one enforcement path), a reach (all your workspaces, one workspace with all, selected or only public repositories, or none), an owner and an expiry; identity/0041 writes every existing token's access out exactly; one form, list and page for yours and a workspace's; old URLs redirect - Presence: active, away and offline from open tabs, live over the notifications socket through a room per workspace; a status with emoji and clear-after, set away, pause notifications (Do Not Disturb silences toasts and push); a source field so calendars and integrations can set status later, never over one set by hand - Usernames: letters in either case, digits and single hyphens, up to 39; unique and looked up regardless of case, shown as chosen (identity/0042) - The homepage tour draws the real shell: labelled rail in its order, the real top bar, sidebars, session cards and tab bar; Agents works today; named agents are hired from templates - apple-touch-icon-precomposed and a web manifest for the site and the docs
| 65 | 65 | ), | |
| 66 | 66 | ( | |
| 67 | 67 | "Personal access tokens", | |
| 68 | − | "A workspace's rules for its members' personal access tokens: whether classic and fine-grained tokens reach it, whether fine-grained tokens wait for an owner's approval, and how long a token may last; the tokens that reach it, approving or denying the ones that wait, and revoking one there. Owners only, as people.", | |
| 68 | + | "A workspace's rules for its members' personal access tokens: whether tokens made for all of a member's workspaces reach it, whether tokens may be made for it alone and wait for an owner's approval, and how long a token may last; the tokens that reach it, approving or denying the ones that wait, and revoking one there. Owners only, as people.", | |
| 69 | 69 | &[ | |
| 70 | 70 | Op::Tokens(TokenOp::GetTokenPolicy), | |
| 71 | 71 | Op::Tokens(TokenOp::SetTokenPolicy), |
| 10665 | 10665 | "workspace": "flagon-io" | |
| 10666 | 10666 | }, | |
| 10667 | 10667 | "response": { | |
| 10668 | − | "allow_classic": true, | |
| 10669 | − | "allow_fine_grained": true, | |
| 10668 | + | "allow_tokens_for_all_workspaces": true, | |
| 10669 | + | "allow_tokens_for_this_workspace": true, | |
| 10670 | 10670 | "require_approval": true, | |
| 10671 | 10671 | "max_lifetime_days": null, | |
| 10672 | 10672 | "forbid_no_expiry": false, | |
| ⋯ | |||
| 10679 | 10679 | "workspace": "flagon-io" | |
| 10680 | 10680 | }, | |
| 10681 | 10681 | "request": { | |
| 10682 | − | "allow_classic": false, | |
| 10682 | + | "allow_tokens_for_all_workspaces": false, | |
| 10683 | 10683 | "max_lifetime_days": 90 | |
| 10684 | 10684 | }, | |
| 10685 | 10685 | "response": { | |
| 10686 | − | "allow_classic": false, | |
| 10687 | − | "allow_fine_grained": true, | |
| 10686 | + | "allow_tokens_for_all_workspaces": false, | |
| 10687 | + | "allow_tokens_for_this_workspace": true, | |
| 10688 | 10688 | "require_approval": true, | |
| 10689 | 10689 | "max_lifetime_days": 90, | |
| 10690 | 10690 | "forbid_no_expiry": false, | |
| 10691 | 10691 | "updated_by": "ada", | |
| 10692 | 10692 | "updated_at": "2026-10-08T09:30:00.000Z" | |
| 10693 | 10693 | }, | |
| 10694 | − | "notes": "From each token's next request, classic tokens no longer reach the workspace, and neither does a token that lasts longer than 90 days or never expires. They keep working everywhere else." | |
| 10694 | + | "notes": "From each token's next request, tokens made for all of a member's workspaces no longer reach this one (tokens made for it alone still do), and neither does a token that lasts longer than 90 days or never expires. They keep working everywhere else." | |
| 10695 | 10695 | }, | |
| 10696 | 10696 | "list_member_tokens": { | |
| 10697 | 10697 | "params": { | |
| ⋯ | |||
| 10702 | 10702 | "id": "tok_01HZX3K2M9V7Q4N8B6D5C3A2E1", | |
| 10703 | 10703 | "name": "release-bot", | |
| 10704 | 10704 | "owner": "ada", | |
| 10705 | − | "kind": "fine_grained", | |
| 10706 | − | "description": "Publishes releases from CI", | |
| 10705 | + | "description": "Publishes releases from CI", | |
| 10707 | 10706 | "created_at": "2026-10-08T09:00:00.000Z", | |
| 10708 | 10707 | "created_by": null, | |
| 10709 | 10708 | "last_used_at": null, | |
| 10710 | 10709 | "expires_at": "2026-11-07T09:00:00.000Z", | |
| 10711 | − | "scopes": ["repo:read", "repo:write", "code:read", "code:write"], | |
| 10712 | − | "resource_owner": "flagon-io", | |
| 10710 | + | "scopes": ["repo:read", "code:write"], | |
| 10711 | + | "workspace": "flagon-io", | |
| 10713 | 10712 | "repository_selection": "selected", | |
| 10714 | 10713 | "repositories": ["flagon-io/hello"], | |
| 10715 | − | "permissions": { "contents": "write", "metadata": "read" }, | |
| 10714 | + | "permissions": { "code": "write", "repo": "read" }, | |
| 10716 | 10715 | "status": "pending", | |
| 10717 | 10716 | "review_reason": null, | |
| 10718 | 10717 | "reaches": false, | |
| ⋯ | |||
| 10729 | 10728 | "id": "tok_01HZX3K2M9V7Q4N8B6D5C3A2E1", | |
| 10730 | 10729 | "name": "release-bot", | |
| 10731 | 10730 | "owner": "ada", | |
| 10732 | − | "kind": "fine_grained", | |
| 10733 | − | "description": "Publishes releases from CI", | |
| 10731 | + | "description": "Publishes releases from CI", | |
| 10734 | 10732 | "created_at": "2026-10-08T09:00:00.000Z", | |
| 10735 | 10733 | "created_by": null, | |
| 10736 | 10734 | "last_used_at": null, | |
| 10737 | 10735 | "expires_at": "2026-11-07T09:00:00.000Z", | |
| 10738 | − | "scopes": ["repo:read", "repo:write", "code:read", "code:write"], | |
| 10739 | − | "resource_owner": "flagon-io", | |
| 10736 | + | "scopes": ["repo:read", "code:write"], | |
| 10737 | + | "workspace": "flagon-io", | |
| 10740 | 10738 | "repository_selection": "selected", | |
| 10741 | 10739 | "repositories": ["flagon-io/hello"], | |
| 10742 | − | "permissions": { "contents": "write", "metadata": "read" }, | |
| 10740 | + | "permissions": { "code": "write", "repo": "read" }, | |
| 10743 | 10741 | "status": "pending", | |
| 10744 | 10742 | "review_reason": null, | |
| 10745 | 10743 | "reaches": false, | |
| ⋯ | |||
| 10759 | 10757 | "id": "tok_01HZX3K2M9V7Q4N8B6D5C3A2E1", | |
| 10760 | 10758 | "name": "release-bot", | |
| 10761 | 10759 | "owner": "ada", | |
| 10762 | − | "kind": "fine_grained", | |
| 10763 | − | "description": "Publishes releases from CI", | |
| 10760 | + | "description": "Publishes releases from CI", | |
| 10764 | 10761 | "created_at": "2026-10-08T09:00:00.000Z", | |
| 10765 | 10762 | "created_by": null, | |
| 10766 | 10763 | "last_used_at": null, | |
| 10767 | 10764 | "expires_at": "2026-11-07T09:00:00.000Z", | |
| 10768 | − | "scopes": ["repo:read", "repo:write", "code:read", "code:write"], | |
| 10769 | − | "resource_owner": "flagon-io", | |
| 10765 | + | "scopes": ["repo:read", "code:write"], | |
| 10766 | + | "workspace": "flagon-io", | |
| 10770 | 10767 | "repository_selection": "selected", | |
| 10771 | 10768 | "repositories": ["flagon-io/hello"], | |
| 10772 | − | "permissions": { "contents": "write", "metadata": "read" }, | |
| 10769 | + | "permissions": { "code": "write", "repo": "read" }, | |
| 10773 | 10770 | "status": "active", | |
| 10774 | 10771 | "review_reason": null, | |
| 10775 | 10772 | "reaches": true, | |
| 58 | 58 | // A workspace's rules for personal access tokens, and its members' tokens. | |
| 59 | 59 | route("GET", "/workspaces/:workspace/personal-access-token-policy", Op::Tokens(TokenOp::GetTokenPolicy), &[]), | |
| 60 | 60 | route("PATCH", "/workspaces/:workspace/personal-access-token-policy", Op::Tokens(TokenOp::SetTokenPolicy), &[]), | |
| 61 | − | route("GET", "/workspaces/:workspace/personal-access-tokens", Op::Tokens(TokenOp::ListMemberTokens), &[("kind", "kind")]), | |
| 61 | + | route("GET", "/workspaces/:workspace/personal-access-tokens", Op::Tokens(TokenOp::ListMemberTokens), &[]), | |
| 62 | 62 | route("POST", "/workspaces/:workspace/personal-access-tokens/:id", Op::Tokens(TokenOp::RevokeMemberToken), &[]), | |
| 63 | 63 | route("GET", "/workspaces/:workspace/personal-access-token-requests", Op::Tokens(TokenOp::ListTokenRequests), &[]), | |
| 64 | 64 | route("POST", "/workspaces/:workspace/personal-access-token-requests/:id", Op::Tokens(TokenOp::ReviewTokenRequest), &[]), |
| 1 | 1 | //! A workspace's rules for personal access tokens, over REST and MCP: the | |
| 2 | − | //! policy (which kinds reach it, approval, lifetime), the members' tokens | |
| 3 | − | //! that reach it, approving or denying fine-grained tokens that wait for | |
| 2 | + | //! policy (which tokens reach it, approval, lifetime), the members' tokens | |
| 3 | + | //! that reach it, approving or denying tokens made for it that wait for | |
| 4 | 4 | //! approval, and revoking a token there. Identity decides and keeps all of | |
| 5 | 5 | //! it (services/identity/src/token_reach.rs); owners only, as people. | |
| 6 | 6 | ||
| ⋯ | |||
| 50 | 50 | TokenOp::GetTokenPolicy => "Get a workspace's personal access token policy", | |
| 51 | 51 | TokenOp::SetTokenPolicy => "Set a workspace's personal access token policy", | |
| 52 | 52 | TokenOp::ListMemberTokens => "List the personal access tokens that reach a workspace", | |
| 53 | − | TokenOp::ListTokenRequests => "List fine-grained tokens waiting for approval", | |
| 54 | − | TokenOp::ReviewTokenRequest => "Approve or deny a fine-grained token", | |
| 53 | + | TokenOp::ListTokenRequests => "List personal access tokens waiting for approval", | |
| 54 | + | TokenOp::ReviewTokenRequest => "Approve or deny a personal access token", | |
| 55 | 55 | TokenOp::RevokeMemberToken => "Revoke a member's token in a workspace", | |
| 56 | 56 | } | |
| 57 | 57 | } | |
| 58 | 58 | ||
| 59 | 59 | pub fn description(self) -> &'static str { | |
| 60 | 60 | match self { | |
| 61 | − | TokenOp::GetTokenPolicy => "A workspace's rules for its members' personal access tokens: allow_classic (classic tokens reach it), allow_fine_grained (fine-grained tokens may name it as their resource owner), require_approval (a fine-grained token naming it waits for an owner's approval; true unless an owner says, and never for an owner's own token), max_lifetime_days (the longest a token reaching it may last; null for no limit, and a fine-grained token lasts at most 366 days anyway) and forbid_no_expiry (a token that never expires does not reach it). A token outside the rules keeps working elsewhere and reaches the workspace's public repositories only. Members only.", | |
| 61 | + | TokenOp::GetTokenPolicy => "A workspace's rules for its members' personal access tokens: allow_tokens_for_all_workspaces (a token made for every workspace of its owner reaches this one), allow_tokens_for_this_workspace (a token may be made for this workspace alone), require_approval (a token made for this workspace waits for an owner's approval; true unless an owner says, and never for an owner's own token), max_lifetime_days (the longest a token reaching it may last; null for no limit, and a token with an expiry lasts at most 366 days anyway) and forbid_no_expiry (a token that never expires does not reach it). A token outside the rules keeps working elsewhere and reaches the workspace's public repositories only. Members only.", | |
| 62 | 62 | TokenOp::SetTokenPolicy => "Change a workspace's rules for personal access tokens; fields left out stay as they are. max_lifetime_days of 0 removes the limit. The rules apply from each token's next request, to tokens made before them too. Owners only, as people.", | |
| 63 | − | TokenOp::ListMemberTokens => "The personal access tokens of the workspace's members and outside collaborators that can reach it: every fine-grained token naming it as its resource owner, whatever its status, and every classic token that has not expired. Each with its owner, kind, name, scopes, a fine-grained token's permissions, repository_selection, repositories and status (active, pending, denied or revoked), when it was made, last used and expires, and whether it reaches the workspace now (reaches, and blocked_by when not: pending approval, denied, revoked, classic tokens not allowed, lasts too long, never expires). Never the token itself. kind narrows it to classic or fine_grained. Owners only, as people.", | |
| 64 | − | TokenOp::ListTokenRequests => "The fine-grained tokens naming the workspace that wait for an owner's approval, as list_member_tokens shows them. Until approved, a token reaches public repositories only. Owners only, as people.", | |
| 65 | − | TokenOp::ReviewTokenRequest => "Approve or deny a fine-grained token waiting for approval: decision is approve or deny, and reason, if given, is shown to the token's owner, who hears of it in their inbox. An approved token reaches the workspace from its next request; a denied one reaches public repositories only. Recorded in the audit log as token.approved or token.denied. Owners only, as people.", | |
| 66 | − | TokenOp::RevokeMemberToken => "Take a member's token out of the workspace, with an optional reason its owner is shown. A fine-grained token naming the workspace stops reaching it for good; a classic token keeps working everywhere else but never reaches this workspace again. Recorded in the audit log as token.revoked. Owners only, as people.", | |
| 63 | + | TokenOp::ListMemberTokens => "The personal access tokens of the workspace's members and outside collaborators that can reach it and have not expired: every token made for this workspace, whatever its status, and every token made for all of its owner's workspaces. Each with its owner, name, description, permissions (each resource at its level, such as {\"issues\": \"write\"}), scopes, workspace (the one it is made for; null for all of its owner's), repository_selection (all, selected or public), repositories, status (active, pending, denied or revoked), when it was made, last used and expires, and whether it reaches the workspace now (reaches, and blocked_by when not: pending approval, denied, revoked, tokens for all workspaces not allowed, tokens made for this workspace not allowed, lasts too long, never expires). Never the token itself. Owners only, as people.", | |
| 64 | + | TokenOp::ListTokenRequests => "The tokens made for the workspace that wait for an owner's approval, as list_member_tokens shows them. Until approved, a token reaches public repositories only. Owners only, as people.", | |
| 65 | + | TokenOp::ReviewTokenRequest => "Approve or deny a token waiting for approval: decision is approve or deny, and reason, if given, is shown to the token's owner, who hears of it in their inbox. An approved token reaches the workspace from its next request; a denied one reaches public repositories only. Recorded in the audit log as token.approved or token.denied. Owners only, as people.", | |
| 66 | + | TokenOp::RevokeMemberToken => "Take a member's token out of the workspace, with an optional reason its owner is shown. A token made for this workspace stops reaching it for good; a token made for all of its owner's workspaces keeps working everywhere else but never reaches this one again. Recorded in the audit log as token.revoked. Owners only, as people.", | |
| 67 | 67 | } | |
| 68 | 68 | } | |
| 69 | 69 | ||
| ⋯ | |||
| 78 | 78 | let id = json!({ "type": "string", "description": "The token's id, tok_…." }); | |
| 79 | 79 | let reason = json!({ "type": "string", "description": "Why, shown to the token's owner." }); | |
| 80 | 80 | let (properties, required): (Value, &[&str]) = match self { | |
| 81 | − | TokenOp::GetTokenPolicy | TokenOp::ListTokenRequests => (json!({ "workspace": workspace }), &["workspace"]), | |
| 81 | + | TokenOp::GetTokenPolicy | TokenOp::ListTokenRequests | TokenOp::ListMemberTokens => (json!({ "workspace": workspace }), &["workspace"]), | |
| 82 | 82 | TokenOp::SetTokenPolicy => ( | |
| 83 | 83 | json!({ | |
| 84 | 84 | "workspace": workspace, | |
| 85 | − | "allow_classic": { "type": "boolean", "description": "Classic tokens reach the workspace." }, | |
| 86 | − | "allow_fine_grained": { "type": "boolean", "description": "Fine-grained tokens may name the workspace as their resource owner." }, | |
| 87 | − | "require_approval": { "type": "boolean", "description": "A fine-grained token naming the workspace waits for an owner's approval." }, | |
| 85 | + | "allow_tokens_for_all_workspaces": { "type": "boolean", "description": "A token made for every workspace of its owner reaches this one." }, | |
| 86 | + | "allow_tokens_for_this_workspace": { "type": "boolean", "description": "A token may be made for this workspace alone." }, | |
| 87 | + | "require_approval": { "type": "boolean", "description": "A token made for this workspace waits for an owner's approval." }, | |
| 88 | 88 | "max_lifetime_days": { "type": "integer", "description": "The longest a token reaching it may last, in days, 1 to 3650; 0 for no limit." }, | |
| 89 | 89 | "forbid_no_expiry": { "type": "boolean", "description": "A token that never expires does not reach the workspace." }, | |
| 90 | 90 | }), | |
| 91 | 91 | &["workspace"], | |
| 92 | 92 | ), | |
| 93 | − | TokenOp::ListMemberTokens => ( | |
| 94 | − | json!({ | |
| 95 | − | "workspace": workspace, | |
| 96 | − | "kind": { "type": "string", "enum": ["classic", "fine_grained"], "description": "Only tokens of this kind." }, | |
| 97 | − | }), | |
| 98 | − | &["workspace"], | |
| 99 | − | ), | |
| 100 | 93 | TokenOp::ReviewTokenRequest => ( | |
| 101 | 94 | json!({ | |
| 102 | 95 | "workspace": workspace, | |
| ⋯ | |||
| 138 | 131 | } | |
| 139 | 132 | } | |
| 140 | 133 | ||
| 141 | − | /// A member's token in one flat shape: the token's fields, a fine-grained | |
| 142 | − | /// token's beside them, and its owner and whether it reaches the workspace. | |
| 143 | − | /// Keys stay as identity sends them (`camelCase`); the API's converter | |
| 144 | − | /// writes them out in `snake_case`. | |
| 134 | + | /// A member's token in one flat shape: the token's fields, and its owner | |
| 135 | + | /// and whether it reaches the workspace. Keys stay as identity sends them | |
| 136 | + | /// (`camelCase`); the API's converter writes them out in `snake_case`. | |
| 145 | 137 | pub(crate) fn member_view(member: &Value) -> Value { | |
| 146 | 138 | let mut out = Map::new(); | |
| 147 | 139 | if let Some(token) = member["token"].as_object() { | |
| 148 | 140 | for (key, value) in token { | |
| 149 | − | if key != "fineGrained" && key != "legacy" { | |
| 141 | + | if key != "legacy" && key != "workspaceOwned" && key != "admin" { | |
| 150 | 142 | out.insert(key.clone(), value.clone()); | |
| 151 | − | } | |
| 152 | − | } | |
| 153 | − | if let Some(details) = token.get("fineGrained").and_then(Value::as_object) { | |
| 154 | − | for (key, value) in details { | |
| 155 | − | let key = if key == "workspace" { "resourceOwner".to_owned() } else { key.clone() }; | |
| 156 | − | out.insert(key, value.clone()); | |
| 157 | 143 | } | |
| 158 | 144 | } | |
| 159 | 145 | } | |
| ⋯ | |||
| 196 | 182 | &json!({ | |
| 197 | 183 | "actor": actor, | |
| 198 | 184 | "slug": workspace, | |
| 199 | − | "allow_classic": flag(input, "allow_classic"), | |
| 200 | − | "allow_fine_grained": flag(input, "allow_fine_grained"), | |
| 185 | + | "allow_tokens_for_all_workspaces": flag(input, "allow_tokens_for_all_workspaces"), | |
| 186 | + | "allow_tokens_for_this_workspace": flag(input, "allow_tokens_for_this_workspace"), | |
| 201 | 187 | "require_approval": flag(input, "require_approval"), | |
| 202 | 188 | "max_lifetime_days": days, | |
| 203 | 189 | "forbid_no_expiry": flag(input, "forbid_no_expiry"), | |
| ⋯ | |||
| 207 | 193 | .await? | |
| 208 | 194 | } | |
| 209 | 195 | TokenOp::ListMemberTokens | TokenOp::ListTokenRequests => { | |
| 210 | − | let kind = text(input, "kind"); | |
| 211 | − | if kind.as_deref().is_some_and(|kind| kind != "classic" && kind != "fine_grained") { | |
| 212 | − | return Ok(Outcome::fail(FailureCode::Invalid, "kind is classic or fine_grained.")); | |
| 213 | − | } | |
| 214 | 196 | let status = (op == TokenOp::ListTokenRequests).then_some("pending"); | |
| 215 | − | let kind = if op == TokenOp::ListTokenRequests { Some("fine_grained".to_owned()) } else { kind }; | |
| 216 | − | let members: Outcome<Value> = | |
| 217 | − | g1t_kit::call(identity, "list_member_tokens", &json!({ "actor": actor, "slug": workspace, "status": status, "kind": kind })).await?; | |
| 197 | + | let members: Outcome<Value> = g1t_kit::call(identity, "list_member_tokens", &json!({ "actor": actor, "slug": workspace, "status": status })).await?; | |
| 218 | 198 | map(members, list) | |
| 219 | 199 | } | |
| 220 | 200 | TokenOp::ReviewTokenRequest => { | |
| ⋯ | |||
| 275 | 255 | "token": { | |
| 276 | 256 | "id": "tok_1", "name": "ci", "createdAt": "2026-10-08T00:00:00.000Z", "lastUsedAt": null, | |
| 277 | 257 | "createdBy": null, "scopes": ["repo:read", "code:read"], "legacy": false, "expiresAt": "2026-11-07T00:00:00.000Z", | |
| 278 | − | "kind": "fine_grained", | |
| 279 | − | "fineGrained": { "workspace": "acme", "repositorySelection": "selected", "repositories": ["acme/web"], "permissions": { "contents": "read", "metadata": "read" }, "status": "pending" }, | |
| 258 | + | "permissions": { "code": "read", "repo": "read" }, | |
| 259 | + | "workspace": "acme", "repositorySelection": "selected", "repositories": ["acme/web"], "status": "pending", | |
| 280 | 260 | }, | |
| 281 | 261 | })); | |
| 282 | 262 | assert_eq!(view["owner"], "ana"); | |
| 283 | − | assert_eq!(view["resourceOwner"], "acme"); | |
| 263 | + | assert_eq!(view["workspace"], "acme"); | |
| 284 | 264 | assert_eq!(view["repositorySelection"], "selected"); | |
| 285 | − | assert_eq!(view["permissions"]["contents"], "read"); | |
| 265 | + | assert_eq!(view["permissions"]["code"], "read"); | |
| 286 | 266 | assert_eq!(view["status"], "pending"); | |
| 287 | 267 | assert_eq!(view["blockedBy"], "pending approval"); | |
| 288 | − | assert!(view.get("fineGrained").is_none() && view.get("legacy").is_none()); | |
| 268 | + | assert!(view.get("legacy").is_none()); | |
| 289 | 269 | } | |
| 290 | 270 | ||
| 291 | 271 | #[test] | |
| 407 | 407 | a("delete_ruleset", Op::Rules(RulesOp::DeleteWorkspaceRuleset), "Delete one of its rulesets"), | |
| 408 | 408 | a("rule_evaluations", Op::Rules(RulesOp::ListWorkspaceRuleEvaluations), "How rules judged changes across its repositories"), | |
| 409 | 409 | a("get_token_policy", Op::Tokens(TokenOp::GetTokenPolicy), "Its rules for personal access tokens"), | |
| 410 | − | a("set_token_policy", Op::Tokens(TokenOp::SetTokenPolicy), "Change them: kinds allowed, approval, lifetime"), | |
| 410 | + | a("set_token_policy", Op::Tokens(TokenOp::SetTokenPolicy), "Change them: which tokens reach it, approval, lifetime"), | |
| 411 | 411 | a("list_member_tokens", Op::Tokens(TokenOp::ListMemberTokens), "Members' personal access tokens that reach it"), | |
| 412 | − | a("list_token_requests", Op::Tokens(TokenOp::ListTokenRequests), "Fine-grained tokens waiting for approval"), | |
| 412 | + | a("list_token_requests", Op::Tokens(TokenOp::ListTokenRequests), "Tokens waiting for approval"), | |
| 413 | 413 | a("review_token_request", Op::Tokens(TokenOp::ReviewTokenRequest), "Approve or deny one"), | |
| 414 | 414 | a("revoke_member_token", Op::Tokens(TokenOp::RevokeMemberToken), "Revoke a member's token in it"), | |
| 415 | 415 | ], |
| 1 | 1 | # Fingerprinted by the build (typefaces, styles, scripts): kept for good. | |
| 2 | 2 | /_astro/* | |
| 3 | 3 | Cache-Control: public, max-age=31536000, immutable | |
| 4 | + | ||
| 5 | + | # The web app manifest: name, icons and colours for home screens. | |
| 6 | + | /site.webmanifest | |
| 7 | + | Content-Type: application/manifest+json |
Binary or large file; its contents are not shown.
| 1 | + | { | |
| 2 | + | "name": "g1t docs", | |
| 3 | + | "short_name": "g1t", | |
| 4 | + | "description": "How to use g1t: chat, agents, docs and code in one workspace.", | |
| 5 | + | "start_url": "/", | |
| 6 | + | "scope": "/", | |
| 7 | + | "display": "minimal-ui", | |
| 8 | + | "background_color": "#0f0f11", | |
| 9 | + | "theme_color": "#0f0f11", | |
| 10 | + | "icons": [ | |
| 11 | + | { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, | |
| 12 | + | { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, | |
| 13 | + | { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" } | |
| 14 | + | ] | |
| 15 | + | } |
| 406 | 406 | g1t is invite-only for now. See [Invites](/guides/authentication/#invites). | |
| 407 | 407 | **Status.** Opening sign-up is planned. | |
| 408 | 408 | ||
| 409 | − | ### Fine-grained tokens for workspaces you belong to | |
| 409 | + | ### Tokens for one workspace you belong to | |
| 410 | 410 | ||
| 411 | − | A fine-grained personal access token can name a workspace as its resource | |
| 412 | − | owner only when you are a member of it. For a repository where you are an | |
| 413 | − | outside collaborator, use a classic token. A workspace's | |
| 411 | + | A personal access token can be made for one workspace only when you are a | |
| 412 | + | member of it. For a repository where you are an outside collaborator, make | |
| 413 | + | a token for all your workspaces. A workspace's | |
| 414 | 414 | [rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens) | |
| 415 | 415 | cover personal access tokens only, not applications you signed in to with | |
| 416 | 416 | OAuth. **Status.** Planned. |
| 101 | 101 | on their one repository. What is for people only, such as transferring or | |
| 102 | 102 | deleting a repository, still needs a person. | |
| 103 | 103 | ||
| 104 | − | A [fine-grained personal access token](/guides/authentication/#create-a-fine-grained-token) | |
| 105 | − | has your role only in its resource owner's repositories that it reaches: | |
| 106 | − | all of them, the ones chosen, or none. Everywhere else it reads public | |
| 107 | − | repositories, as anyone can, and does nothing more. A classic token has | |
| 108 | − | your role wherever you have one, unless a workspace's | |
| 104 | + | A [personal access token](/guides/authentication/#where-a-token-reaches) | |
| 105 | + | made for one workspace has your role only in that workspace's repositories | |
| 106 | + | that it reaches: all of them, the ones chosen, or none. Everywhere else it | |
| 107 | + | reads public repositories, as anyone can, and does nothing more. A token | |
| 108 | + | made for all your workspaces has your role wherever you have one, unless a | |
| 109 | + | workspace's | |
| 109 | 110 | [rules for tokens](/guides/authentication/#a-workspaces-rules-for-tokens) | |
| 110 | 111 | keep it out. | |
| 111 | 112 |
| 1208 | 1208 | even with `contents: write`. A push that does is declined, naming the file, | |
| 1209 | 1209 | so a workflow cannot rewrite the workflows that run with its repository's | |
| 1210 | 1210 | secrets. To change workflows from a job, push with a | |
| 1211 | − | [fine-grained token](/guides/authentication/#workflow-files) that has the | |
| 1212 | − | Workflows permission, kept as a secret. | |
| 1211 | + | [personal access token](/guides/authentication/#workflow-files) that has | |
| 1212 | + | Workflow files: write, kept as a secret. | |
| 1213 | 1213 | ||
| 1214 | 1214 | The job's token is the repository's workspace acting with the Write role | |
| 1215 | 1215 | at most, never Admin: it cannot manage webhooks, secrets, deploy keys or who |
| 38 | 38 | | `workspace.ownership_transferred` | An owner handed the workspace to another member. | | |
| 39 | 39 | | `workspace.member_privileges_changed` | An owner turned a [member privilege](/guides/workspaces/#member-privileges) on or off. | | |
| 40 | 40 | | `workspace.two_factor_required`, `workspace.two_factor_not_required` | An owner started or stopped [requiring two-factor authentication](/guides/workspaces/#require-two-factor-authentication). | | |
| 41 | − | | `workspace_token.created`, `workspace_token.deleted` | An owner made or deleted one of the workspace's [access tokens](/guides/workspaces/#workspace-access-tokens). | | |
| 42 | − | | `token.created`, `token.deleted`, `token.rescoped` | A member made, deleted or changed the scopes of one of their own [access tokens](/guides/authentication/#access-tokens). Recorded in each of their workspaces. | | |
| 41 | + | | `workspace_token.created`, `workspace_token.changed`, `workspace_token.deleted` | An owner made, changed the permissions or repositories of, or deleted one of the workspace's [access tokens](/guides/workspaces/#workspace-access-tokens). | | |
| 42 | + | | `token.created`, `token.deleted`, `token.rescoped` | A member made, deleted or changed the permissions or repositories of one of their own [access tokens](/guides/authentication/#access-tokens). Recorded in each of their workspaces. | | |
| 43 | 43 | | `ssh_key.added`, `ssh_key.removed` | A member added or removed an SSH key. Recorded in each of their workspaces. | | |
| 44 | 44 | | `oauth_grant.created`, `oauth_grant.rescoped`, `oauth_grant.revoked` | A member [signed in to an application](/guides/authentication/#signing-in-with-oauth), changed what it may do, or signed it out. Recorded in each of their workspaces. | | |
| 45 | 45 | | `two_factor.enabled`, `two_factor.disabled` | A member turned [two-factor authentication](/guides/authentication/#two-factor-authentication) on or off. Recorded in each of their workspaces. | | |
| 46 | 46 | | `token.policy_changed` | An owner changed the workspace's [rules for personal access tokens](/guides/authentication/#a-workspaces-rules-for-tokens). | | |
| 47 | − | | `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. | | |
| 47 | + | | `token.approval_requested`, `token.approved`, `token.denied` | A member's token made for the workspace asked to reach it, and an owner approved or denied it, with their note. | | |
| 48 | 48 | | `token.revoked` | An owner revoked a member's token in the workspace, with their note. | | |
| 49 | 49 | | `workspace.team_creation_changed` | An owner changed who can create teams. See [who can create teams](/guides/teams/#who-can-create-teams). | | |
| 50 | 50 | | `team.created`, `team.edited`, `team.deleted` | A [team](/guides/teams/) was created, changed or deleted. | |
| 1 | 1 | --- | |
| 2 | 2 | title: Accounts and authentication | |
| 3 | − | description: 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, your security log and deleting your account. | |
| 3 | + | description: Accounts, invites, email addresses, confirming them, two-factor authentication and recovery codes, personal access tokens and their permissions and scopes, a workspace's rules for tokens, OAuth, signing in from a tool, password reset, your security log and deleting your account. | |
| 4 | 4 | --- | |
| 5 | 5 | ||
| 6 | 6 | ## Creating an account | |
| ⋯ | |||
| 8 | 8 | g1t is invite-only for now: to make an account you need an | |
| 9 | 9 | [invite](#invites). Open the link in your invite, or enter its code at | |
| 10 | 10 | [g1t.sh/register](https://g1t.sh/register). Without one, ask for access | |
| 11 | − | on the same page. Usernames are lowercase letters, digits and single | |
| 12 | − | hyphens, up to 39 characters. | |
| 11 | + | on the same page. | |
| 12 | + | ||
| 13 | + | Usernames are letters, digits and single hyphens, 1 to 39 characters, not | |
| 14 | + | starting or ending with a hyphen. They keep the case you type: choose | |
| 15 | + | `Ana-Lopez` and your profile, menus and cards show `Ana-Lopez`. Case never | |
| 16 | + | makes a different name, though: `ana-lopez` is the same person and can't | |
| 17 | + | be registered by anyone else, signing in works in any case, | |
| 18 | + | `g1t.sh/u/ANA-LOPEZ` opens the same profile, and an `@ana-lopez` mention | |
| 19 | + | reaches you. Addresses and git URLs use the lowercase form. Reserved words | |
| 20 | + | (such as `settings`, `api` or `g1t`) are reserved in every case. | |
| 13 | 21 | ||
| 14 | 22 | Before you can do anything else, you [confirm your email | |
| 15 | 23 | address](#confirming-your-email-address) with the code g1t emails you, | |
| ⋯ | |||
| 32 | 40 | | 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). | | |
| 33 | 41 | | Invites to g1t | [`/settings/invites`](https://g1t.sh/settings/invites) | [Making, copying and revoking invites to g1t](#making-invites), while g1t is invite-only; after that, the invites you made. | | |
| 34 | 42 | | 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. | | |
| 35 | − | | Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens): fine-grained and classic. | | |
| 43 | + | | Access tokens | [`/settings/tokens`](https://g1t.sh/settings/tokens) | Your [personal access tokens](#access-tokens): their permissions, where they reach, and when they expire. | | |
| 36 | 44 | | GitHub | [`/settings/github`](https://g1t.sh/settings/github) | [Linking and unlinking GitHub](/guides/github/#link-and-unlink-github). | | |
| 37 | 45 | | 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. | | |
| 38 | 46 | | Two-factor authentication | [`/settings/two-factor`](https://g1t.sh/settings/two-factor) | [An authenticator app and recovery codes](#two-factor-authentication). | | |
| ⋯ | |||
| 580 | 588 | If you lose one, delete it and create another. Delete a token the moment | |
| 581 | 589 | you think someone else has seen it. | |
| 582 | 590 | ||
| 583 | − | There are two kinds of personal access token, on two tabs of | |
| 584 | − | [Settings → Access tokens](https://g1t.sh/settings/tokens): | |
| 591 | + | There is one kind of access token. Every token has: | |
| 585 | 592 | ||
| 586 | − | | | Fine-grained token | Classic token | | |
| 587 | − | | --- | --- | --- | | |
| 588 | − | | 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 | | |
| 589 | − | | Repositories | All of the workspace's, the ones you choose (up to 50), or public ones only | All you can reach | | |
| 590 | − | | What it may do | A level for each [permission](#permissions) | Its [scopes](#scopes) | | |
| 591 | − | | Expires | Always, within 366 days | 7 days to 1 year, or never | | |
| 592 | − | | A workspace can | Require an owner's approval first, or keep them out | Keep them out | | |
| 593 | + | - **Permissions**: a level for each resource, such as Issues: read and | |
| 594 | + | write, or Code: read. See [permissions](#permissions). | |
| 595 | + | - **A reach**: the workspaces and repositories it works in. See | |
| 596 | + | [where a token reaches](#where-a-token-reaches). | |
| 597 | + | - **An expiration**: 7 days to 1 year, or none where the workspaces it | |
| 598 | + | reaches allow that. | |
| 593 | 599 | ||
| 594 | − | Both never do more than you could on the website, and both are sent the | |
| 595 | − | same way. Prefer a fine-grained token: it reaches only what it needs. | |
| 600 | + | It never does more than you could on the website. Your own tokens are | |
| 601 | + | under [Settings → Access tokens](https://g1t.sh/settings/tokens). For CI | |
| 602 | + | and integrations that work for a team, a workspace can have tokens of its | |
| 603 | + | own, made with the same form, that act as the workspace and keep working | |
| 604 | + | when their creator leaves. See [workspace tokens](#workspace-tokens). | |
| 596 | 605 | ||
| 597 | − | For CI and integrations that work for a team, a workspace can have tokens | |
| 598 | − | of its own that act as the workspace and keep working when their creator | |
| 599 | − | leaves. See [workspace tokens](#workspace-tokens). | |
| 606 | + | ### Create a token | |
| 600 | 607 | ||
| 601 | − | ### Create a fine-grained token | |
| 608 | + | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens) and | |
| 609 | + | select **New token**. | |
| 610 | + | 2. Give it a **Token name** after what will use it, and optionally a | |
| 611 | + | **Description**, which a workspace's owners see if they review it. | |
| 612 | + | 3. Choose its **Expiration**: 7, 30, 60, 90 or 180 days, 1 year, or **No | |
| 613 | + | expiration**. A workspace it reaches can set a shorter limit, or forbid | |
| 614 | + | tokens that never expire; the choices follow its rules. No expiration | |
| 615 | + | shows a warning: the token works until someone deletes it. | |
| 616 | + | 4. Under **Where it reaches**, choose **Workspaces**: | |
| 617 | + | - **All your workspaces**: every workspace you belong to, including | |
| 618 | + | ones you join later. | |
| 619 | + | - **One workspace**: then choose its **Repository access**: **All | |
| 620 | + | repositories** (including ones made later), **Only select | |
| 621 | + | repositories** (tick up to 50), or **No private repositories** | |
| 622 | + | (public repositories, read-only, and the workspace's own settings its | |
| 623 | + | permissions allow). | |
| 624 | + | - **No workspace**: your account and public repositories only, such as | |
| 625 | + | a token that reads your inbox. | |
| 626 | + | 5. Under **Permissions**, set each resource the token needs to a level. | |
| 627 | + | **Read only**, **Agent** and **CI** fill in a [preset](#presets); | |
| 628 | + | **Clear** sets everything back to no access. | |
| 629 | + | 6. Select **Generate token**, and copy it. It is not shown again. | |
| 602 | 630 | ||
| 603 | − | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens). The | |
| 604 | − | **Fine-grained tokens** tab is first. | |
| 605 | − | 2. Under **New fine-grained token**, give it a **Token name** after what | |
| 606 | − | will use it, and optionally a **Description**, which a workspace's | |
| 607 | − | owners see if they review it. | |
| 608 | − | 3. Choose the **Resource owner**: a workspace you belong to, or **Your | |
| 609 | − | account**. A workspace that does not allow fine-grained tokens cannot be | |
| 610 | − | chosen. | |
| 611 | − | 4. Choose its **Expiration**: 7, 30, 60, 90 or 180 days, or 1 year, or | |
| 612 | − | less when the workspace sets a shorter limit. | |
| 613 | − | 5. Under **Repository access**, choose **Public repositories** (read-only), | |
| 614 | − | **All repositories** of the workspace (including ones made later), or | |
| 615 | − | **Only select repositories**, and tick up to 50. | |
| 616 | − | 6. Under **Permissions**, set each one the token needs to **Read-only** or | |
| 617 | − | **Read and write** (and **Admin** for packages). **Metadata** is always | |
| 618 | − | read-only. Each row shows the g1t scopes its level gives. | |
| 619 | − | 7. Select **Generate token**, and copy it. It is not shown again. | |
| 631 | + | When you make a token for one workspace that | |
| 632 | + | [requires approval](#a-workspaces-rules-for-tokens), and you are not one of | |
| 633 | + | its owners, the token is made **Pending approval**: it works at once, but | |
| 634 | + | reads public repositories only until an owner approves it. The owners hear | |
| 635 | + | of it in their [inbox](/guides/inbox/), and you hear of their answer in | |
| 636 | + | yours. An owner's own token never waits. | |
| 620 | 637 | ||
| 621 | − | When the workspace [requires approval](#a-workspaces-rules-for-tokens) and | |
| 622 | − | you are not one of its owners, the token is made **Pending approval**: it | |
| 623 | − | works at once, but reads public repositories only until an owner approves | |
| 624 | − | it. The owners hear of it in their [inbox](/guides/inbox/), and you hear of | |
| 625 | − | their answer in yours. An owner's own token never waits. | |
| 638 | + | ### Change or delete a token | |
| 626 | 639 | ||
| 627 | − | Select **Edit** on a token to change its name, description, repositories | |
| 628 | − | or permissions. The token stays the same. Widening it in a workspace that | |
| 629 | − | requires approval asks again. Its resource owner and expiry cannot change; | |
| 630 | − | make a new token instead. | |
| 640 | + | The list under Settings → Access tokens shows each token's name, status | |
| 641 | + | (pending, denied or revoked, with the owner's note), where it reaches, its | |
| 642 | + | permissions, and when it was made, last used and expires. Select a token to | |
| 643 | + | open its page, where you can change its name, description, repositories | |
| 644 | + | and permissions, and select **Save changes**. The token itself stays the | |
| 645 | + | same; the change applies from its next request. Widening a token made for | |
| 646 | + | a workspace that requires approval asks its owners again. Where it reaches | |
| 647 | + | and when it expires cannot change; make a new token instead. | |
| 631 | 648 | ||
| 632 | − | The list shows each token's status (pending, denied or revoked, with the | |
| 633 | − | owner's note), what it reaches, its permissions, and when it was made, last | |
| 634 | − | used and expires. | |
| 649 | + | **Delete token**, at the bottom of its page, stops it working at once. | |
| 635 | 650 | ||
| 636 | 651 | ### Permissions | |
| 637 | 652 | ||
| 638 | − | Each level of a fine-grained token's permissions gives g1t | |
| 639 | − | [scopes](#scopes), and the token is checked by those scopes | |
| 640 | − | exactly as a classic token is. Where two permissions give the same scopes | |
| 641 | − | (Checks and Commit statuses; Secrets and Variables; Deployments and Pages), | |
| 642 | − | giving either gives both. | |
| 653 | + | A permission is a resource and a level. A higher level includes the lower | |
| 654 | + | ones: Issues: read and write includes reading issues. Each level is one of | |
| 655 | + | g1t's [scopes](#scopes), so Issues: read and write is `issues:write`; the | |
| 656 | + | API, the MCP server and git check every token by those scopes. | |
| 643 | 657 | ||
| 644 | − | Repository permissions, for a workspace as the resource owner: | |
| 658 | + | Repository permissions apply in every repository the token reaches: | |
| 645 | 659 | ||
| 646 | − | | Permission | Levels | What it covers | g1t scopes it gives | | |
| 647 | − | | --- | --- | --- | --- | | |
| 648 | − | | `actions` (Actions) | read, write | Workflow runs, jobs, logs and artifacts: reading them, and running, cancelling and rerunning workflows | read: `workflows:read`; write: `workflows:write` | | |
| 649 | − | | `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` | | |
| 650 | − | | `agents` (g1t agents) | write | Putting g1t's agents to work and messaging them, which uses the workspace's money | write: `agents:run` | | |
| 651 | − | | `checks` (Checks) | read, write | Check runs and check suites on commits. Shares its scopes with Commit statuses | read: `checks:read`; write: `checks:write` | | |
| 652 | − | | `contents` (Contents) | read, write | Code, branches, commits and releases: cloning and fetching, pushing, and publishing releases | read: `code:read`; write: `code:write`, `repo:write` | | |
| 653 | − | | `deployments` (Deployments) | read, write | Deployments and their statuses | read: `deployments:read`; write: `deployments:write` | | |
| 654 | − | | `environments` (Environments) | read, write | Environments, and their secrets and variables | read: `deployments:read`, `secrets:read`; write: `secrets:admin` | | |
| 655 | − | | `issues` (Issues) | read, write | Issues, their comments, labels and milestones, and plans | read: `issues:read`; write: `issues:write` | | |
| 656 | − | | `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` | | |
| 657 | − | | `metadata` (Metadata) | read | Seeing repositories and searching them. Always read | read: `repo:read` | | |
| 658 | − | | `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` | | |
| 659 | − | | `pages` (Pages) | read, write | Deployments on g1t.page. Shares its scopes with Deployments | read: `deployments:read`; write: `deployments:write` | | |
| 660 | − | | `pull_requests` (Pull requests) | read, write | Pull requests, their reviews, changes, sessions and merge queues | read: `pull_requests:read`; write: `pull_requests:write` | | |
| 661 | − | | `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` | | |
| 662 | − | | `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` | | |
| 663 | − | | `statuses` (Commit statuses) | read, write | Statuses on commits. Shares its scopes with Checks | read: `checks:read`; write: `checks:write` | | |
| 664 | − | | `variables` (Variables) | read, write | Actions variables: reading, setting and deleting them. Shares its scopes with Secrets | read: `secrets:read`; write: `secrets:admin` | | |
| 665 | − | | `webhooks` (Webhooks) | read, write | Webhooks and their deliveries | read: `webhooks:read`; write: `webhooks:admin` | | |
| 666 | − | | `workflows` (Workflows) | write | Adding, changing and deleting workflow files under .g1t/workflows and .github/workflows. Write only | write: `workflow_files:write` | | |
| 660 | + | | Permission | Levels | Scope names | | |
| 661 | + | | --- | --- | --- | | |
| 662 | + | | Repositories | read, read and write, admin | `repo:read`, `repo:write`, `repo:admin` | | |
| 663 | + | | Code | read, read and write | `code:read`, `code:write` | | |
| 664 | + | | Security | read, read and write | `security:read`, `security:write` | | |
| 665 | + | | Packages | read, read and write, read, write and delete | `packages:read`, `packages:write`, `packages:delete` | | |
| 666 | + | | Issues | read, read and write | `issues:read`, `issues:write` | | |
| 667 | + | | Pull requests | read, read and write | `pull_requests:read`, `pull_requests:write` | | |
| 668 | + | | g1t agents | run | `agents:run` | | |
| 669 | + | | Workflows | read, read and write | `workflows:read`, `workflows:write` | | |
| 670 | + | | Workflow files | write | `workflow_files:write` | | |
| 671 | + | | Checks and statuses | read, read and write | `checks:read`, `checks:write` | | |
| 672 | + | | Deployments | read, read and write | `deployments:read`, `deployments:write` | | |
| 673 | + | | Memory and context | read, read and write | `memory:read`, `memory:write` | | |
| 674 | + | | Who has access | read, admin | `access:read`, `access:admin` | | |
| 675 | + | | Webhooks | read, admin | `webhooks:read`, `webhooks:admin` | | |
| 676 | + | | Secrets and variables | read, admin | `secrets:read`, `secrets:admin` | | |
| 677 | + | ||
| 678 | + | Workspace permissions apply to the workspaces the token reaches themselves: | |
| 679 | + | ||
| 680 | + | | Permission | Levels | Scope names | | |
| 681 | + | | --- | --- | --- | | |
| 682 | + | | Workspaces | read, admin | `workspace:read`, `workspace:admin` | | |
| 683 | + | | Billing | read, read and write | `billing:read`, `billing:write` | | |
| 684 | + | | Self-hosted runners | read, admin | `runners:read`, `runners:admin` | | |
| 685 | + | | AI Gateway | read, read and write | `models:read`, `models:write` | | |
| 667 | 686 | ||
| 668 | − | Workspace permissions, for a workspace as the resource owner: | |
| 687 | + | Account permissions are about you, wherever you are, and only a personal | |
| 688 | + | token can hold them: | |
| 669 | 689 | ||
| 670 | − | | Permission | Levels | What it covers | g1t scopes it gives | | |
| 671 | − | | --- | --- | --- | --- | | |
| 672 | − | | `members` (Members) | read, write | The workspace's people, invitations and teams | read: `workspace:read`; write: `workspace:admin` | | |
| 673 | − | | `workspace_administration` (Administration) | read, write | The workspace's settings, integrations, rulesets and base permission | read: `workspace:read`, `access:read`; write: `workspace:admin`, `access:admin` | | |
| 674 | − | | `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` | | |
| 675 | − | | `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` | | |
| 676 | − | | `self_hosted_runners` (Self-hosted runners) | read, write | Runners, their groups and settings | read: `runners:read`; write: `runners:admin` | | |
| 677 | − | | `workspace_secrets` (Secrets) | read, write | The workspace's Actions secrets. Shares its scopes with the repository Secrets permission | read: `secrets:read`; write: `secrets:admin` | | |
| 678 | − | | `workspace_webhooks` (Webhooks) | read, write | The workspace's webhooks. Shares its scopes with the repository Webhooks permission | read: `webhooks:read`; write: `webhooks:admin` | | |
| 690 | + | | Permission | Levels | Scope names | | |
| 691 | + | | --- | --- | --- | | |
| 692 | + | | Your account | read, read and write | `account:read`, `account:write` | | |
| 693 | + | | Notifications | read, read and write | `notifications:read`, `notifications:write` | | |
| 679 | 694 | ||
| 680 | − | Account permissions, for your own account as the resource owner: | |
| 695 | + | What each level lets a token do is in [scopes](#scopes). On the form, each | |
| 696 | + | row says it for the level chosen, and admin and delete levels are shown in | |
| 697 | + | red: they change things that are hard to undo, or decide who can reach | |
| 698 | + | what. Give them only to something you trust as much as yourself. | |
| 681 | 699 | ||
| 682 | − | | Permission | Levels | What it covers | g1t scopes it gives | | |
| 683 | − | | --- | --- | --- | --- | | |
| 684 | − | | `email_addresses` (Email addresses) | read, write | Your email addresses and email settings, invites and invitations | read: `account:read`; write: `account:write` | | |
| 685 | − | | `starring` (Starring) | read, write | Stars and pinned projects. Shares its scopes with Email addresses | read: `account:read`; write: `account:write` | | |
| 686 | − | | `notifications` (Notifications) | read, write | Your inbox, subscriptions and watched repositories | read: `notifications:read`; write: `notifications:write` | | |
| 700 | + | ### Where a token reaches | |
| 687 | 701 | ||
| 688 | − | ### What a fine-grained token reaches | |
| 702 | + | | Made for | Reaches | | |
| 703 | + | | --- | --- | | |
| 704 | + | | All your workspaces | Every workspace you belong to, and repositories you were given, including ones you join later, unless a workspace's [rules](#a-workspaces-rules-for-tokens) keep it out. | | |
| 705 | + | | One workspace, all repositories | That workspace, and every repository of it you can reach. | | |
| 706 | + | | One workspace, select repositories | That workspace, and only the repositories chosen. | | |
| 707 | + | | One workspace, no private repositories | That workspace's own settings its permissions allow, and public repositories. | | |
| 708 | + | | No workspace | Your account, and public repositories. | | |
| 689 | 709 | ||
| 690 | − | - **In its workspace**, what your role allows, in the repositories it | |
| 691 | − | reaches, and only what its permissions give. | |
| 692 | − | - **Elsewhere**, public repositories, read-only, as anyone can. It cannot | |
| 693 | − | comment, open issues or push there. | |
| 694 | − | - **With your account as its resource owner**, public repositories, | |
| 695 | − | read-only, and what its account permissions give. | |
| 696 | − | - **While pending, denied or revoked**, public repositories, read-only. | |
| 710 | + | Wherever it does not reach, a token reads public repositories, read-only, | |
| 711 | + | as anyone can; it cannot comment, open issues or push there. While a token | |
| 712 | + | made for a workspace is pending, denied or revoked, that is all it does | |
| 713 | + | there too. | |
| 697 | 714 | ||
| 698 | 715 | A request it cannot make answers `403` naming why: the scope it lacks, or | |
| 699 | − | `This fine-grained token's resource owner is the workspace acme: it can only | |
| 700 | − | read public repositories elsewhere, …`. A repository outside its selection | |
| 701 | − | answers as if it did not exist. | |
| 716 | + | `This access token is made for the workspace acme: elsewhere it can only | |
| 717 | + | read public repositories, …`. A repository outside its selection answers as | |
| 718 | + | if it did not exist. | |
| 702 | 719 | ||
| 703 | − | ### Create a classic token | |
| 720 | + | ### Presets | |
| 704 | 721 | ||
| 705 | − | 1. Open [Settings → Access tokens](https://g1t.sh/settings/tokens), and | |
| 706 | − | select the **Tokens (classic)** tab. | |
| 707 | − | 2. Under **New classic token**, give it a **Name** after what will use it. | |
| 708 | − | 3. Choose when it **Expires**: 7 days, 30 days, 90 days (the default), | |
| 709 | − | 1 year, or No expiry. An expired token stops working; make a new one. | |
| 710 | − | No expiry shows a warning: the token works until someone deletes it. | |
| 711 | − | 4. Under **Scopes**, tick the boxes for what it may do. They are grouped | |
| 712 | − | by area. The form starts on the **Agent** [preset](#presets); select | |
| 713 | − | another preset to tick its boxes instead. | |
| 714 | − | 5. Select **Create token**, and copy the token. It is not shown again. | |
| 722 | + | A preset fills in a starting set of permissions. Select one, then change | |
| 723 | + | any row. | |
| 715 | 724 | ||
| 716 | − | The list shows each token's name, when it was made and last used, when it | |
| 717 | − | expires, and its access: a preset's name, its scopes, or Full access. To | |
| 718 | − | change what a token may do, select **Edit access**, tick or untick boxes, | |
| 719 | − | and select **Save access**. The token stays the same; the change applies | |
| 720 | − | from its next request. | |
| 725 | + | | Preset | Permissions | | |
| 726 | + | | --- | --- | | |
| 727 | + | | Read only | Every resource at read. Changes nothing. | | |
| 728 | + | | Agent | Every resource at read except Self-hosted runners, and Code, Issues, Pull requests, Memory and context and Notifications at read and write, and g1t agents at run. Reads everything, works on issues and pull requests, pushes code, puts g1t to work, and answers your inbox. No admin level. | | |
| 729 | + | | CI | Repositories: read; Code, Packages, Workflows, Checks and statuses, and Deployments: read and write. Clones and pushes code, pushes and pulls packages, runs workflows, and reports [checks](/guides/checks/) and deployments. | | |
| 721 | 730 | ||
| 722 | − | A classic token reaches every workspace you belong to unless the | |
| 723 | − | workspace's [rules](#a-workspaces-rules-for-tokens) keep it out: one that | |
| 724 | − | does not allow classic tokens, one whose longest lifetime this token | |
| 725 | − | exceeds, or one whose owner revoked it there. It keeps working everywhere | |
| 726 | − | else. | |
| 731 | + | A new personal token starts on Read only; a new workspace token on CI. | |
| 727 | 732 | ||
| 728 | 733 | ## Scopes | |
| 729 | − | ||
| 730 | − | A scope is a resource and a level, written `resource:level`, such as | |
| 731 | − | `issues:write`. A higher level includes the lower ones of the same | |
| 732 | − | resource: `repo:admin` includes `repo:write`, which includes `repo:read`. | |
| 733 | − | It never includes another resource: `repo:admin` does not let a token push, | |
| 734 | − | which is `code:write`. | |
| 735 | − | ||
| 736 | − | On the form, scopes are a checklist grouped by area: | |
| 737 | 734 | ||
| 738 | − | | Group | Scopes | | |
| 739 | − | | --- | --- | | |
| 740 | − | | Repositories & code | `repo:read`, `repo:write`, `code:read`, `code:write` | | |
| 741 | − | | Packages | `packages:read`, `packages:write` | | |
| 742 | − | | Issues & pull requests | `issues:read`, `issues:write`, `pull_requests:read`, `pull_requests:write` | | |
| 743 | − | | Agents | `agents:run` | | |
| 744 | − | | Workflows | `workflows:read`, `workflows:write`, `workflow_files:write` | | |
| 745 | − | | Checks | `checks:read`, `checks:write` | | |
| 746 | − | | Deployments | `deployments:read`, `deployments:write` | | |
| 747 | − | | Memory & search | `memory:read`, `memory:write` | | |
| 748 | − | | Account | `account:read`, `account:write` | | |
| 749 | − | | Notifications | `notifications:read`, `notifications:write` | | |
| 750 | − | | Security | `security:read`, `security:write` | | |
| 751 | − | | Workspace | `workspace:read`, `access:read`, `webhooks:read`, `secrets:read` | | |
| 752 | − | | Billing | `billing:read`, `billing:write` | | |
| 753 | − | | Runners | `runners:read` | | |
| 754 | − | | AI Gateway | `models:read`, `models:write` | | |
| 755 | − | | Dangerous | `repo:admin`, `packages:delete`, `workspace:admin`, `access:admin`, `webhooks:admin`, `secrets:admin`, `runners:admin` | | |
| 735 | + | A scope is a permission's level, written `resource:level`, such as | |
| 736 | + | `issues:write`. A token stores the highest scope of each resource it | |
| 737 | + | holds, and every check reads them. A higher level includes the lower ones | |
| 738 | + | of the same resource: `repo:admin` includes `repo:write`, which includes | |
| 739 | + | `repo:read`. It never includes another resource: `repo:admin` does not let | |
| 740 | + | a token push, which is `code:write`. | |
| 756 | 741 | ||
| 757 | − | Ticking a higher level ticks the lower ones of its resource and greys | |
| 758 | − | them out: tick `issues:write` and `issues:read` is ticked too. Untick | |
| 759 | − | `issues:write` and `issues:read` stays ticked. | |
| 742 | + | Applications that [sign in with OAuth](#signing-in-with-oauth) ask for | |
| 743 | + | scopes by these names, and you choose them on a checklist when you approve | |
| 744 | + | one. | |
| 760 | 745 | ||
| 761 | 746 | | Scope | What it lets a token do | | |
| 762 | 747 | | --- | --- | | |
| ⋯ | |||
| 777 | 762 | | `agents:run` | Put g1t to work and message it, which uses the workspace's money | | |
| 778 | 763 | | `workflows:read` | Read workflows, runs and logs | | |
| 779 | 764 | | `workflows:write` | Run, cancel, rerun and turn workflows on or off | | |
| 780 | − | | `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. | | |
| 765 | + | | `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. | | |
| 781 | 766 | | `checks:read` | Read commits' statuses, check runs, check suites and annotations | | |
| 782 | 767 | | `checks:write` | Report [statuses and check runs](/guides/checks/) on commits, and ask for checks to run again | | |
| 783 | 768 | | `deployments:read` | See [deployments](/guides/deployments-api/), their statuses and environments | | |
| ⋯ | |||
| 791 | 776 | | `workspace:read` | Read workspace settings, invites, integrations, model routes and [teams](/guides/teams/) | | |
| 792 | 777 | | `workspace:admin` | Create and delete workspaces, invite members, manage teams, connect integrations | | |
| 793 | 778 | | `billing:read` | See a workspace's [usage, budget, AI credit and invoices](/guides/usage-and-billing/) | | |
| 794 | − | | `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. | | |
| 779 | + | | `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. | | |
| 795 | 780 | | `access:read` | See who has access to repositories | | |
| 796 | 781 | | `access:admin` | Give people and teams access to repositories, and take it away | | |
| 797 | 782 | | `webhooks:read` | See webhooks and their deliveries | | |
| ⋯ | |||
| 801 | 786 | | `runners:read` | See [self-hosted runners](/guides/self-hosted-runners/), their groups and where agents run. Not in the Agent preset. | | |
| 802 | 787 | | `runners:admin` | Register and remove self-hosted runners, change their groups and settings | | |
| 803 | 788 | | `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status | | |
| 804 | − | | `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. | | |
| 789 | + | | `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. | | |
| 805 | 790 | ||
| 806 | 791 | Every operation of the API and the MCP server needs exactly one of these, | |
| 807 | 792 | except `whoami` (`GET /user`), which any token may use. Each endpoint's page | |
| 808 | 793 | in the [API reference](/reference/api/) names its scope, and so does each | |
| 809 | − | action in [MCP tools](/reference/mcp/). A few calls need a second scope for | |
| 810 | − | what they ask: | |
| 794 | + | action in [MCP tools](/reference/mcp/); the MCP server lists only the tools | |
| 795 | + | a token's permissions can use. A few calls need a second scope for what | |
| 796 | + | they ask: | |
| 811 | 797 | ||
| 812 | 798 | | Call | Also needs | | |
| 813 | 799 | | --- | --- | | |
| ⋯ | |||
| 820 | 806 | What a request may do is where these overlap: | |
| 821 | 807 | ||
| 822 | 808 | 1. **Your role.** A token never does more than you could on the website. A | |
| 823 | − | token with `repo:admin` still cannot delete a repository unless you are | |
| 824 | − | an owner of its workspace. See [access and roles](/guides/access-and-roles/). | |
| 825 | − | 2. **What it reaches.** A classic token, every workspace and repository you | |
| 826 | − | can reach, including ones you join later, unless a workspace's | |
| 827 | − | [rules](#a-workspaces-rules-for-tokens) keep it out. A fine-grained | |
| 828 | − | token, its [resource owner](#what-a-fine-grained-token-reaches) only. | |
| 829 | − | 3. **Its scopes.** What kinds of thing it may do: chosen directly on a | |
| 830 | − | classic token, given by its permissions on a fine-grained one. | |
| 831 | − | ||
| 832 | − | To keep a token away from other workspaces, make a fine-grained one, or use | |
| 833 | − | a [workspace token](#workspace-tokens): it reaches only its own workspace. | |
| 834 | − | ||
| 835 | − | ### Presets | |
| 836 | − | ||
| 837 | − | A preset ticks a starting set of boxes. Select one, then tick or untick | |
| 838 | − | any box. | |
| 839 | − | ||
| 840 | − | | Preset | Scopes | | |
| 841 | − | | --- | --- | | |
| 842 | − | | Read only | Every `read` scope. Changes nothing. | | |
| 843 | − | | 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. | | |
| 844 | − | | 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. | | |
| 845 | − | | Full access | Everything you can do, including deleting repositories and changing who has access. Marked **Dangerous**. | | |
| 846 | − | ||
| 847 | − | Admin scopes change things that are hard to undo, or decide who can reach | |
| 848 | − | what. They are under **Dangerous**, with a warning. Give them only to | |
| 849 | − | something you trust as much as yourself. | |
| 809 | + | token with Repositories: admin still cannot delete a repository unless | |
| 810 | + | you are an owner of its workspace. See | |
| 811 | + | [access and roles](/guides/access-and-roles/). | |
| 812 | + | 2. **Where it reaches.** All your workspaces, one, or none, and in one, its | |
| 813 | + | repositories. See [where a token reaches](#where-a-token-reaches). | |
| 814 | + | 3. **Its permissions.** What kinds of thing it may do there. | |
| 850 | 815 | ||
| 851 | 816 | ### Git and scopes | |
| 852 | 817 | ||
| ⋯ | |||
| 854 | 819 | ||
| 855 | 820 | | To | Needs | | |
| 856 | 821 | | --- | --- | | |
| 857 | − | | Clone or fetch a public repository | No scope | | |
| 858 | − | | Clone or fetch a private repository | `code:read` | | |
| 859 | − | | Push | `code:write` | | |
| 860 | − | | Push commits that add, change or delete [workflow files](#workflow-files) | `code:write` and `workflow_files:write` | | |
| 822 | + | | Clone or fetch a public repository | No permission | | |
| 823 | + | | Clone or fetch a private repository | Code: read (`code:read`) | | |
| 824 | + | | Push | Code: read and write (`code:write`) | | |
| 825 | + | | Push commits that add, change or delete [workflow files](#workflow-files) | Code: read and write, and Workflow files: write (`workflow_files:write`) | | |
| 861 | 826 | ||
| 862 | 827 | Your role on the repository applies too, as on the website. A refused push | |
| 863 | 828 | or clone says which scope is missing. | |
| ⋯ | |||
| 866 | 831 | ||
| 867 | 832 | A workflow runs with its repository's secrets and a token of its own, so | |
| 868 | 833 | changing one is as powerful as holding those. A token therefore needs | |
| 869 | − | `workflow_files:write` (a fine-grained token's **Workflows** permission) to | |
| 870 | − | add, change or delete any file under `.g1t/workflows/` or | |
| 871 | − | `.github/workflows/`, besides `code:write`: | |
| 834 | + | Workflow files: write (`workflow_files:write`) to add, change or delete any | |
| 835 | + | file under `.g1t/workflows/` or `.github/workflows/`, besides Code: read | |
| 836 | + | and write: | |
| 872 | 837 | ||
| 873 | 838 | - **With git**, every commit a push adds is compared with its parent, and a | |
| 874 | 839 | push that changes a workflow file is declined, naming it: | |
| ⋯ | |||
| 886 | 851 | See [the job's token](/guides/actions/#the-jobs-token). | |
| 887 | 852 | - **Signed in on g1t.sh**, your role decides, as for any file. | |
| 888 | 853 | ||
| 889 | − | Full-access tokens, and tokens made before scopes, include it. A | |
| 890 | − | [deploy key](/guides/git/#deploy-keys) with write access may change | |
| 854 | + | A [deploy key](/guides/git/#deploy-keys) with write access may change | |
| 891 | 855 | workflow files. | |
| 892 | 856 | ||
| 893 | 857 | ### When a token lacks a scope | |
| ⋯ | |||
| 905 | 869 | ``` | |
| 906 | 870 | ||
| 907 | 871 | Through MCP the same message comes back as a tool result with `isError` | |
| 908 | − | set. Give the token that scope with **Edit access**, or make a new token. | |
| 872 | + | set. Give the token that permission on its page, or make a new token. | |
| 909 | 873 | ||
| 910 | − | ### Tokens made before scopes | |
| 874 | + | ### Tokens made before | |
| 911 | 875 | ||
| 912 | − | Tokens and OAuth sign-ins made before tokens had scopes keep full access, | |
| 913 | − | so nothing that uses them stops working. Settings marks each one | |
| 914 | − | **Legacy · full access**, and says to narrow it to what it needs. For a | |
| 915 | − | token, select **Narrow this token**; for an application, **Change access** | |
| 916 | − | in [Connected applications](https://g1t.sh/settings/applications). Then | |
| 917 | − | tick its scopes. A token you make with Full access on purpose is not marked | |
| 918 | − | legacy. | |
| 876 | + | Tokens once came in two kinds, with scopes or with permissions for one | |
| 877 | + | workspace. Every one of them is now a token like any other, and does | |
| 878 | + | exactly what it did: | |
| 919 | 879 | ||
| 920 | − | A token from [signing in from a tool](#signing-in-from-a-tool), such as the | |
| 921 | − | g1t CLI, has full access. | |
| 880 | + | - A token made with scopes is made for **all your workspaces**, with the | |
| 881 | + | permissions its scopes were. | |
| 882 | + | - A token made for one workspace (or for your account only) is made for | |
| 883 | + | that workspace (or for **No workspace**), with the repositories it had, | |
| 884 | + | and with permissions that are the scopes its old permissions gave. | |
| 885 | + | - A token with full access, including one made before tokens had scopes and | |
| 886 | + | one from [signing in from a tool](#signing-in-from-a-tool) such as the | |
| 887 | + | g1t CLI, has every permission at its highest level. Narrow it on its page | |
| 888 | + | to what it needs. | |
| 922 | 889 | ||
| 890 | + | An application signed in with OAuth before applications had scopes keeps | |
| 891 | + | full access too, marked **Legacy · full access**: select **Change access** | |
| 892 | + | in [Connected applications](https://g1t.sh/settings/applications) to narrow | |
| 893 | + | it. | |
| 894 | + | ||
| 895 | + | The old addresses of the token settings lead to the list and to each | |
| 896 | + | token's page. | |
| 897 | + | ||
| 923 | 898 | ### Workspace tokens | |
| 924 | 899 | ||
| 925 | 900 | A workspace's own tokens act as the workspace rather than a person. An | |
| 926 | − | owner makes them in the workspace's **Settings → Access tokens**, with the | |
| 927 | − | same checklist and expiry choices; the form starts on the CI preset. A | |
| 928 | − | workspace token reaches all of that workspace's repositories, never | |
| 929 | − | another workspace, and cannot manage people, tokens or workspaces. | |
| 901 | + | owner makes them in the workspace's **Settings → Access tokens** | |
| 902 | + | (`g1t.sh/<workspace>/-/tokens`), with **New token**: the same form as a | |
| 903 | + | personal token, starting on the CI preset. A workspace token reaches all | |
| 904 | + | of that workspace's repositories, or the ones chosen, never another | |
| 905 | + | workspace, and cannot manage people, tokens or workspaces. It holds no | |
| 906 | + | account permissions. | |
| 930 | 907 | ||
| 931 | 908 | It has the Write role on the workspace's repositories, as a member does: | |
| 932 | − | it pushes, merges and works on issues and pull requests, within its scopes. | |
| 933 | − | Tick **Admin on the workspace's repositories** when making it to give it | |
| 934 | − | Admin instead, so it can also manage webhooks, secrets, deploy keys and who | |
| 935 | − | has access, and manage teams as an owner would. Only an owner can, and only | |
| 936 | − | when making it. See | |
| 909 | + | it pushes, merges and works on issues and pull requests, within its | |
| 910 | + | permissions. Give it **Repositories: admin** to make it an admin of the | |
| 911 | + | workspace's repositories instead, so it can also manage webhooks, secrets, | |
| 912 | + | deploy keys and who has access, and manage teams as an owner would. Only an | |
| 913 | + | owner can make, change or delete one. See | |
| 937 | 914 | [workspace access tokens](/guides/workspaces/#workspace-access-tokens). | |
| 938 | 915 | ||
| 939 | 916 | ## A workspace's rules for tokens | |
| ⋯ | |||
| 947 | 924 | ||
| 948 | 925 | | Rule | Default | What it does | | |
| 949 | 926 | | --- | --- | --- | | |
| 950 | − | | 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. | | |
| 951 | − | | 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. | | |
| 952 | − | | Allow classic personal access tokens | On | Off: classic tokens no longer reach the workspace. | | |
| 927 | + | | Allow tokens made for the workspace | On | Off: no token can be made for the workspace alone, and existing ones stop reaching it. | | |
| 928 | + | | Require approval of tokens made for the workspace | On | A member's token made for the workspace waits for an owner's approval, and again when it is widened. Owners' own tokens never wait. | | |
| 929 | + | | Allow tokens made for all of a member's workspaces | On | Off: tokens made for all of their owner's workspaces no longer reach this one; members make a token for it alone instead, which the rule above can require approval for. | | |
| 953 | 930 | | Tokens must expire | Off | On: a token that never expires does not reach the workspace. | | |
| 954 | − | | 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. | | |
| 931 | + | | Longest lifetime | No limit | A token that lasts longer (from when it was made to when it expires), or never expires, does not reach the workspace. Tokens for it cannot be made longer. | | |
| 955 | 932 | ||
| 956 | 933 | The same page lists: | |
| 957 | 934 | ||
| 958 | − | - **Waiting for approval.** Each pending fine-grained token with its owner, | |
| 935 | + | - **Waiting for approval.** Each pending token with its owner, | |
| 959 | 936 | permissions, repositories and expiry. Add an optional note, then select | |
| 960 | 937 | **Approve** or **Deny**. Its owner hears of it in their inbox, with the | |
| 961 | 938 | note. | |
| 962 | − | - **Tokens that can reach the workspace.** Every fine-grained token naming | |
| 963 | − | it, and every classic token of its members and outside collaborators that | |
| 964 | − | has not expired, with its owner, permissions or scopes, last use and | |
| 965 | − | expiry, and whether it reaches the workspace now (and if not, why). Never | |
| 966 | − | the token itself. Select **Revoke** to take one out: a fine-grained token | |
| 967 | − | stops reaching the workspace for good; a classic token keeps working | |
| 968 | − | everywhere else, but never reaches this workspace again. | |
| 939 | + | - **Tokens that can reach the workspace.** Every token made for it, and | |
| 940 | + | every token of its members and outside collaborators made for all of | |
| 941 | + | their workspaces, that has not expired, with its owner, permissions, | |
| 942 | + | reach, last use and expiry, and whether it reaches the workspace now (and | |
| 943 | + | if not, why). Never the token itself. Select **Revoke** to take one out: | |
| 944 | + | a token made for the workspace stops reaching it for good; a token made | |
| 945 | + | for all of its owner's workspaces keeps working everywhere else, but | |
| 946 | + | never reaches this workspace again. | |
| 969 | 947 | ||
| 970 | 948 | Approvals, denials, revocations and rule changes are | |
| 971 | 949 | [audit log](/guides/audit-log/) entries: `token.approval_requested`, | |
| ⋯ | |||
| 974 | 952 | ||
| 975 | 953 | ### A workspace's rules through the API | |
| 976 | 954 | ||
| 977 | − | Owners, as people (a personal token with the scope works; a workspace's own | |
| 978 | − | token does not): | |
| 955 | + | Owners, as people (a personal token with the permission works; a | |
| 956 | + | workspace's own token does not): | |
| 979 | 957 | ||
| 980 | 958 | | Route | MCP tool and action | What it does | Scope | | |
| 981 | 959 | | --- | --- | --- | --- | | |
| 982 | 960 | | [`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` | | |
| 983 | − | | [`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` | | |
| 984 | − | | [`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` | | |
| 985 | − | | [`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` | | |
| 961 | + | | [`PATCH /workspaces/{workspace}/personal-access-token-policy`](/reference/api/personal-access-tokens/set-token-policy/) | `workspace` `set_token_policy` | Change `allow_tokens_for_this_workspace`, `allow_tokens_for_all_workspaces`, `require_approval`, `max_lifetime_days` (0 for no limit) or `forbid_no_expiry` | `workspace:admin` | | |
| 962 | + | | [`GET /workspaces/{workspace}/personal-access-tokens`](/reference/api/personal-access-tokens/list-member-tokens/) | `workspace` `list_member_tokens` | The tokens that can reach it, each with its `permissions` (`{"issues": "write"}`), `scopes`, `workspace` (null when made for all of its owner's), `repository_selection`, `repositories` and `status` | `access:read` | | |
| 963 | + | | [`GET /workspaces/{workspace}/personal-access-token-requests`](/reference/api/personal-access-tokens/list-token-requests/) | `workspace` `list_token_requests` | The tokens waiting for approval | `access:read` | | |
| 986 | 964 | | [`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` | | |
| 987 | 965 | | [`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` | | |
| 988 | 966 | ||
| ⋯ | |||
| 1072 | 1050 | ||
| 1073 | 1051 | Only approve a code you asked for. The token has full access: it can do | |
| 1074 | 1052 | everything you can. To give a tool less, make an | |
| 1075 | − | [access token](#create-a-fine-grained-token) with only the scopes it needs instead. | |
| 1053 | + | [access token](#create-a-token) with only the scopes it needs instead. | |
| 1076 | 1054 | ||
| 1077 | 1055 | ## Resetting your password | |
| 1078 | 1056 | ||
| ⋯ | |||
| 1168 | 1146 | | | | | |
| 1169 | 1147 | | --- | --- | | |
| 1170 | 1148 | | Signing in | You are signed out everywhere. Signing in with your password, GitHub, a recovery code or from a tool fails, with the same answer a wrong password gets. | | |
| 1171 | − | | Access tokens, SSH keys and applications | Your personal access tokens (classic and fine-grained), SSH keys, connected applications and sign-ins from a tool stop working and are removed, and so do the deploy keys you added to repositories. A workspace's own tokens are not affected, even ones you made. | | |
| 1149 | + | | Access tokens, SSH keys and applications | Your personal access tokens, SSH keys, connected applications and sign-ins from a tool stop working and are removed, and so do the deploy keys you added to repositories. A workspace's own tokens are not affected, even ones you made. | | |
| 1172 | 1150 | | Workspaces, teams and repositories | You leave every workspace and team, and lose the roles you were given on single repositories. Repository invitations waiting for you are withdrawn, and invites you made that nobody used are revoked. | | |
| 1173 | 1151 | | Your profile | `g1t.sh/<username>` answers 404, and you drop out of search. Nobody can add you to a workspace, team or repository, and nothing more is emailed to you. | | |
| 1174 | 1152 | | What you wrote | Stays where it is, under your username for now. Commits made with your confirmed or noreply addresses show as `ghost`, and as yours again if your account is restored. | | |
| 1 | 1 | --- | |
| 2 | 2 | title: Chat | |
| 3 | − | description: Talk to your team and your agents in channels, direct messages and threads, live. Mention an agent and it answers in the thread. React, add your workspace's own emoji, and choose what notifies you. | |
| 3 | + | description: Talk to your team and your agents in channels, direct messages and threads, live. Mention an agent and it answers in the thread. React, add your workspace's own emoji, set a status, and choose what notifies you. | |
| 4 | 4 | --- | |
| 5 | 5 | ||
| 6 | 6 | import { Steps } from '@astrojs/starlight/components'; | |
| ⋯ | |||
| 342 | 342 | Changing a setting doesn't change what already exists: channels already | |
| 343 | 343 | made stay, whoever made them. | |
| 344 | 344 | ||
| 345 | + | ## Presence and status | |
| 346 | + | ||
| 347 | + | Everyone you share a workspace with can see whether you're here, and what | |
| 348 | + | you've said about yourself, wherever your name shows: beside a direct | |
| 349 | + | message in the sidebar, on the card over your name, in a channel's member | |
| 350 | + | list, on the workspace's People page and after your name on your messages. | |
| 351 | + | It all moves live; nobody has to reload. | |
| 352 | + | ||
| 353 | + | | The dot on an avatar | It means | | |
| 354 | + | | --- | --- | | |
| 355 | + | | Green | **Active**: g1t is open and they've used it in the last 10 minutes. | | |
| 356 | + | | A ring | **Away**: every tab they have open has sat untouched for 10 minutes, or they set themselves away. | | |
| 357 | + | | Amber, with a bar | **Notifications paused**: they're here, but nothing pops up for them until the time they chose. | | |
| 358 | + | | None | **Offline**: no tab of g1t is open. | | |
| 359 | + | ||
| 360 | + | Agents have dots of their own, which say what they're doing (idle, | |
| 361 | + | working, out of budget), not whether they're here. | |
| 362 | + | ||
| 363 | + | ### Set a status | |
| 364 | + | ||
| 365 | + | Open the menu on your avatar at the bottom of the rail (on a phone, the | |
| 366 | + | workspace avatar at the top left) and choose **Set a status**. Give it an | |
| 367 | + | emoji and a few words, or pick one: | |
| 368 | + | ||
| 369 | + | | | Clears after | | |
| 370 | + | | --- | --- | | |
| 371 | + | | 🗓️ In a meeting | 1 hour | | |
| 372 | + | | 🚌 Commuting | 30 minutes | | |
| 373 | + | | 🎯 Focusing | 1 hour | | |
| 374 | + | | 🤒 Out sick | Today | | |
| 375 | + | | 🌴 On vacation | Never: it stays until you change it | | |
| 376 | + | ||
| 377 | + | **Clear after** can be 30 minutes, 1 hour, 4 hours, today (your midnight), | |
| 378 | + | this week (the end of your Sunday), never, or a time you choose. When the | |
| 379 | + | time comes your status goes, for everyone at once, whether or not you're | |
| 380 | + | online. Clear it sooner with **Clear status** in the same menu. | |
| 381 | + | ||
| 382 | + | ### Away | |
| 383 | + | ||
| 384 | + | Your dot turns to a ring by itself after 10 minutes without using g1t, and | |
| 385 | + | back to green as soon as you do. **Set yourself away** keeps you away | |
| 386 | + | however much you use it, until you choose **Set yourself active**. | |
| 387 | + | ||
| 388 | + | ### Statuses from other apps | |
| 389 | + | ||
| 390 | + | A status has a source: you, a calendar, or another integration. Calendar | |
| 391 | + | and integration statuses (such as "In a meeting" while one is on your | |
| 392 | + | calendar) are coming with those integrations. One you set yourself always | |
| 393 | + | wins: a calendar never replaces or clears it. <Soon /> | |
| 394 | + | ||
| 345 | 395 | ## Notifications | |
| 346 | 396 | ||
| 347 | 397 | g1t tells you when something is for you, wherever you are in the app. | |
| ⋯ | |||
| 367 | 417 | such as **Everything** for a small team and **DMs and mentions** for a big | |
| 368 | 418 | one. **Send a test notification** shows you what one looks like. | |
| 369 | 419 | ||
| 420 | + | ### Pause notifications | |
| 421 | + | ||
| 422 | + | From the menu on your avatar, **Pause notifications** for 30 minutes, an | |
| 423 | + | hour, or until tomorrow morning (9:00 your time). Until then nothing pops | |
| 424 | + | up and no browser notification is sent, whatever your settings; counts and | |
| 425 | + | your inbox still update, and everyone sees your amber dot. **Resume | |
| 426 | + | notifications** ends it early. | |
| 427 | + | ||
| 370 | 428 | [Your inbox](/guides/inbox/) is separate: it keeps every item until you | |
| 371 | 429 | deal with it, whatever these settings say. | |
| 372 | 430 | ||
| 17 | 17 | ||
| 18 | 18 | The first time, g1t makes your account: | |
| 19 | 19 | ||
| 20 | − | - **Username**: your GitHub login, lowercased, if it is free and follows | |
| 21 | − | g1t's rules (lowercase letters, digits and single hyphens, up to 39 | |
| 22 | − | characters). Otherwise you choose one. | |
| 20 | + | - **Username**: your GitHub login, in its own case, if it is free in any | |
| 21 | + | case and follows g1t's rules (letters, digits and single hyphens, up to | |
| 22 | + | 39 characters; see [creating an account](/guides/authentication/#creating-an-account)). | |
| 23 | + | Otherwise you choose one. | |
| 23 | 24 | - **Email**: the primary address on your GitHub account, if GitHub says it | |
| 24 | 25 | is verified. Only verified addresses count, and GitHub's | |
| 25 | 26 | `@users.noreply.github.com` relay addresses are not used. Your email is |
| 44 | 44 | | Reason | Shown as | Why you were told | | |
| 45 | 45 | | --- | --- | --- | | |
| 46 | 46 | | `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, 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). | | |
| 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 token made for the workspace waiting for [approval](/guides/authentication/#a-workspaces-rules-for-tokens) (in the inbox only, never emailed). | | |
| 48 | 48 | | `assign` | assigned | You were assigned, or you are an assignee. | | |
| 49 | 49 | | `mention` | mentioned | Someone mentioned you with `@username`, or you were mentioned on it before. | | |
| 50 | 50 | | `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. | | |
| 51 | 51 | | `ci_activity` | CI activity | A check, workflow or deployment on your work finished badly, or recovered. | | |
| 52 | 52 | | `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. | | |
| 53 | 53 | | `state_change` | state changed | It was closed, reopened or merged. | | |
| 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. | | |
| 54 | + | | `author` | your work | You opened it, or you asked g1t for it. Also an owner's answer to your [token made for a workspace](/guides/authentication/#create-a-token) waiting for approval, or its revocation. | | |
| 55 | 55 | | `comment` | commented | You commented on it. | | |
| 56 | 56 | | `manual` | subscribed | You subscribed to it yourself. | | |
| 57 | 57 | | `subscribed` | watching | You watch its repository. | |
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
Binary or large file; its contents are not shown.
This change is too large to show in full.