Skip to content

Add token_provider for short-lived MCP auth in common.ai#68104

Merged
kaxil merged 1 commit into
apache:mainfrom
astronomer:mcphook-token-provider
Jun 6, 2026
Merged

Add token_provider for short-lived MCP auth in common.ai#68104
kaxil merged 1 commit into
apache:mainfrom
astronomer:mcphook-token-provider

Conversation

@kaxil

@kaxil kaxil commented Jun 5, 2026

Copy link
Copy Markdown
Member

Summary

MCPHook built the MCP server with a single static Authorization header taken from the connection password, so it could not authenticate to MCP endpoints that require a freshly minted or short-lived token. The motivating case is a Snowflake managed MCP server, best authenticated with a key-pair JWT that expires after about an hour and cannot be stored as a static value. The same limit blocked OAuth/refresh tokens, Workload Identity Federation, and GitHub App installation tokens.

MCPHook and MCPToolset now accept an optional token_provider callable.

How it works

  • When token_provider is set, it is invoked each time the HTTP/SSE server connection is established and its return value is used as the bearer token, overriding the static password.
  • The minted token is registered with secret masking (matching the auto-masking the connection password already receives), so it does not leak into task logs.
  • A provider that returns a non-string or empty value fails loud rather than silently sending an unauthenticated request.
  • token_provider is resolved in DAG code (a Python callable, not a stored connection field), so the signing key never enters the serialized DAG.

Usage

def mint_snowflake_jwt() -> str:
    ...  # sign a short-lived JWT from the connection's key-pair


MCPToolset(mcp_conn_id="snowflake_managed_mcp", token_provider=mint_snowflake_jwt)

Gotchas

  • token_provider applies to HTTP/SSE transports only; it is ignored for stdio (which has no HTTP headers).
  • The provider is called when the server connection is established; the resulting server is cached for the toolset instance's lifetime (one task run), so the token must remain valid for that run.

MCPHook built the MCP server with a single static Authorization header from the
connection password, so it could not authenticate to MCP endpoints that require
a freshly minted or short-lived token. The motivating case is a Snowflake
managed MCP server, best authenticated with a key-pair JWT that expires after
about an hour and cannot be stored as a static connection value; the same limit
blocked OAuth/refresh tokens, Workload Identity Federation, and GitHub App
installation tokens.

MCPHook and MCPToolset now accept an optional token_provider callable. When set,
it is invoked each time the HTTP/SSE server connection is established and its
return value is used as the bearer token, overriding the static password. The
minted token is registered with secret masking (matching the auto-masking the
connection password already receives) so it does not leak into task logs, and a
provider that returns a non-string or empty value fails loud instead of silently
sending an unauthenticated request. token_provider is resolved in DAG code, so
the signing key never enters the serialized DAG.
@kaxil kaxil force-pushed the mcphook-token-provider branch from 8629355 to f9520b2 Compare June 5, 2026 22:35
@kaxil kaxil merged commit d4a5294 into apache:main Jun 6, 2026
94 checks passed
@kaxil kaxil deleted the mcphook-token-provider branch June 6, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants