Access Tokens & Capabilities
Access tokens authenticate the CLI, Terraform, and API requests as a Bearer token. Every token carries a set of capabilities that bound what it can do. The stategraph user access-tokens commands let you mint, list, and revoke capability-scoped tokens directly from the CLI using an existing API key — no browser session required.
This is the recommended way to issue least-privilege credentials: a token can be limited to, for example, applying changes to a single state while being unable to manage users or create further tokens.
Capability Model
A token's capabilities are a subset of the capabilities held by the session that created it. A token can never exceed its creator.
| Capability | Grants | Scope |
|---|---|---|
admin |
Full access. Installation-wide when it names no tenants ({}); scoped to specific tenants when it does ({"tenants": [...]}). See Tenants and Administration. |
Installation-wide or per-tenant |
plan |
Plan changes through transactions. | Per-tenant, per-state, and per-subgraph |
apply |
Apply changes through transactions. | Per-tenant, per-state, and per-subgraph |
users-manage |
Create, update, and delete users, and reset the passwords of users holding less authority. Never grants admin. See Who can act on whom. |
Installation-wide or per-tenant |
sudo |
Act on behalf of specific users. | Per-user |
access-token-create |
Issue new access tokens. | Global |
access-token-refresh |
Refresh existing access tokens. | Global |
When no capability flags are given, the token inherits the creating session's capabilities — the least-surprising default for "give me a token that can do what I can do."
In the raw capabilities JSON — what --capabilities-json accepts and what stategraph user whoami --format json returns — the plan and apply capabilities appear under their internal keys preview and commit respectively. The CLI flags and table output use plan and apply.
stategraph user access-tokens create
Create an access token for the current user.
stategraph user access-tokens create --name <name> [capability flags]
The --name flag is required. The capability flags below select and scope what the token may do:
| Flag | Description |
|---|---|
--admin |
Grant the admin capability, over the whole installation unless --admin-tenant is given. |
--admin-tenant <TENANT> |
Restrict admin to these tenants (repeatable). |
--plan |
Grant plan; unrestricted unless scoped with --plan-tenant, --plan-modified, or --plan-pulled-in. |
--plan-tenant <TENANT> |
Restrict plan to these tenants (repeatable). |
--plan-modified <STATE_ID=PATTERN> |
Restrict plan to the directly modified resources in a state that match PATTERN (repeatable). |
--plan-pulled-in <STATE_ID=PATTERN> |
Restrict what plan may pull in: the resources pulled in as cone/blast dependencies in that state must match PATTERN (repeatable). |
--apply |
Grant apply; unrestricted unless scoped with --apply-tenant, --apply-modified, or --apply-pulled-in. |
--apply-tenant <TENANT> |
Restrict apply to these tenants (repeatable). |
--apply-modified <STATE_ID=PATTERN> |
Restrict apply to the directly modified resources in a state that match PATTERN (repeatable). |
--apply-pulled-in <STATE_ID=PATTERN> |
Restrict what apply may pull in: the resources pulled in as cone/blast dependencies in that state must match PATTERN (repeatable). |
--users-manage |
Grant users-manage; unrestricted unless scoped with --users-manage-tenant. |
--users-manage-tenant <TENANT> |
Restrict users-manage to these tenants (repeatable). |
--sudo-user <USER> |
Grant sudo over these users (repeatable). |
--access-token-create |
Grant the access-token-create capability. |
--access-token-refresh |
Grant the access-token-refresh capability. |
--capabilities-json <json> |
Raw capabilities JSON object. Mutually exclusive with the individual capability flags above. |
Tenant and user values are rules: a tenant id (or a user), or a prefix ending in * (* alone matches everything); the most specific value that matches decides, and a leading ! refuses. When every value refuses, everything else is reached — --admin-tenant '!t1' grants admin over every tenant except t1, not admin over nothing.
State patterns take the form STATE_ID=PATTERN. Use * for the whole state (for example sid=*), a prefix such as sid=module.foo.*, or a leading ! to deny — for example --apply-pulled-in 'sid=!module.foo.output.*'. Repeated flags accumulate their patterns. A STATE_ID of * stands for the states that no other flag of the same name names, so --apply-modified '*=*' --apply-modified 'sid=!*' reaches every state except sid.
The --*-modified and --*-pulled-in flags check different things. --*-modified matches the resources the change directly modifies; --*-pulled-in matches the resources the change pulls in as cone or blast dependencies. Without --*-pulled-in, what a change pulls in is only restricted to the tenants the capability reaches, so a token that may modify one module but must not drag in anything outside it needs both.
Least-privilege example
Mint a token that can only apply changes to one specific state:
stategraph user access-tokens create \
--name ci-prod-apply \
--apply \
--apply-modified 'a1b2c3d4-5678-90ab-cdef-1234567890ab=*'
The token value is printed once in the response and cannot be retrieved again — store it securely.
field value
----- ------------------------------------
token eyJhbGciOiJIUzI1NiIs...
For scripting, use --format json:
{ "token": "eyJhbGciOiJIUzI1NiIs..." }
stategraph user access-tokens list
List the access tokens owned by the current user.
stategraph user access-tokens list
By default, output is a table with the columns id, name, created_at, expiration, owner_name, and owner_type. The expiration column is blank for tokens that never expire.
id name created_at expiration owner_name owner_type
------------------------------------ ------------- -------------------- ---------- ---------------- ----------
f02791c8-aa63-4cdf-acae-a7c968d8a831 ci-prod-apply 2026-06-04T10:30:00Z jane@example.com user
For scripting, use --format json. Each token object also includes owner_id:
{
"tokens": [
{
"id": "f02791c8-aa63-4cdf-acae-a7c968d8a831",
"name": "ci-prod-apply",
"created_at": "2026-06-04T10:30:00Z",
"owner_id": "550e8400-e29b-41d4-a716-446655440000",
"owner_name": "jane@example.com",
"owner_type": "user"
}
]
}
stategraph user access-tokens delete
Delete (revoke) an access token by id. The --token-id flag is required.
stategraph user access-tokens delete --token-id <uuid>
field value
------- ------------------------------------
id f02791c8-aa63-4cdf-acae-a7c968d8a831
revoked true
Inspecting your capabilities
Run stategraph user whoami to confirm the current identity and the exact capabilities a token or session holds. The capabilities object in its output mirrors the model above, so you can verify a least-privilege token is scoped the way you intended.
Default capabilities for new users
When a new user is created, they are granted a system-wide default capability. Out of the box this default is lenient, which is convenient when ACLs are not required. In an ACL-reliant setup you typically tighten it to a minimal baseline and grant additional rights per user or per group (for example, based on OAuth group membership).
Two admin commands manage this default:
# Show the capabilities granted to newly created users
stategraph capabilities default show
# Tighten the default so new users start with plan-only rights
stategraph capabilities default set --plan
stategraph capabilities default set accepts the same capability flags as token creation — see the table above — including --capabilities-json for setting the raw capabilities object directly. It takes no --name.
Changing the default applies to users created afterward; it does not retroactively change the capabilities of existing users.
API
The CLI is a thin wrapper over three endpoints. See the API Reference for full details.
| Method | Endpoint | Purpose |
|---|---|---|
POST |
/api/v1/user/access-tokens |
Create a token. The request body accepts name and an optional capabilities object. |
GET |
/api/v1/user/access-tokens |
List the current user's tokens. |
POST |
/api/v1/user/access-tokens/revoke?token_id=<id> |
Revoke a token. |
When capabilities is omitted from the create request, the token inherits the creator's full session capabilities; any requested capabilities are capped at the creator's, so a token can never exceed the identity that created it.
Next Steps
- User Commands - The
stategraph userCLI group - Authentication - API keys and service accounts
- Local Authentication - Email/password user management
- API Reference - REST API endpoints