Repository navigation
Support authorization_details on token exchange - #6921
Merged
Merged
Conversation
jhrozek
requested review from
ChrisJBurns,
JAORMX,
amirejaz,
rdimitrov and
tgrunnagle
as code owners
October 22, 2026 15:14
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6921 +/- ##
==========================================
+ Coverage 79.87% 79.88% +0.01%
==========================================
Files 829 833 +4
Lines 84722 84976 +254
==========================================
+ Hits 67668 67881 +213
- Misses 17049 17090 +41
Partials 5 5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ChrisJBurns
previously approved these changes
Oct 22, 2026
Token exchange needs RFC 9396 authorization_details support for delegated clients (#6894). Add a Go-only, immutable registry that maps a type name to the grant types it applies to and a Grant hook. Parsing enforces the RFC 9396 structure plus ToolHive policy: duplicate and case-folded member names, a 64 KiB limit and depth 64. Grant calls each hook once with all of its entries and the request context, validates the hook output to the same limits, and returns the granted details in a fixed order. Hooks decide only; the package does not persist details or put them in tokens. Co-authored-by: Mecatl <noreply@mecatl.dev>
Delegated clients such as Mecatl name a session or schedule grant with an authorization_details entry on token exchange (#6894). With a registry configured, the handler rejects a repeated parameter with invalid_request (RFC 6749 section 5.2), parses the details before the subject token is checked, and calls the type hooks after the subject, consent, scope and audience checks. The response echoes what the hooks granted, only after the token is issued. Typed hook errors become invalid_authorization_details or invalid_request with a safe reason; other hook failures become server_error. Each rejection is logged once at WARN with a fixed reason; hook error text is never logged, since it could carry credentials or request data. Without a registry the parameter is ignored, as before. The registry is passed through a functional factory option, authserver.Config and runner.WithAuthorizationDetailsRegistry. Setting it while token exchange is disabled is a startup error. Docs describe the behaviour and its limits: details are not put in tokens, persisted or sent to resource servers yet (#6909, #6895). Co-authored-by: Mecatl <noreply@mecatl.dev>
CI's Go lint job flagged a long line, a few unused parameters and receivers, a missing t.Helper(), and missing t.Parallel() calls in the new authorization_details tests. Fix the ones that are mechanical. Two tests keep their serial execution with a //nolint reason: one mutates the process-wide slog default, and the other's subtests share state and must run in order. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
CI's lint job flagged validArray (complexity 20) and HandleTokenEndpointRequest (complexity 18), both over the gocyclo limit of 15. Split validArray into an arrayScanner with one method per token kind, and move the consent, scope, audience and authorization_details steps into authorizeDelegation. The check order is unchanged and no error or log reason changes. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
jhrozek
force-pushed
the
authorization_details_v2
branch
from
October 22, 2026 18:34
04e339e to
05e8b19
Compare
ChrisJBurns
approved these changes
Oct 22, 2026
1 task
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.
Summary
Delegated clients such as Mecatl need to name a session or schedule grant with an RFC 9396
authorization_detailsentry when they call token exchange. The auth server ignores the parameter today, so there is no way for a deployment to validate or grant these details. This PR adds the parsing and hook mechanism and wires it into the token-exchange handler. It stops there: details are not put in tokens, persisted or sent to resource servers yet.pkg/authserver/authorizationdetailspackage: an immutable, Go-only registry mapping a type name to the grant types it applies to and aGranthook. Parsing enforces the RFC 9396 structure plus ToolHive policy (duplicate and case-folded member names, 64 KiB size limit, depth 64). Each hook is called once with all of its entries; its output is validated to the same limits and returned in a fixed order.authserver.Configandrunner.WithAuthorizationDetailsRegistry. Setting it while token exchange is disabled is a startup error.docs/arch/17-token-exchange-delegation.mddescribes the behaviour and its limits.Fixes #6894
Related: #6886, #6895, #6897, #6909.
Type of change
Test plan
Not yet run on this branch. Unit and integration tests are included (package tests,
handler_test.go, runner and config tests, andauthorization_details_integration_test.go), but they have not been executed, and neither has lint. I will check the boxes below as each is run.task test)task test-e2e)task lint-fix)Changes
pkg/authserver/authorizationdetails/pkg/authserver/server/tokenexchange/authdetails.gopkg/authserver/server/tokenexchange/{handler,factory,validator}.gopkg/authserver/{config.go,server_impl.go}Configfield and option plumbingpkg/authserver/runner/embeddedauthserver.goWithAuthorizationDetailsRegistry, startup checkdocs/arch/*_test.goDoes this introduce a user-facing change?
Before:
authorization_detailson a token-exchange request is ignored, and the response never contains the member.After, with no registry configured: nothing changes.
After, with a registry configured: a client can receive
invalid_request(repeated parameter, or a hook's typed rejection with a safe reason),invalid_authorization_details, orserver_errorfor a hook failure. A successful response includes anauthorization_detailsmember with what the hooks granted.Special notes for reviewers