Files
homelab-frontend/tasks/3.2-bearer-validation.md
T
Story Crater BotandClaude Opus 5 058f11cf2b
CI / Test (push) Canceled after 0s
CI / Vet (push) Canceled after 0s
CI / Build (push) Canceled after 0s
CI / Security (govulncheck) (push) Canceled after 0s
chore: initial commit of Go API gateway
Baseline for the Kong replacement on api.riotpiao.com. Brings the working
tree under version control for the first time: gateway source, the task
board that drives the agent runs, test fixtures, and K8s manifests.

Anchor the gateway ignore rule to the repo root. Unanchored, "gateway"
also matched the cmd/gateway/ source directory, so the program entrypoint
was excluded from every commit.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-19 20:54:34 -07:00

2.0 KiB

3.2 — Bearer token validation (GREEN)

Phase: 3 — Authentication Stage: GREEN Depends on: 3.1

  • Authorization: Bearer <jwt> is the credential the gateway accepts on protected routes
  • The scheme match is case-insensitive, as the HTTP spec requires — bearer, Bearer and BEARER all work
  • A valid, unexpired token signed by a currently published Authentik key returns the upstream response
  • Missing header, wrong scheme, malformed token, bad signature, expired token, and wrong issuer or audience each return 401 with WWW-Authenticate set
  • Rejections are RFC 9457 application/problem+json, and the reason is logged without logging the token
  • The Authorization header is not forwarded to upstreams
  • The validated caller identity is available to later stages, since 3.5 authorizes on it
  • Signature verification is real: a token with a valid-looking payload and a forged signature is rejected

This is precisely what Kong OSS key-auth could not do. Verified live: a raw apikey: header succeeded with 200 while Authorization: Bearer failed with 401, which hard-blocked every OpenAI-compatible client and is why authentication is OFF on the model API today.

Authentik is at https://authentik.riotpiao.com. A local stub issuer must be enough to work this task — no cluster, no credentials.

Verify

curl -s -o /dev/null -w '%{http_code}\n' localhost:8080/v1/chat/completions \
  -H "authorization: Bearer $VALID_TOKEN" -H 'content-type: application/json' \
  -d '{"model":"reasoning","messages":[]}'
# expected: 200

curl -s -i localhost:8080/v1/chat/completions -H 'content-type: application/json' -d '{"model":"reasoning"}'
# expected: 401, WWW-Authenticate present, content-type application/problem+json

curl -s -o /dev/null -w '%{http_code}\n' localhost:8080/v1/models -H "apikey: $OLD_KONG_KEY"
# expected: 401 — the retired Kong credential form is not accepted