Skip to content

Call KF Auth as the app and check the console's token - #73

Merged
tefkah merged 1 commit into
mainfrom
kf-console-token
Oct 30, 2026
Merged

tefkah merged 1 commit into
mainfrom
kf-console-token

Conversation

@tefkah

@tefkah tefkah commented Oct 30, 2026

Copy link
Copy Markdown
Member

Merge only after kf-console #76 is deployed to production. On staging, the console must be deployed with #76 before this goes to staging.

Moves underlay off the shared AUTH_INTERNAL_API_KEY, following kf-console's docs/calling-kf.md.

  • App → KF Auth. The internal API calls (/api/internal/users/:id/orgs, /users/search, /users/:id, used to link new orgs to a KF org) now send Authorization: Basic base64(OIDC_CLIENT_ID:OIDC_CLIENT_SECRET) instead of Bearer <key>. The console grants kf_underlay users.search, users.get and users.orgs.
  • KF console → app. GET /api/kf/summary checks the KF-Console-Token header and no longer reads Authorization. The token must verify against KF Auth's JWKS (EdDSA, fetched from <OIDC_ISSUER_URL>/api/auth/jwks with jose's createRemoteJWKSet), with iss = <OIDC_ISSUER_URL>/api/auth, aud = OIDC_CLIENT_ID, sub = kf-console, at most 60 s old with 30 s of skew, htm = GET and htu = APP_URL + /api/kf/summary (the registered summary_url, not the URL the request arrived at). Anything else answers 401. The auth check now runs before the kf_org_id check.
  • AUTH_INTERNAL_API_KEY is gone from the code and wrangler.jsonc; nothing reads it now. jose is added to @underlay/server (it was already in the lockfile through better-auth).

Underlay has no webhook receiver, so there is no body_sha256 check to add.

Checked: tests sign tokens with a locally generated EdDSA key and serve its JWKS from a stub fetch, with no network. They accept a good token and refuse a missing header, a non-JWT, a wrong aud, sub, iss, an expired or too-old token, a wrong htm, a wrong htu path or host, a token signed by an unpublished key, and a tampered payload. A route test runs the real check through /api/kf/summary, and the old Bearer key alone now gets 401. The outbound test checks that internal calls carry Basic base64(id:secret) and no Bearer. pnpm fmt:check, pnpm lint, pnpm typecheck, pnpm test and the web build and SSR smoke all pass locally.

Env: the AUTH_INTERNAL_API_KEY secret can be deleted from each Worker (wrangler secret delete AUTH_INTERNAL_API_KEY --env staging|prod) and from the encrypted env files after this deploys. Nothing needs to be added: OIDC_CLIENT_ID/OIDC_CLIENT_SECRET are already set.

@tefkah
tefkah marked this pull request as ready for review October 30, 2026 17:39
@tefkah
tefkah merged commit 7d1c6a7 into main Oct 30, 2026
1 check passed
@tefkah
tefkah deleted the kf-console-token branch October 30, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant