Skip to content

Check KF-Console-Token and call KF as the OIDC client - #3708

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 running #76 before this goes to DuqDuq.

PubPub stops using the shared AUTH_INTERNAL_API_KEY, as kf-console's docs/calling-kf.md describes.

PubPub → KF. The orgs lookup, ban and unban sync, and the legacy /api/login check now send Authorization: Basic base64(OIDC_CLIENT_ID:OIDC_CLIENT_SECRET), the client credentials PubPub already signs in with. /api/login takes the KF Auth path when the client secret is set, instead of when the key is set.

KF → PubPub. /api/kf/webhooks, /summary, /branding, /contexts and /usage now check the KF-Console-Token header with jose (new dependency), and no longer read Authorization:

  • signature against KF Auth's JWKS (<OIDC_ISSUER_INTERNAL_URL>/api/auth/jwks)
  • iss <OIDC_ISSUER_URL>/api/auth, aud OIDC_CLIENT_ID, sub kf-console, exp (60s max age, 30s skew)
  • htm is the method, and htu is APP_URL plus the route's path, not the URL the request arrived on. APP_URL must be https://www.pubpub.org in prod and https://www.duqduq.org on DuqDuq, the URLs registered in kf-console's apps.*.yaml. It must already be, since REDIRECT_URI is built from it.
  • for the webhook, body_sha256 against the raw body. express.json keeps the raw bytes for that path only, through its verify hook. The guards are registered with router.all ahead of the routes, so the handlers are unchanged.

Any failure answers 401.

Checked

  • New tests sign tokens with a locally generated Ed25519 key and serve its JWKS from a stubbed fetch. They accept a good token on every route and a webhook with a matching body. They refuse a missing header, the old Bearer key alone, a wrong aud, sub or iss, an expired token, a wrong htm, a wrong htu (including the request-as-seen URL), another signing key, a tampered body, and a webhook token with no body hash.
  • Outbound tests check that orgs, ban and unban send Basic from the client id and secret with no Bearer, and send nothing without a secret. The /api/login test now expects Basic.
  • pnpm run lint (biome and tsc) is green. The full suite (vitest --run under the Firebase emulator, Node 24) passes: 789 passed, 3 skipped, 2 todo.

After deploy, the secret: ${KF_INTERNAL_API_KEY} on PubPub's webhook in kf-console can go, and AUTH_INTERNAL_API_KEY can come out of infra/.env.enc, .env.dev.enc and .env.local.enc. Nothing reads it any more.

@tefkah
tefkah marked this pull request as ready for review October 30, 2026 18:04
@tefkah
tefkah merged commit 922239a into main Oct 30, 2026
1 check passed
@tefkah
tefkah deleted the kf/console-token branch October 30, 2026 18:06
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