Skip to content

Tokens & ACL

Every API request is authenticated with a token (except GET /api/v1/stats). A token has a unique name, a role and an optional acl. Only a SHA-256 hash of the secret is stored: the secret is shown once when the token is created or rotated.

Sending the token

  • Authorization: Bearer <token> (scheme case-insensitive)
  • access-token: <token> header
  • ?access_token=<token> query parameter (for devices that can only fetch a URL; redacted from logs)

After CONFIG_RATE_LIMIT_FAILED_AUTH (default 20) failed attempts per client IP and minute, further attempts get 429 until the minute is over – guessing tokens doesn't scale.

Roles and default ACLs

Role Default ACL Typical use
admin * Administration, CLI password login
user export, export/*, export/private/*, export/group/*, import, import/*, indicators, indicators/*, sources, sources/*, hits, hits/* Integrations that manage sources and indicators
guest export, hits Public export, reporting hits

A non-empty acl on the token replaces the role defaults – a machine with its own ACL that should report hits needs hits in it (since v1.33.0; the defaults got hits then too).

ACL patterns

Patterns are minimatch globs matched against the request path relative to /api/v1/:

Request Checked against
GET /api/v1/export export
GET /api/v1/export/3 export/3 or export/<its name>
GET /api/v1/sources/5/fetch sources/5/fetch
GET /api/v1/export/private/5,6 export/private/5 and export/private/6 (every source must be allowed, by ID or name)
GET /api/v1/export/group/customer-x export/group/customer-x or export/group/<its id>

* matches one path segment (export/* matches export/3, not export/private/3); ** matches any depth.

Since v1.29.0. Sources and groups can be named in a rule by ID or name (export/google-ips, export/group/customer-x), whichever form the URL uses. Names are easier to read but can change: renaming a source or group rewrites the rules naming it exactly, so tokens keep their access (glob rules like export/google-* are not rewritten). A token without access gets 403 also for sources and groups that don't exist.

Common setups

# customer machines pulling one group
token:create --name customer-x-pull --role guest --acl '["export/group/customer-x","hits"]'

# a firewall pulling two private sources
token:create --name fw-prague --role guest --acl '["export/private/5","export/private/google-ips"]'

# a push script importing into source 7
token:create --name honeypot-push --role guest --acl '["import/7"]'

# read-only monitoring of indicators
token:create --name monitoring --role guest --acl '["indicators","indicators/*"]'

Managing tokens

tokens                                   # list (secrets are never shown)
token:update --id 5 --acl '["export"]'   # "null" clears the ACL (back to role defaults)
token:rotate --id 5                      # new secret, shown once
token:delete --id 5

lastActiveAt (shown as Last Active) is updated at most once a minute per token – handy for finding unused tokens.

Primary admin token

Token ID 1 is the primary admin token. It cannot be deleted, its role cannot be changed and it cannot be given a restrictive ACL (only none, [] or one containing *). Rotate it after installation – see Installation.

Audit

Changes are recorded in the audit log with the token's name as actor (GUI users and CLI users with their sign-in name): audit in the CLI, Audit log in the GUI, GET /api/v1/audit.

Web CLI access

The browser CLI is not controlled by API ACLs: it requires an Authentik sign-in (optionally limited by CONFIG_OIDC_ALLOWED_GROUPS) or the name and secret of an admin token. See Installation – CLI sign-in.