Skip to content

feat: add token-gated manual CIBA approve/deny UI - #245

Merged
osanderson merged 4 commits into
mainfrom
conformance-as/ciba-approval-ui
Sep 1, 2026
Merged

feat: add token-gated manual CIBA approve/deny UI#245
osanderson merged 4 commits into
mainfrom
conformance-as/ciba-approval-ui

Conversation

@osanderson

Copy link
Copy Markdown
Collaborator

Summary

  • Hosted OIDF certification has no equivalent of the local dev-mode automated_ciba_approval_url mechanism — locally, the suite calls this binary's own /backchannel-approve automatically; the hosted certification UI has no such field. Without it, any CIBA module needing a real completed flow (happy-flow, refresh-token, a two-attempt module) always expires and fails once its auth_req_id's lifetime runs out, since nothing ever calls that endpoint.
  • Adds -ciba-approval-ui-token=<token>, off by default, which serves a token-gated HTML form at GET/POST /ciba-approve for driving a pending auth_req_id by hand while watching a live hosted run — paste the ID, click Approve/Deny.
  • POST /backchannel-approve itself stays unauthenticated by design (meant to be called automatically by the local suite); the new UI needs its own access gate to be usable as a link over the public internet, hence the token (compared with subtle.ConstantTimeCompare; wrong/missing token → 404, not 403, so a bad guess doesn't even confirm the route exists).
  • backchannelHandler.handleApprove's core logic (pending-set lookup, building the InteractionResult, calling CompleteBackchannelAuthentication) is extracted into a new decide method so the existing JSON endpoint and the new HTML UI share one implementation instead of duplicating it.

Test plan

  • TestValidCIBAApprovalUIToken — token comparison (match/mismatch/empty)
  • TestCIBAApproveUIRouteNotRegisteredWhenTokenEmpty — confirms the route truly doesn't exist when the flag is unset
  • TestCIBAApproveFormRequiresToken — no/wrong/right token on GET
  • TestCIBAApproveUIApprovesRealRequest / TestCIBAApproveUIDeniesRealRequest — full round trip through a real client.BeginBackchannelAuthentication session, approved/denied via the new UI, confirmed via client.PollBackchannelAuthentication (a real issued token, or a real denial)
  • TestCIBAApproveUIUnknownAuthReqID — error rendering, not a panic
  • TestCIBAApproveUISubmitRequiresToken — a wrong-token POST is a true no-op (the same request is still approvable afterward with the right token)
  • go build ./..., go vet ./cmd/conformance-as/..., gofmt -l cmd/conformance-as all clean
  • go test ./cmd/conformance-as/... and full go test ./... both pass

🤖 Generated with Claude Code

https://claude.ai/code/session_01KWEP7ddZm9T8pVotywwFfF

osanderson and others added 2 commits September 1, 2026 19:49
Hosted OIDF certification has no equivalent of the local dev-mode
automated_ciba_approval_url mechanism, so a CIBA module that needs a
real completed flow always expires and fails once nothing calls
POST /backchannel-approve. Adds -ciba-approval-ui-token, which serves
a token-gated HTML form at GET/POST /ciba-approve for driving a
pending auth_req_id by hand during a live hosted run. Off by default;
reuses the existing approve/deny logic (extracted into
backchannelHandler.decide) rather than duplicating it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.35714% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/conformance-as/backchannel.go 50.00% 7 Missing and 1 partial ⚠️
cmd/conformance-as/backchannel_ui.go 91.17% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

decide's own doc comment already guarantees it only ever returns a
*decideError or nil; handleApprove and the new UI's submit handler
were still defensively falling back to a generic 500 for a shape that
guarantee rules out. Trust it directly instead, and add coverage for
the one real gap that surfaced alongside it: an invalid action value
through the manual approve/deny UI.
@sonarqubecloud

sonarqubecloud Bot commented Sep 1, 2026

Copy link
Copy Markdown

@osanderson
osanderson merged commit e0931fb into main Sep 1, 2026
9 checks passed
@osanderson
osanderson deleted the conformance-as/ciba-approval-ui branch September 1, 2026 12:10
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