Skip to content

oauth/cimd: post-merge review nits (F1, F2, F6, F7)#117

Merged
BorisTyshkevich merged 1 commit into
mainfrom
oauth/cimd-post-merge-nits
May 15, 2026
Merged

oauth/cimd: post-merge review nits (F1, F2, F6, F7)#117
BorisTyshkevich merged 1 commit into
mainfrom
oauth/cimd-post-merge-nits

Conversation

@BorisTyshkevich
Copy link
Copy Markdown
Collaborator

Summary

Four findings from the post-merge review on #116, all addressed on one branch.

  • F1 (high) — `/authorize` + `/callback` plain-text `http.Error` responses replaced with `writeOAuthTokenError`, producing RFC 6749 §5.2 JSON shape (`application/json` + `error` + `error_description`). All 13 error sites mapped to standard codes (`invalid_request` / `invalid_client` / `invalid_target` / `server_error`).
  • F2 (medium) — `writeOAuthTokenError` now emits `WWW-Authenticate: Bearer error="...", error_description="..."` when status == 401. RFC 7235 §3.1 mandates the header on 401s; RFC 6750 §3 is the Bearer-challenge shape. The two existing 401 callers on `/oauth/token` get the challenge for free.
  • F6 (nit) — `pkg/config/config.go:105` referenced a non-existent `GatingSecretKey`; corrected to `SigningSecret`. While in the file, the `SigningSecret` desc tag (which still mentioned "refresh tokens, DCR client_secrets" — both removed in RFC: support CIMD inbound at /authorize #115) was rewritten to describe what the secret actually HKDF-derives keys for in v1.
  • F7 (nit) — Stripped stale `refresh_revokes_tracking` mentions from the gating-mode forbidden list in `docs/oauth_authorization.md` (3 sites). The field never existed under that name post-DCR-removal; the real list enforced by `validateOAuthRuntimeConfig` is `client_id` / `client_secret` / `token_url` / `auth_url` / `userinfo_url` / `public_auth_server_url`.

Test plan

  • `go test ./...` green
  • `go vet ./...` clean
  • New tests: `TestWriteOAuthTokenError` gains a 401-Bearer-challenge subtest; `TestOAuthAuthorizeErrorsAreJSON` verifies four error paths through /authorize + /callback return `application/json` with the OAuth error shape.
  • Smoke: `curl -X POST .../oauth/authorize` should now return application/json with `error=invalid_request` (was: `text/plain` "Method not allowed").
  • Smoke: `curl -X POST .../oauth/token` with bogus client_id should now return `WWW-Authenticate: Bearer error="invalid_client"` (was: 401 with no challenge header).

🤖 Generated with Claude Code

F1 (high) — /authorize and /callback emitted plain text/plain errors via
http.Error. Now all error paths in those two handlers route through
writeOAuthTokenError, producing the RFC 6749 §5.2 JSON shape that the
rest of /oauth/* already used. Error codes mapped:
  - missing client_id/redirect_uri/response_type → invalid_request
  - resolver failure                              → invalid_client
  - redirect_uri not registered                   → invalid_request
  - missing/wrong PKCE                            → invalid_request
  - resource indicator mismatch                   → invalid_target (RFC 8707)
  - PKCE-verifier generation failure              → server_error (500)
  - pending-auth JWE encode failure               → server_error (500)
  - upstream-AS URL resolve failure               → server_error (502)
  - missing state/code at /callback               → invalid_request
  - unknown/expired pending-auth at /callback     → invalid_request
  - auth-code JWE encode failure                  → server_error (500)
  - unparseable pending.RedirectURI at /callback  → server_error (502)
Method-not-allowed at /authorize stays 405 but as JSON.

F2 (medium) — writeOAuthTokenError now sets
`WWW-Authenticate: Bearer error="...", error_description="..."` when
status == 401. RFC 7235 §3.1 mandates the header on 401s; RFC 6750 §3
specifies the Bearer challenge shape. The two existing 401 callers on
/oauth/token (`invalid_client` for missing CIMD client + unsupported
client auth) now carry the challenge for free.

F6 (nit) — pkg/config/config.go:105 said "secrets like GatingSecretKey
can be injected" — the field is SigningSecret; comment updated. While
in the file, also rewrote the SigningSecret desc tag (was referring to
"refresh tokens, DCR client_secrets" — both gone post-#115) to
accurately describe what the secret HKDF-derives keys for in v1:
pending-auth state JWE + downstream auth-code JWE.

F7 (nit) — docs/oauth_authorization.md listed `refresh_revokes_tracking`
in the gating-mode forbidden list at three places. The field never
existed under that name post-DCR-removal — validateOAuthRuntimeConfig
forbids client_id / client_secret / token_url / auth_url / userinfo_url
/ public_auth_server_url, and that's it. Stripped from the doc.

Tests added:
- TestWriteOAuthTokenError gains a 401-Bearer-challenge subtest pinning
  the new WWW-Authenticate behaviour.
- TestOAuthAuthorizeErrorsAreJSON pins F1: four error paths through
  /authorize and /callback verified to return application/json bodies
  with RFC 6749 error/error_description.

No behaviour change beyond the four fixes; all existing tests stay
green; `go vet ./...` clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@BorisTyshkevich BorisTyshkevich merged commit f643a44 into main May 15, 2026
4 checks passed
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