You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c32d05f
Browse filesBrowse the repository at this point in the historyBrowse files
Describe the ID-JAG confidential-client rule as SDK policy
The docs, several comments and docstrings, and one ValueError said SEP-990
requires a confidential client for the jwt-bearer (ID-JAG) grant. It does
not: the IETF draft it profiles makes that a SHOULD (section 9.1 in -04,
not 8.1), and RFC 7521 leaves client authentication policy to the
authorization server. Say that the SDK chose the stricter reading, that
Client ID Metadata Document clients therefore cannot use the grant against
the built-in authorization server, and how to apply a different policy.
Which clients the authorization server accepts is unchanged. The only
runtime difference is the text of the ValueError raised by
IdentityAssertionOAuthProvider for an empty client_secret.
Fixes#3598
Copy file name to clipboardExpand all lines: docs/client/identity-assertion.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -59,7 +59,7 @@ The extension does not demand this; it is a deliberately stricter choice. This c
59
59
60
60
### A confidential client
61
61
62
-
`client_secret` is required; the constructor raises `ValueError` without one. The IETF profile underneath [SEP-990](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/990)reserves this grant for confidential clients, SEP-990 requires the client to authenticate, and this SDK enforces both by insisting on a shared secret. `token_endpoint_auth_method` picks where it travels: `client_secret_post` (the default, in the form body) or `client_secret_basic` (an HTTP Basic header). The profile also permits `private_key_jwt`; this provider does not support it.
62
+
`client_secret` is required; the constructor raises `ValueError` without one. The IETF profile underneath [SEP-990](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/990)recommends this grant for confidential clients only, and [RFC 7521](https://datatracker.ietf.org/doc/html/rfc7521) leaves that policy to the authorization server. This SDK takes the conservative reading on both sides: the built-in authorization server refuses a client that has no shared secret, and this provider insists on one. `token_endpoint_auth_method` picks where it travels: `client_secret_post` (the default, in the form body) or `client_secret_basic` (an HTTP Basic header). The profile also permits `private_key_jwt`; this provider does not support it.
63
63
64
64
!!! tip
65
65
Read `client_secret` from the environment or a secret manager, never from source control.
@@ -86,6 +86,7 @@ The SDK can also *be* the authorization server: `create_auth_routes` returns the
86
86
87
87
*`identity_assertion_enabled=True` gates everything. Off, which is the default, `/token` answers this grant with `unsupported_grant_type` even if you implemented the hook, and the metadata does not mention it. On, the metadata gains the `jwt-bearer` grant type and lists `urn:ietf:params:oauth:grant-profile:id-jag` in `authorization_grant_profiles_supported`, the field the extension uses to advertise support. (This SDK's client never reads it: it is provisioned for one issuer and simply asks.)
88
88
***`exchange_identity_assertion`** is the hook. Before it runs, the SDK has authenticated the client, refused public clients, and refused clients whose registration does not list the grant. You get an `IdentityAssertionParams` (the raw `assertion`, the requested `scopes` and `resource`) and return a plain `OAuthToken`.
89
+
* Refusing public clients is SDK policy, not a spec requirement. A client identified by a Client ID Metadata Document has no secret, so it can't use this grant here, and the built-in server doesn't resolve those documents yet ([#1801](https://github.com/modelcontextprotocol/python-sdk/issues/1801)). A deployment that wants a different policy can swap the `/token` route that `create_auth_routes` returns for its own.
89
90
* Dynamic client registration refuses this grant unconditionally, so `get_client` here serves a hand-provisioned client. An ID-JAG client cannot register itself into existence.
90
91
* Half the class is refusals. `OAuthAuthorizationServerProvider` is the *whole* authorization server, so it also asks for the authorization-code flow; a server that signs users in as well implements those for real, and this one has exactly one door.
0 commit comments