# 3.3 — Authentik service account and token provider (GREEN) Phase: 3 — Authentication Stage: GREEN Depends on: [3.2](3.2-bearer-validation.md) - [ ] A service account exists in Authentik at `https://authentik.riotpiao.com` for machine callers of the model API - [ ] An OAuth2 provider is configured so that account can obtain a token non-interactively, with no browser step - [ ] The token endpoint returns a signed JWT whose issuer and audience match what the gateway validates, and which the gateway accepts on a protected route - [ ] Token lifetime is set deliberately and recorded, not left at whatever the default is - [ ] The client secret is stored as a Kubernetes Secret referenced from git, never committed in plaintext - [ ] The Authentik configuration is captured in the repo as reproducible steps or declarative config, so it can be rebuilt rather than clicked together again - [ ] The token carries whatever claim [3.5](3.5-capability-authorization.md) authorizes on Open risk recorded in `AUTH-PLAN.md` and unresolved: Authentik 2026.x may require an app-password or JWT-assertion flow rather than a plain `client_secret` POST to the token endpoint. Verify which flow the running version accepts before wiring anything that depends on it, and record the answer here. ## Verify ```bash curl -s -i -X POST https://authentik.riotpiao.com/application/o/token/ \ -d grant_type=client_credentials -d "client_id=$CID" -d "client_secret=$CSEC" # expected: 200, JSON with access_token; if 400/401, the app-password / JWT-assertion risk above is real — record which curl -s -o /dev/null -w '%{http_code}\n' http://homelab-frontend.api.svc.cluster.local/v1/models \ -H "authorization: Bearer $ACCESS_TOKEN" # expected: 200 — the gateway accepts a real Authentik-issued token, not only a stub one ```