OIDC / OAuth2 bearer tokens (mode: :jwt): the control planes accept the
access tokens your identity provider issues, so operators sign in with SSO
and revocation is the provider's.
jwt: %{
issuer: "https://login.example.com/",
audience: "ankusa-admin",
jwks_url: "https://login.example.com/.well-known/jwks.json"
}A token is accepted when all of these hold:
- it is a JWS signed with an asymmetric algorithm (
RS*,PS*,ES*,EdDSA) by a key of the configured set.noneand theHS*family are never accepted, so a token cannot be forged by presenting a public key as an HMAC secret; issequalsjwt.issuerandaudis, or contains,jwt.audience(or one of its entries, when that is a list);expis present and not past, andnbf, when present, is not ahead, each withjwt.leeway_sseconds of clock-skew leeway;subnames the caller (it becomes the principal's id).
The principal's scopes come from the jwt.scope_claim claim (default
scope: a space-delimited string as in RFC 9068, or a list), and its tenants
from jwt.tenants_claim (default ankusa_tenants: a list of tenant ids, or
["*"]) together with any tenant:<id> scopes. Scopes this system does not
define (openid, email) are ignored.
Keys come from jwt.keys (public JWKs or PEMs), from jwt.jwks_url, or
both; see Ankusa.Admin.Auth.JWT.Keys for how the JWKS is cached and
refreshed. With no key loaded every token is 401.