From 1432fa8ebb03fa5c56a9e5f267978b48c459b6bf Mon Sep 17 00:00:00 2001 From: Samuel Collard Date: Fri, 5 Sep 2025 13:02:59 -0500 Subject: [PATCH 1/5] Allow config for not forwarding Auth tokens to GraphQL API --- crates/apollo-mcp-server/src/auth.rs | 3 +++ crates/apollo-mcp-server/src/main.rs | 19 +++++++++++++++++++ crates/apollo-mcp-server/src/server.rs | 3 +++ crates/apollo-mcp-server/src/server/states.rs | 2 ++ .../src/server/states/running.rs | 8 ++++++-- .../src/server/states/starting.rs | 1 + 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/crates/apollo-mcp-server/src/auth.rs b/crates/apollo-mcp-server/src/auth.rs index fc1f4bd6..b6994f7c 100644 --- a/crates/apollo-mcp-server/src/auth.rs +++ b/crates/apollo-mcp-server/src/auth.rs @@ -46,6 +46,9 @@ pub struct Config { /// Supported OAuth scopes by this resource server pub scopes: Vec, + + /// Whether to disable the auth token passthrough to upstream API + pub disable_auth_token_passthrough: bool, } impl Config { diff --git a/crates/apollo-mcp-server/src/main.rs b/crates/apollo-mcp-server/src/main.rs index ae5102e6..51c72102 100644 --- a/crates/apollo-mcp-server/src/main.rs +++ b/crates/apollo-mcp-server/src/main.rs @@ -109,6 +109,8 @@ async fn main() -> anyhow::Result<()> { .then(|| config.graphos.graph_ref()) .transpose()?; + let transport = config.transport.clone(); + Ok(Server::builder() .transport(config.transport) .schema_source(schema_source) @@ -125,6 +127,23 @@ async fn main() -> anyhow::Result<()> { .mutation_mode(config.overrides.mutation_mode) .disable_type_description(config.overrides.disable_type_description) .disable_schema_description(config.overrides.disable_schema_description) + .disable_auth_token_passthrough(match transport { + apollo_mcp_server::server::Transport::StreamableHttp { + auth, + address: _, + port: _, + } => auth + .map(|a| a.disable_auth_token_passthrough) + .unwrap_or(true), + apollo_mcp_server::server::Transport::SSE { + auth, + address: _, + port: _, + } => auth + .map(|a| a.disable_auth_token_passthrough) + .unwrap_or(true), + apollo_mcp_server::server::Transport::Stdio => false, + }) .custom_scalar_map( config .custom_scalars diff --git a/crates/apollo-mcp-server/src/server.rs b/crates/apollo-mcp-server/src/server.rs index 96c0d772..6ef0153c 100644 --- a/crates/apollo-mcp-server/src/server.rs +++ b/crates/apollo-mcp-server/src/server.rs @@ -36,6 +36,7 @@ pub struct Server { mutation_mode: MutationMode, disable_type_description: bool, disable_schema_description: bool, + disable_auth_token_passthrough: bool, search_leaf_depth: usize, index_memory_bytes: usize, health_check: HealthCheckConfig, @@ -112,6 +113,7 @@ impl Server { mutation_mode: MutationMode, disable_type_description: bool, disable_schema_description: bool, + disable_auth_token_passthrough: bool, search_leaf_depth: usize, index_memory_bytes: usize, health_check: HealthCheckConfig, @@ -138,6 +140,7 @@ impl Server { mutation_mode, disable_type_description, disable_schema_description, + disable_auth_token_passthrough, search_leaf_depth, index_memory_bytes, health_check, diff --git a/crates/apollo-mcp-server/src/server/states.rs b/crates/apollo-mcp-server/src/server/states.rs index 81211cda..2bf71147 100644 --- a/crates/apollo-mcp-server/src/server/states.rs +++ b/crates/apollo-mcp-server/src/server/states.rs @@ -44,6 +44,7 @@ struct Config { mutation_mode: MutationMode, disable_type_description: bool, disable_schema_description: bool, + disable_auth_token_passthrough: bool, search_leaf_depth: usize, index_memory_bytes: usize, health_check: HealthCheckConfig, @@ -76,6 +77,7 @@ impl StateMachine { mutation_mode: server.mutation_mode, disable_type_description: server.disable_type_description, disable_schema_description: server.disable_schema_description, + disable_auth_token_passthrough: server.disable_auth_token_passthrough, search_leaf_depth: server.search_leaf_depth, index_memory_bytes: server.index_memory_bytes, health_check: server.health_check, diff --git a/crates/apollo-mcp-server/src/server/states/running.rs b/crates/apollo-mcp-server/src/server/states/running.rs index b1b69495..b2f1f4b4 100644 --- a/crates/apollo-mcp-server/src/server/states/running.rs +++ b/crates/apollo-mcp-server/src/server/states/running.rs @@ -52,6 +52,7 @@ pub(super) struct Running { pub(super) mutation_mode: MutationMode, pub(super) disable_type_description: bool, pub(super) disable_schema_description: bool, + pub(super) disable_auth_token_passthrough: bool, pub(super) health_check: Option, } @@ -211,8 +212,10 @@ impl ServerHandler for Running { let mut headers = self.headers.clone(); if let Some(axum_parts) = context.extensions.get::() { // Optionally extract the validated token and propagate it to upstream servers if present - if let Some(token) = axum_parts.extensions.get::() { - headers.typed_insert(token.deref().clone()); + if !self.disable_auth_token_passthrough { + if let Some(token) = axum_parts.extensions.get::() { + headers.typed_insert(token.deref().clone()); + } } // Forward the mcp-session-id header if present @@ -355,6 +358,7 @@ mod tests { mutation_mode: MutationMode::None, disable_type_description: false, disable_schema_description: false, + disable_auth_token_passthrough: false, health_check: None, }; diff --git a/crates/apollo-mcp-server/src/server/states/starting.rs b/crates/apollo-mcp-server/src/server/states/starting.rs index a23b137b..4109faca 100644 --- a/crates/apollo-mcp-server/src/server/states/starting.rs +++ b/crates/apollo-mcp-server/src/server/states/starting.rs @@ -148,6 +148,7 @@ impl Starting { mutation_mode: self.config.mutation_mode, disable_type_description: self.config.disable_type_description, disable_schema_description: self.config.disable_schema_description, + disable_auth_token_passthrough: self.config.disable_auth_token_passthrough, health_check: health_check.clone(), }; From efddadaedb10927e38b9b47fa66c26e1fda57fda Mon Sep 17 00:00:00 2001 From: Samuel Collard Date: Mon, 8 Sep 2025 09:29:26 -0500 Subject: [PATCH 2/5] use serde default to make new config optional --- crates/apollo-mcp-server/src/auth.rs | 1 + .../apollo-mcp-server/src/server/states/running.rs | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/apollo-mcp-server/src/auth.rs b/crates/apollo-mcp-server/src/auth.rs index b6994f7c..1c802828 100644 --- a/crates/apollo-mcp-server/src/auth.rs +++ b/crates/apollo-mcp-server/src/auth.rs @@ -48,6 +48,7 @@ pub struct Config { pub scopes: Vec, /// Whether to disable the auth token passthrough to upstream API + #[serde(default)] pub disable_auth_token_passthrough: bool, } diff --git a/crates/apollo-mcp-server/src/server/states/running.rs b/crates/apollo-mcp-server/src/server/states/running.rs index b2f1f4b4..92c060a5 100644 --- a/crates/apollo-mcp-server/src/server/states/running.rs +++ b/crates/apollo-mcp-server/src/server/states/running.rs @@ -212,10 +212,10 @@ impl ServerHandler for Running { let mut headers = self.headers.clone(); if let Some(axum_parts) = context.extensions.get::() { // Optionally extract the validated token and propagate it to upstream servers if present - if !self.disable_auth_token_passthrough { - if let Some(token) = axum_parts.extensions.get::() { - headers.typed_insert(token.deref().clone()); - } + if !self.disable_auth_token_passthrough + && let Some(token) = axum_parts.extensions.get::() + { + headers.typed_insert(token.deref().clone()); } // Forward the mcp-session-id header if present @@ -245,7 +245,9 @@ impl ServerHandler for Running { let mut headers = self.headers.clone(); if let Some(axum_parts) = context.extensions.get::() { // Optionally extract the validated token and propagate it to upstream servers if present - if let Some(token) = axum_parts.extensions.get::() { + if !self.disable_auth_token_passthrough + && let Some(token) = axum_parts.extensions.get::() + { headers.typed_insert(token.deref().clone()); } From 4a76bf7b6b23ac7afd8cae7e0ccb34e66922188e Mon Sep 17 00:00:00 2001 From: Samuel Collard Date: Mon, 8 Sep 2025 09:40:52 -0500 Subject: [PATCH 3/5] Changeset --- .changesets/feat_auth_token_passthrough_disable.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changesets/feat_auth_token_passthrough_disable.md diff --git a/.changesets/feat_auth_token_passthrough_disable.md b/.changesets/feat_auth_token_passthrough_disable.md new file mode 100644 index 00000000..dd9ac487 --- /dev/null +++ b/.changesets/feat_auth_token_passthrough_disable.md @@ -0,0 +1,3 @@ +### feat: Configuration for disabling authorization token passthrough - @swcollard PR #336 + +A new optional new MCP Server configuration parameter, `transport.auth.disable_auth_token_passthrough`, which is `false` by default, that when true, will no longer pass through validated Auth tokens to the GraphQL API. \ No newline at end of file From a3f054b0421b9b88bbb21206330897a6e8c70dde Mon Sep 17 00:00:00 2001 From: Samuel Collard Date: Tue, 9 Sep 2025 10:51:08 -0500 Subject: [PATCH 4/5] Fix default case in main.rs --- crates/apollo-mcp-server/src/main.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/crates/apollo-mcp-server/src/main.rs b/crates/apollo-mcp-server/src/main.rs index 51c72102..3f3d8738 100644 --- a/crates/apollo-mcp-server/src/main.rs +++ b/crates/apollo-mcp-server/src/main.rs @@ -128,21 +128,13 @@ async fn main() -> anyhow::Result<()> { .disable_type_description(config.overrides.disable_type_description) .disable_schema_description(config.overrides.disable_schema_description) .disable_auth_token_passthrough(match transport { - apollo_mcp_server::server::Transport::StreamableHttp { - auth, - address: _, - port: _, - } => auth + apollo_mcp_server::server::Transport::Stdio => false, + apollo_mcp_server::server::Transport::SSE { auth, .. } => auth .map(|a| a.disable_auth_token_passthrough) - .unwrap_or(true), - apollo_mcp_server::server::Transport::SSE { - auth, - address: _, - port: _, - } => auth + .unwrap_or(false), + apollo_mcp_server::server::Transport::StreamableHttp { auth, .. } => auth .map(|a| a.disable_auth_token_passthrough) - .unwrap_or(true), - apollo_mcp_server::server::Transport::Stdio => false, + .unwrap_or(false), }) .custom_scalar_map( config From 33d3f2dc269acae9e317b86e8442c90060d5bbaf Mon Sep 17 00:00:00 2001 From: Samuel Collard Date: Tue, 9 Sep 2025 14:27:17 -0500 Subject: [PATCH 5/5] Add new config option to documentation --- docs/source/config-file.mdx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/source/config-file.mdx b/docs/source/config-file.mdx index ba7c45dc..294bf697 100644 --- a/docs/source/config-file.mdx +++ b/docs/source/config-file.mdx @@ -165,13 +165,14 @@ The available fields depend on the value of the nested `type` key: These fields are under the top-level `transport` key, nested under the `auth` key. Learn more about [authorization and authentication](/apollo-mcp-server/auth). -| Option | Type | Default | Description | -| :----------------------- | :------------- | :------ | :------------------------------------------------------------------------------------------------- | -| `servers` | `List` | | List of upstream delegated OAuth servers (must support OIDC metadata discovery endpoint) | -| `audiences` | `List` | | List of accepted audiences from upstream signed JWTs | -| `resource` | `string` | | The externally available URL pointing to this MCP server. Can be `localhost` when testing locally. | -| `resource_documentation` | `string` | | Optional link to more documentation relating to this MCP server | -| `scopes` | `List` | | List of queryable OAuth scopes from the upstream OAuth servers | +| Option | Type | Default | Description | +| :-------------------------------- | :------------- | :------ | :------------------------------------------------------------------------------------------------- | +| `servers` | `List` | | List of upstream delegated OAuth servers (must support OIDC metadata discovery endpoint) | +| `audiences` | `List` | | List of accepted audiences from upstream signed JWTs | +| `resource` | `string` | | The externally available URL pointing to this MCP server. Can be `localhost` when testing locally. | +| `resource_documentation` | `string` | | Optional link to more documentation relating to this MCP server | +| `scopes` | `List` | | List of queryable OAuth scopes from the upstream OAuth servers | +| `disable_auth_token_passthrough` | `bool` | `false` | Optional flag to disable passing validated Authorization header to downstream API | Below is an example configuration using `StreamableHTTP` transport with authentication: