Skip to content

fix: accept only the issuer as client assertion aud for non-CIBA clients - #370

Merged
osanderson merged 1 commit into
mainfrom
fix/client-assertion-aud-issuer-only
Sep 23, 2026
Merged

osanderson merged 1 commit into
mainfrom
fix/client-assertion-aud-issuer-only

Conversation

@osanderson

@osanderson osanderson commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes the scheduled FAPI Conformance failure on main (run 35848443579): AS baseline-client-credentials and AS mtls-client-credentials each failed fapi2-security-profile-final-ensure-invalid-client-assertions-fail, block "Client assertion with token endpoint as aud".

Cause. FAPI 2.0 Security Profile Final §5.3.2.1: the AS "shall only accept its issuer identifier value … as a string in the aud claim received in client authentication assertions". acceptableClientAssertionAudiences also accepted the token endpoint URL (and its mTLS alias) at the token endpoint, per RFC 7523 §3's older allowance. The suite added this check upstream on 2026-09-22 (commit f096b51f0). Only the client-credentials variant exercises it at the token endpoint, because the auth-code variants' first authenticated endpoint is PAR, which was already issuer-only.

Fix. Endpoint-URL audiences are now accepted only for clients registered for CIBA (BackchannelAuthenticationRequestAlgorithm set). Every other client is issuer-only at every endpoint.

  • CIBA clients keep CIBA Core 1.0 §7.1's widened set ("the OP MUST accept its Issuer Identifier, Token Endpoint URL, or Backchannel Authentication Endpoint URL"). The FAPI-CIBA-ID1 suite signs every token-endpoint assertion, refresh included, with the token endpoint URL, so an issuer-only token endpoint would break the CIBA legs.
  • PAR is unchanged: issuer-only for every client.

Behaviour change for integrators: a non-CIBA client that signed aud as the token endpoint URL now gets invalid_client. go-fapi's own client package already signs with the issuer.

Changes

  • server/par.go: the CIBA gate in acceptableClientAssertionAudiences, plus a rewritten doc comment.
  • Tests: the auth-code token-URL and mTLS-alias audience tests now expect rejection. New TestExchangeBackchannelAuthenticationAcceptsTokenEndpointURLAsClientAssertionAudience checks a CIBA client still authenticates at the token endpoint with the token URL.
  • cmd/conformance-as client-credentials smoke tests now sign with the issuer, as the FAPI2 suite does.
  • ARCHITECTURE.md, the oidf-config README and in-code comments no longer describe the old token-endpoint allowance.

Test plan

  • go vet, go test -race ./..., golangci-lint clean
  • Reproduced the CI failure locally against main with the latest suite image (identical module, block and condition counts)
  • Full local 22-leg conformance run on this branch against the latest suite image (2026-09-23): 22/22 clean, zero auto-retries. AS baseline-client-credentials 0 failures (1166 successes, previously 1163 + 3 failures) and AS mtls-client-credentials 0 failures (548, previously 545 + 3). All four CIBA legs are unchanged and clean.

🤖 Generated with Claude Code

FAPI 2.0 Security Profile Final §5.3.2.1 requires the authorization
server to "only accept its issuer identifier value ... as a string in
the aud claim received in client authentication assertions". The token
endpoint also accepted its own URL (and its mTLS alias), per RFC 7523
§3's older allowance. The OIDF suite's new
fapi2-security-profile-final-ensure-invalid-client-assertions-fail
module now checks this at the token endpoint for the client-credentials
variant, failing the scheduled conformance run.

Endpoint-URL audiences are now accepted only for clients registered
for CIBA: CIBA Core 1.0 §7.1 requires the token and backchannel
authentication endpoint URLs to be accepted, and the FAPI-CIBA suite
signs every token-endpoint assertion (refresh included) with the token
endpoint URL. PAR stays issuer-only for every client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@osanderson
osanderson merged commit 3f94297 into main Sep 23, 2026
9 checks passed
@osanderson
osanderson deleted the fix/client-assertion-aud-issuer-only branch September 23, 2026 12:41
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