Repository navigation
fix: a client without a secret cannot authenticate to token introspection (0.6.0-rc159) - #321
Merged
Merged
Conversation
|
Sorry @ciresnave-bot, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 2 days and 16 hours by commenting |
Reviewer's GuideThis release centralizes OAuth2 client-secret handling with Argon2id storage and legacy migration, closes secret-less client authentication at token introspection, and authenticates JARM JWE protected headers as AES-GCM AAD; the remaining changes synchronize the 0.6.0-rc159 release metadata. Sequence diagram for secretless client introspection authorizationsequenceDiagram
participant Client
participant Introspect as /oauth/introspect
participant Storage
participant SecretAuth as client_secret
Client->>Introspect: POST introspection with client_id and empty client_secret
Introspect->>Storage: load oauth2_client record
Storage-->>Introspect: client record without a secret
Introspect->>SecretAuth: verify_client_credentials
SecretAuth-->>Introspect: false
Introspect-->>Client: invalid_client HTTP 401
Sequence diagram for hashed OAuth2 client-secret authenticationsequenceDiagram
participant Client
participant TokenEndpoint
participant SecretAuth as client_secret
participant Storage
Client->>TokenEndpoint: Authenticate with client secret
TokenEndpoint->>SecretAuth: authenticate
alt Hashed secret
SecretAuth-->>TokenEndpoint: Argon2id verification result
else Legacy plaintext secret
SecretAuth->>Storage: upgrade legacy client record
Storage-->>SecretAuth: upgraded record with client_secret_hash
SecretAuth-->>TokenEndpoint: authentication successful
else No secret
SecretAuth-->>TokenEndpoint: authentication failed
end
TokenEndpoint-->>Client: OAuth response
Sequence diagram for JARM JWE protected-header authenticationsequenceDiagram
participant JARM
participant Encryptor as AES256GCM
participant Recipient
JARM->>JARM: create_jwe_header
JARM->>Encryptor: encrypt_payload with protected-header AAD
Encryptor-->>JARM: ciphertext and authentication tag
JARM-->>Recipient: JWE compact serialization
Recipient->>Encryptor: decrypt with protected-header AAD
Encryptor-->>Recipient: plaintext or decryption failure
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
ciresnave-bot
force-pushed
the
fix/introspection-secretless-client
branch
from
October 26, 2026 21:43
6fd3902 to
c78580c
Compare
…tion (0.6.0-rc159) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013YEhSGGFctL3d4hGevi7tC
ciresnave-bot
force-pushed
the
fix/introspection-secretless-client
branch
from
October 27, 2026 00:26
c78580c to
edfba52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
/oauth/introspectread the stored client secret asclient_data["client_secret"].as_str().unwrap_or("")and compared the presented secret with it, so a record with no secret, an empty one or a non-string one authenticated with an empty presented secret (Basicclient_id:or POSTclient_secret=). RFC 7662 section 2.1: the endpoint MUST require authorization. A client without a secret now getsinvalid_client(401). Confidential clients are unaffected, and so are clients created byPOST /oauth/register, which always issues a secret. Reachable only for secret-less clients an operator wrote into storage (public clients); the caller still needs the token it asks about.Stacked on #318 (it uses
api::client_secret); merge #316 and #318 first.Red first, in Docker (rust:latest,
--features api-server,axum-integration, jobs=2): with only the new test file,a_client_without_a_secret_cannot_introspectfails on the old code anda_client_with_a_secret_still_introspectspasses; with the fix both pass. Regression, same run:introspection_status_tests4,oauth_advanced_tests19,oauth2_client_secret_hash_tests3,oauth2_code_grant_client_auth_tests10 pass;cargo fmt --all -- --checkclean. Not run: the rest of the suite, clippy. No existing test authenticated a secret-less client at introspection (checked by reading the seeds in the introspection tests).Version 0.6.0-rc159 (PM-allocated); the 0.5.x backport (rc71) follows. GHSA (Low) and RustSec after the fixed versions are live.
🤖 Generated with Claude Code
https://claude.ai/code/session_013YEhSGGFctL3d4hGevi7tC
Summary by Sourcery
Require a real client secret for OAuth token introspection and release the change as 0.6.0-rc159.
Bug Fixes:
invalid_clientas required by RFC 7662.Enhancements:
Tests: