@@ -236,6 +236,67 @@ This attribute may be placed on a method to provide for the tool, prompt, or res
236236XML comments may also be used ; if an `[McpServerTool ]`, `[McpServerPrompt ]`, or `[McpServerResource ]`- attributed method is marked as `partial `,
237237XML comments placed on the method will be used automatically to generate `[Description ]` attributes for the method and its parameters .
238238
239+ ## Enterprise Auth / Enterprise Managed Authorization (SEP-990)
240+
241+ The SDK provides Enterprise Auth utilities for the Identity Assertion Authorization Grant flow (SEP - 990 ),
242+ enabling enterprise SSO scenarios where users authenticate once via their enterprise Identity Provider and
243+ access MCP servers without per - server authorization prompts .
244+
245+ The flow consists of two token operations :
246+ 1 . ** RFC 8693 Token Exchange ** at the IdP : ID Token → JWT Authorization Grant (JAG )
247+ 2 . ** RFC 7523 JWT Bearer Grant ** at the MCP Server : JAG → Access Token
248+
249+ ### Using the Layer 2 utilities directly
250+
251+ ```csharp
252+ using ModelContextProtocol .Authentication ;
253+
254+ // Step 1: Exchange ID token for a JAG at the enterprise IdP
255+ var jag = await EnterpriseAuth .DiscoverAndRequestJwtAuthorizationGrantAsync (
256+ new DiscoverAndRequestJwtAuthGrantOptions
257+ {
258+ IdpUrl = " https://company.okta.com" ,
259+ Audience = " https://auth.mcp-server.example.com" ,
260+ Resource = " https://mcp-server.example.com" ,
261+ IdToken = myIdToken , // obtained via SSO/OIDC login
262+ ClientId = " idp-client-id" ,
263+ });
264+
265+ // Step 2: Exchange JAG for an access token at the MCP authorization server
266+ var tokens = await EnterpriseAuth .ExchangeJwtBearerGrantAsync (
267+ new ExchangeJwtBearerGrantOptions
268+ {
269+ TokenEndpoint = " https://auth.mcp-server.example.com/token" ,
270+ Assertion = jag ,
271+ ClientId = " mcp-client-id" ,
272+ });
273+ ```
274+
275+ ### Using the EnterpriseAuthProvider (Layer 3)
276+
277+ ```csharp
278+ var provider = new EnterpriseAuthProvider (new EnterpriseAuthProviderOptions
279+ {
280+ ClientId = " mcp-client-id" ,
281+ AssertionCallback = async (context , ct ) =>
282+ {
283+ return await EnterpriseAuth .DiscoverAndRequestJwtAuthorizationGrantAsync (
284+ new DiscoverAndRequestJwtAuthGrantOptions
285+ {
286+ IdpUrl = " https://company.okta.com" ,
287+ Audience = context .AuthorizationServerUrl .ToString (),
288+ Resource = context .ResourceUrl .ToString (),
289+ IdToken = myIdToken ,
290+ ClientId = " idp-client-id" ,
291+ }, ct );
292+ }
293+ });
294+
295+ var tokens = await provider .GetAccessTokenAsync (
296+ resourceUrl : new Uri (" https://mcp-server.example.com" ),
297+ authorizationServerUrl : new Uri (" https://auth.mcp-server.example.com" ));
298+ ```
299+
239300## Acknowledgements
240301
241302The starting point for this library was a project called [mcpdotnet ](https :// github.com/PederHP/mcpdotnet), initiated by [Peder Holdgaard Pedersen](https://github.com/PederHP). We are grateful for the work done by Peder and other contributors to that repository, which created a solid foundation for this library.
0 commit comments