diff --git a/docs/protocol.md b/docs/protocol.md index 75c5d127..e3b9e8c2 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -8,7 +8,12 @@ 1. [Custom transports](#custom-transports) 1. [Concurrency](#concurrency) 1. [Authorization](#authorization) + 1. [Server](#server) + 1. [Client](#client) 1. [Security](#security) + 1. [Confused Deputy](#confused-deputy) + 1. [Token Passthrough](#token-passthrough) + 1. [Session Hijacking](#session-hijacking) 1. [Utilities](#utilities) 1. [Cancellation](#cancellation) 1. [Ping](#ping) @@ -232,11 +237,67 @@ for more background. ## Authorization - +### Server + +To write an MCP server that performs authorization, +use [`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken). +This function is middleware that wraps an HTTP handler, such as the one returned +by [`NewStreamableHTTPHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#NewStreamableHTTPHandler), to provide support for verifying bearer tokens. +The middleware function checks every request for an Authorization header with a bearer token, +and invokes the +[`TokenVerifier`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#TokenVerifier) + passed to `RequireBearerToken` to parse the token and perform validation. +The middleware function checks expiration and scopes (if they are provided in +[`RequireBearerTokenOptions.Scopes`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerTokenOptions.Scopes)), so the +`TokenVerifer` doesn't have to. +If [`RequireBearerTokenOptions.ResourceMetadataURL`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerTokenOptions.ResourceMetadataURL) is set and verification fails, +the middleware function sets the WWW-Authenticate header as required by the [Protected Resource +Metadata spec](https://datatracker.ietf.org/doc/html/rfc9728). + +The [_auth middleware example_](https://github.com/modelcontextprotocol/go-sdk/tree/main/examples/server/auth-middleware) shows how to implement authorization for both JWT tokens and API keys. + +### Client + +Client-side OAuth is implemented by setting +[`StreamableClientTransport.HTTPClient`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk@v0.5.0/mcp#StreamableClientTransport.HTTPClient) to a custom [`http.Client`](https://pkg.go.dev/net/http#Client) +Additional support is forthcoming; see #493. ## Security - +Here we discuss the mitigations described under +the MCP spec's [Security Best Practices](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices) section, and how we handle them. + +### Confused Deputy + +The [mitigation](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation), obtaining user consent for dynamically registered clients, +happens on the MCP client. At present we don't provide client-side OAuth support. + + +### Token Passthrough + +The [mitigation](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation-2), accepting only tokens that were issued for the server, depends on the structure +of tokens and is the responsibility of the +[`TokenVerifier`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#TokenVerifier) +provided to +[`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken). + +### Session Hijacking + +The [mitigations](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation-3) are as follows: + +- _Verify all inbound requests_. The [`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken) +middleware function will verify all HTTP requests that it receives. It is the +user's responsibility to wrap that function around all handlers in their server. + +- _Secure session IDs_. This SDK generates cryptographically secure session IDs by default. +If you create your own with +[`ServerOptions.GetSessionID`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.GetSessionID), it is your responsibility to ensure they are secure. +If you are using Go 1.24 or above, +we recommend using [`crypto/rand.Text`](https://pkg.go.dev/crypto/rand#Text) + +- _Binding session IDs to user information_. This is an application requirement, out of scope +for the SDK. You can create your own session IDs by setting +[`ServerOptions.GetSessionID`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.GetSessionID). ## Utilities diff --git a/internal/docs/protocol.src.md b/internal/docs/protocol.src.md index 2bb954bf..0abd5aa8 100644 --- a/internal/docs/protocol.src.md +++ b/internal/docs/protocol.src.md @@ -164,11 +164,67 @@ for more background. ## Authorization - +### Server + +To write an MCP server that performs authorization, +use [`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken). +This function is middleware that wraps an HTTP handler, such as the one returned +by [`NewStreamableHTTPHandler`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#NewStreamableHTTPHandler), to provide support for verifying bearer tokens. +The middleware function checks every request for an Authorization header with a bearer token, +and invokes the +[`TokenVerifier`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#TokenVerifier) + passed to `RequireBearerToken` to parse the token and perform validation. +The middleware function checks expiration and scopes (if they are provided in +[`RequireBearerTokenOptions.Scopes`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerTokenOptions.Scopes)), so the +`TokenVerifer` doesn't have to. +If [`RequireBearerTokenOptions.ResourceMetadataURL`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerTokenOptions.ResourceMetadataURL) is set and verification fails, +the middleware function sets the WWW-Authenticate header as required by the [Protected Resource +Metadata spec](https://datatracker.ietf.org/doc/html/rfc9728). + +The [_auth middleware example_](https://github.com/modelcontextprotocol/go-sdk/tree/main/examples/server/auth-middleware) shows how to implement authorization for both JWT tokens and API keys. + +### Client + +Client-side OAuth is implemented by setting +[`StreamableClientTransport.HTTPClient`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk@v0.5.0/mcp#StreamableClientTransport.HTTPClient) to a custom [`http.Client`](https://pkg.go.dev/net/http#Client) +Additional support is forthcoming; see #493. ## Security - +Here we discuss the mitigations described under +the MCP spec's [Security Best Practices](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices) section, and how we handle them. + +### Confused Deputy + +The [mitigation](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation), obtaining user consent for dynamically registered clients, +happens on the MCP client. At present we don't provide client-side OAuth support. + + +### Token Passthrough + +The [mitigation](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation-2), accepting only tokens that were issued for the server, depends on the structure +of tokens and is the responsibility of the +[`TokenVerifier`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#TokenVerifier) +provided to +[`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken). + +### Session Hijacking + +The [mitigations](https://modelcontextprotocol.io/specification/2025-06-18/basic/security_best_practices#mitigation-3) are as follows: + +- _Verify all inbound requests_. The [`RequireBearerToken`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/auth#RequireBearerToken) +middleware function will verify all HTTP requests that it receives. It is the +user's responsibility to wrap that function around all handlers in their server. + +- _Secure session IDs_. This SDK generates cryptographically secure session IDs by default. +If you create your own with +[`ServerOptions.GetSessionID`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.GetSessionID), it is your responsibility to ensure they are secure. +If you are using Go 1.24 or above, +we recommend using [`crypto/rand.Text`](https://pkg.go.dev/crypto/rand#Text) + +- _Binding session IDs to user information_. This is an application requirement, out of scope +for the SDK. You can create your own session IDs by setting +[`ServerOptions.GetSessionID`](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk/mcp#ServerOptions.GetSessionID). ## Utilities