From c4bc4b68bf527e85ab683b36f1617ee034c031a3 Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 8 Sep 2026 14:12:53 +0000 Subject: [PATCH] docs: describe the redesigned api keys page --- docs/reference/api-tokens.md | 80 +++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/docs/reference/api-tokens.md b/docs/reference/api-tokens.md index 6d4af65..401dead 100644 --- a/docs/reference/api-tokens.md +++ b/docs/reference/api-tokens.md @@ -11,9 +11,28 @@ needs something it can hold onto instead — an API token. **API Keys**, in the Access group of the sidebar. The page is reachable at every role: any member may create and revoke their own keys, and owner and -admin additionally see every key in the instance. Give it a name, a role -(owner, admin or member) and one or more scopes, and optionally an expiry. The value is shown -once, in full, immediately after creation: +admin additionally see every key in the instance. + +**Create key** opens a dialog with four decisions, in the order they matter: + +1. **Name and role.** The name says what will use the key — the CI pipeline, + the script, the cluster. The role list offers your own role and everything + below it, never above. +2. **Scopes.** A grid of resources against read and write. Ticking write also + ticks read, since write already satisfies read on the same resource. + **Read-only everywhere** and **Clear all** set the whole grid at once. +3. **Restrict to servers tagged.** Optional; see [Tag + restrictions](#tag-restrictions) below. +4. **Expiry.** Each option names the date it resolves to, so "90 days" and + "7 December 2026" are the same choice read two ways. + +Beneath them sits a preview line that reads the key back as a sentence — +*"gitea-ci-deploy acts as admin, may read and write servers and workflows, +read secrets, and stops working on 7 December 2026."* Read it before you +submit; an over-granted key is far easier to spot in a sentence than in a grid +of ticks. + +The value is shown once, in full, immediately after creation: ``` vt_8f2c1a9e4b6d0735a1c8e29f4b0d6e17... @@ -23,10 +42,14 @@ That is the only time you will see it. Vantage stores a hash of the token, never the value itself, so if you lose it there is no support ticket that gets it back — create a new token and revoke the old one. +The panel showing it also carries a ready-made `curl` line and a summary of +what was granted, so the key can go straight into a secret store without a +second trip to the list. + ## Scopes -A token can reach only what its scopes name. There are eight resources, each -with a `:read` and a `:write` scope, and holding `:write` on a resource also +A token can reach only what its scopes name. Each resource has +a `:read` and a `:write` scope, and holding `:write` on a resource also satisfies a `:read` requirement for it — you do not need to tick both. | Resource | Covers | @@ -44,6 +67,53 @@ A token created with only `servers:read` can list and inspect servers but cannot run a workflow against them, touch a key, or read a secret — each of those needs its own scope. +## Tag restrictions + +A key can be pinned to part of the fleet as well as part of the API. **Restrict +to servers tagged** in the create dialog offers the tag keys and values already +in use across your servers, and the key then reaches only servers carrying +**every** pair listed — the restriction is an AND, not an OR. Leaving it empty +is the opposite: no restriction at all, the whole fleet. + +The restriction is fixed at creation, like the role and the scopes. Changing +what a credential already deployed in CI can reach, with no record of what it +could reach before, is worse than requiring a rotation — so to widen or narrow +one, create a replacement and revoke the old key. + +Restricted keys show their tags as chips beside their scopes in the list. +Unrestricted keys show nothing there, which is the common case. + +## Reading the key list + +Each key is one record rather than a row of bare strings: + +- **Key** — the name, the `vt_` prefix hint, the holder (when viewing all + keys) and the role. +- **Scopes** — one chip per resource, its access half tinted: `rw` in accent, + `r` in grey. A key with nothing granted says so in words rather than showing + a dash. +- **Lifetime** — a bar showing how much of the key's issued life is left, + with the date beside it. Four states, and the label always says which: + + | Bar | Means | + | --- | ----- | + | Green | More than seven days left | + | Amber | Seven days or fewer — rotate it | + | Red | Already expired; the key no longer authenticates | + | Grey, full width | No expiry at all | + + A key issued before the instance's maximum lifetime was tightened also + carries *"outside the current policy — rotate when convenient"*. That is a + prompt, not a failure: the cap is never applied retroactively and the key + keeps working. + +- **Last call** — when the key last authenticated, or *Never used*. + +Above the list, four counts summarise the same thing at fleet scale: keys +listed, keys expiring within seven days, keys that never expire, and keys +never used since they were issued. They describe the list as filtered, so they +change with the **My keys** / **All keys** toggle. + ## A token never outranks its owner A token's role can be at most the role of the person who created it, and its