diff --git a/docs/reference/api-tokens.md b/docs/reference/api-tokens.md new file mode 100644 index 0000000..d587def --- /dev/null +++ b/docs/reference/api-tokens.md @@ -0,0 +1,108 @@ +--- +id: api-tokens +title: API tokens +sidebar_label: API tokens +--- + +A session cookie is fine for a browser. A script, a CI job or a cron task +needs something it can hold onto instead — an API token. + +## Creating one + +Settings → **Access** → API tokens. 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: + +``` +vt_8f2c1a9e4b6d0735a1c8e29f4b0d6e17... +``` + +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. + +## 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 +satisfies a `:read` requirement for it — you do not need to tick both. + +| Resource | Covers | +| ----------- | --------------------------------------------------- | +| `servers` | Fleet list, server detail, agent commands, tags | +| `keys` | SSH key library and assignment | +| `secrets` | The vault | +| `workflows` | Steps, workflows, runs and their logs | +| `monitors` | Monitors, incidents, uptime and notification channels | +| `vulns` | Vulnerability findings, packages and scan rules | +| `workloads` | Containers and systemd units, including control actions and logs | +| `settings` | Instance settings, members, single sign-on, licence, and token management itself | + +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. + +## A token never outranks its owner + +A token's role can be at most the role of the person who created it, and its +effective role is **recomputed on every request** as the lower of the two — +not fixed at creation. Demote the person from owner to member and every token +they hold drops to member from that request onward. Remove the person and +every token they hold stops working immediately: a token has no existence +independent of its owner. + +## Expiry + +An expiry is optional on a token you create. An instance can set a +**maximum token lifetime** (Settings → Access) that caps how far out a new +token's expiry may be set; when that cap is in place, a token with no expiry +at all is refused, so there is no way to route around the policy by leaving +the field blank. + +Changing the maximum lifetime only affects tokens created afterwards. It does +not shorten, extend or invalidate a token that already exists. + +## Using a token + +Send it as a bearer token: + +```bash +curl -H "Authorization: Bearer vt_…" https://acme.vantage.example.com/api/servers +``` + +Everything else about the [REST API](./rest-api.md) applies the same way it +does to a session — JSON errors, audit logging, licence gating on writes — +except that authority comes from the token's role and scopes rather than a +signed-in person's role. + +## Rate limit + +A token is limited to **600 requests per minute**. Going over it gets a `429` +with a `Retry-After` header naming how many seconds to wait. Cookie sessions +are not subject to this limit; it exists so a runaway script cannot take an +instance down, not as a general throttle. + +## Rotating a token + +1. Create the replacement token first, with the scopes and role you need. +2. Deploy it wherever the old one was used, and confirm it works. +3. Revoke the old one. + +Doing it in that order means there is no gap where the credential in use has +already been deleted. + +## The full reference + +This page covers the token model. Every route, request and response shape is +in the generated OpenAPI reference, served by **your own instance** at +`/api/docs` — not this documentation site, since the routes and their shapes +are specific to your install. The raw document is at `/api/openapi.json`. + +:::danger Not the External Secrets token +The bearer token read by `GET /api/secrets/:group/values` for the Kubernetes +External Secrets Operator is a **separate credential** — a single instance-wide +value, rotated from Settings, that reaches only that one endpoint. It is not an +API token and an API token cannot be used in its place: the two are checked by +different code, and neither substitutes for the other. See +[Secrets](../vantage/secrets.md#kubernetes-external-secrets-operator). +::: diff --git a/sidebars.ts b/sidebars.ts index 6ecaaff..e005805 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -43,7 +43,7 @@ const sidebars: SidebarsConfig = { { type: "category", label: "Reference", - items: ["reference/environment-variables", "reference/rest-api", "reference/agent-config", "reference/ports-and-networking", "reference/troubleshooting"], + items: ["reference/environment-variables", "reference/rest-api", "reference/api-tokens", "reference/agent-config", "reference/ports-and-networking", "reference/troubleshooting"], }, { type: "category",