Files
qbit-authentik/docs/ACCESS-TOKENS.md
james.maesandClaude Opus 5.5 7f8e742120 feat(tokens): scopes, last used, reminders and admin views (DESIGN.md section 13, phase 6c)
- Scopes: Create Token takes read only, apps and tables when
  tokenScopesEnabled (validated against the instance and the operator's
  own access). AuthentikTokenScopes reads the signed qqq_token claim in
  both mappers (and AuthentikTokenScopes.apply for hosts with their own
  customizer): no row = unscoped, deleted token = no permissions, any
  verification failure = no permissions. STAND-IN for core
  QCredentialScope (qqq#1168, RC.7): permissions are intersected; the
  core scope is attached by reflection when present (empty dimension =
  null = unrestricted).
- Last used from Authentik login events (method token, 90 days, cached
  5 minutes); createdAt and scopeSummary from the scope row.
- Daily expiry reminders (7 days, 1 day) through the optional Alerts
  producer, deduplicated on the scope row; guard-bypass alert.
- Admin widget on the app home (authentik.tokens.manage): by owner, by
  age, unused for tokenUnusedDays, deactivated owners; bulk Revoke Token
  on the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:26:53 -05:00

5.5 KiB
Raw Permalink Blame History

Using access tokens

An access token lets a script, a CLI or another service call a QQQ app as you, without a browser sign-in. In apps that sign in with Authentik, access tokens are Authentik app passwords, managed from inside the app by qbit-authentik. The design is in DESIGN.md §13.

Create a token

  1. Open Preferences → Access tokens. It's also in the user menu under Access tokens.
  2. Choose Create token and fill in:
    • a description, for example "nightly export script";
    • an expiry. It's required: at most 90 days for people, and 365 for service accounts;
    • optionally, a scope: read only, and/or only some apps and tables. A scoped token can never do more than you can, and loses access as soon as you do.
  3. Copy the key from the dialog. It is shown once. The app does not keep it, and nobody can show it again. If you lose it, rotate the token.

The dialog also shows ready-to-run examples for this app, with its real URLs.

Use a token

Tokens are exchanged for a short-lived access token (a JWT) at the Authentik token endpoint. You then call the app with that JWT.

# 1. Exchange the token for a JWT (valid for the app's access-token lifetime)
JWT=$(curl -s -X POST "https://auth.example.com/application/o/token/" \
  -d grant_type=client_credentials \
  -d client_id="$APP_CLIENT_ID" \
  -d username="$YOUR_USERNAME" \
  -d password="$QQQ_TOKEN" \
  -d scope="openid profile email" | jq -r .access_token)

# 2. Call the app
curl -s -H "Authorization: Bearer $JWT" "https://app.example.com/qqq/v1/metaData"
  • Keep the token in a secret store or an environment variable. Never commit it.
  • When the JWT expires (the API answers 401), repeat step 1.
  • Every exchange is recorded as a sign-in in Authentik. The app shows the token's last used time from those records.

Manage your tokens

From Preferences → Access tokens:

Action What happens
Rotate A new key replaces the old one. The description, expiry and scope stay the same. The old key stops working at once.
Extend Moves the expiry. The limit counts from today.
Revoke Deletes the token in Authentik. Anything using it stops working at once.

When the host has configured a scheduler and the optional Alerts delivery adapter, the daily job sends owner reminders in the 7-day and 1-day expiry windows. Delivery channels (bell/email) follow the host’s Alerts configuration. Each window sends once; if first seen within one day, only the urgent window sends. Extending a token through the qbit resets its reminder windows. Without delivery support, the job logs and leaves the reminder pending.

For administrators

People with authentik.tokens.manage see the Access tokens TABLE widget on the Identity home page, with a link to all access tokens. From there they can:

  • filter by person, intent, expiring status or token identifier; view computed creation time, scope and last use (these computed columns cannot be filtered or sorted by the Authentik API);
  • revoke tokens one at a time or in bulk, for example the tokens the home page lists as unused for 60 days, or as belonging to deactivated people;
  • create a service account for an integration (Users → Create Service Account). The account gets one app password, shown once, and the groups you choose. Rotate and extend it from its token record.

The widget shows the top ten owners plus a total, age buckets (<30d, 30–90d, 90–365d, >365d, and unknown), unused tokens and tokens with deactivated owners. Cleanup rows include owner and token links; age buckets link to the explicit token identifiers. Creation dates are known only for tokens created by the qbit. External tokens can receive reminders without acquiring a scope or an invented creation date.

Last use comes from app-password login events over the last 90 days, cached for five minutes. The pinned Authentik schema has no date-range parameter for this endpoint, so the qbit pages newest-first to the window boundary. API-intent tokens show not tracked and never appear as unused. A token with no recorded login is suggested as unused only if its known creation date is older than tokenUnusedDays and that threshold is at most 90 days.

Create Token offers read-only, apps and tables scopes only when tokenScopesEnabled is enabled after installing the signed claim mapping. Enter one metadata name per line. Review checks existence and the operator’s current read/hasAccess permission and shows the scope. The claims mappers intersect permissions after resolving them; scopes never grant access the owner lacks. A deleted token receives no permissions even if its local scope row remains, subject to the 60-second verification cache.

Administrators can never create, rotate or extend a token for another person. Each person manages their own.

Accounts that can administer Authentik, the break-glass account and the app's own service account can't get tokens from the app at all. Use the Authentik admin UI for them if you really need one.

Security notes

  • A token can do what its owner can do, or less if it's scoped. Prefer a scoped token and a short expiry.
  • Tokens for people are created as that person, through Authentik. The app's own service account cannot create a token for a person.
  • Every create, rotate, extend and revoke is audited in the app (authentik_admin_action, with the channel it came from) and in Authentik's event log.
  • The key exists only in Authentik and in the one response that showed it to you.