feat: per-request OAuth pass-through for Snowflake connections#650
Open
namabile wants to merge 1 commit intomalloydata:mainfrom
Open
feat: per-request OAuth pass-through for Snowflake connections#650namabile wants to merge 1 commit intomalloydata:mainfrom
namabile wants to merge 1 commit intomalloydata:mainfrom
Conversation
Add support for per-request OAuth token injection on Snowflake connections. When a connection has `oauthPassthrough: true`, queries execute under the authenticated user's Snowflake role instead of using static credentials. How it works: - MCP clients send an OAuth token via the `X-Database-Token` HTTP header - The token propagates through AsyncLocalStorage (request_context.ts) so downstream code can access it without parameter threading - At query time, `getQueryResults()` creates a short-lived Snowflake connection using `authenticator: "OAUTH"` with the per-request token - Per-request connections are closed in a `finally` block to prevent Snowflake session leaks Key changes: - api-doc.yaml: Add `oauthPassthrough` boolean to SnowflakeConnection - request_context.ts: AsyncLocalStorage module for per-request tokens - server.ts: Extract X-Database-Token header, run in request context - connection.ts: OAuth config registry, per-request connection factory - model.ts: Create per-request Runtime with OAuth connections in getQueryResults(), with cleanup in finally block Includes unit tests for all new functions. Signed-off-by: namabile <nick@ultrathinksolutions.com>
02b90e8 to
8878068
Compare
Contributor
Author
Integration testing noteThis feature has been validated end-to-end in a production-like environment with:
Verified behaviors:
The CI failure on "Connection Integration Tests" is expected — fork PRs don't have access to the upstream repo's |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds opt-in per-request OAuth token pass-through for Snowflake connections, enabling queries to execute under the authenticated user's identity instead of a shared service account.
Resolves #629
Motivation
Publisher's shared connection model blocks adoption in enterprise environments where Snowflake row-level security, column masking, and audit trails depend on
CURRENT_USER. Every major BI tool supports per-user identity pass-through — this brings that capability to Publisher.What changed
request_context.ts(new) —AsyncLocalStoragecontext to carry theX-Database-Tokenheader through the request lifecycleserver.ts— MCP POST handler extracts the token header and wraps execution in request contextconnection.ts— NewoauthPassthroughflag on Snowflake config;getRequestConnections()creates per-request OAuth connections when a token is presentmodel.ts— Query execution uses per-request connections when available; OAuth connections are closed infinallyto prevent session leaksapi-doc.yaml— Documents theoauthPassthroughconfig field+573 / -133 lines across 8 files (includes tests)
Design decisions
oauthPassthrough: trueare affected. All other connections and requests without the header work exactly as before.snowflake-sdknatively supportsauthenticator: "OAUTH". BigQuery/Trino support can follow the same pattern later.Test plan
AsyncLocalStoragerequest context (request_context.spec.ts)getRequestConnections()map swapping (connection.spec.ts)Modelconstructor changes and query execution with OAuth connections (model.spec.ts)api-doc.yamlchangesX-Database-Tokenheader use shared connections unchangedSigned-off-by: namabile nick@ultrathinksolutions.com