Summary
Add OAuth bearer token authentication as an alternative to keypair JWT in the HTTP transport. This would enable browser-based OAuth (authorization code flow) for local development, where managing RSA keypairs per
developer is friction that discourages adoption.
Motivation
Our team uses Snowflake as a data warehouse and Snowflex as our Ecto adapter. In production, keypair JWT works well. But for local development, requiring each developer to generate an RSA keypair, register the
public key fingerprint in Snowflake, and manage key files adds significant onboarding overhead.
Snowflake's SQL REST API already supports OAuth bearer tokens via the X-Snowflake-Authorization-Token-Type: OAUTH header. Supporting this in Snowflex would let teams use browser-based SSO (which most orgs already
have configured) for dev environments while keeping keypair auth for production.
This isn't just our use case — Snowflake's own documentation recommends OAuth for interactive/user-facing authentication and keypair for service accounts, which maps cleanly to dev vs. production.
Proposed approach
The HTTP transport already has a clean separation between auth and query execution. The change could be scoped to:
- Add an
:auth_method option to Snowflex.Transport.Http (:keypair default, :oauth)
- When
:oauth, skip keypair validation and read a bearer token from a configurable source (e.g., :token option, or a {module, function, args} callback for refresh)
- Set the correct header —
X-Snowflake-Authorization-Token-Type: OAUTH instead of KEYPAIR_JWT
- Token refresh callback — OAuth tokens expire; a callback lets users handle refresh without Snowflex owning the OAuth flow itself
The token acquisition (browser flow, mix task, etc.) would be left to the consuming application — Snowflex would only need to accept and use the token.
Example configuration
# Dev — OAuth with a token provider callback
config :my_app, MyApp.SnowflakeRepo,
adapter: Snowflex,
transport: Snowflex.Transport.Http,
auth_method: :oauth,
token: {MyApp.Snowflake.TokenProvider, :get_token, []},
account_name: "my-org-my-account",
database: "MY_DB",
schema: "MY_SCHEMA",
warehouse: "MY_WH"
# Production — keypair (unchanged, existing behavior)
config :my_app, MyApp.SnowflakeRepo,
adapter: Snowflex,
transport: Snowflex.Transport.Http,
account_name: "my-org-my-account",
username: "service_account",
private_key_path: "/path/to/key.pem",
public_key_fingerprint: "SHA256:..."
Scope
- OAuth token usage in the HTTP transport (small change)
- Token acquisition/refresh is the consumer's responsibility (Snowflex doesn't own the OAuth flow)
- No changes to the Ecto adapter layer, query generation, or existing keypair behavior
Willingness to contribute
I'm happy to implement this and open a PR if the approach sounds reasonable. Would appreciate feedback on the interface design before starting — particularly whether a {m, f, a} callback vs. a simple :token string is preferred for the token source.
Summary
Add OAuth bearer token authentication as an alternative to keypair JWT in the HTTP transport. This would enable browser-based OAuth (authorization code flow) for local development, where managing RSA keypairs per
developer is friction that discourages adoption.
Motivation
Our team uses Snowflake as a data warehouse and Snowflex as our Ecto adapter. In production, keypair JWT works well. But for local development, requiring each developer to generate an RSA keypair, register the
public key fingerprint in Snowflake, and manage key files adds significant onboarding overhead.
Snowflake's SQL REST API already supports OAuth bearer tokens via the
X-Snowflake-Authorization-Token-Type: OAUTHheader. Supporting this in Snowflex would let teams use browser-based SSO (which most orgs alreadyhave configured) for dev environments while keeping keypair auth for production.
This isn't just our use case — Snowflake's own documentation recommends OAuth for interactive/user-facing authentication and keypair for service accounts, which maps cleanly to dev vs. production.
Proposed approach
The HTTP transport already has a clean separation between auth and query execution. The change could be scoped to:
:auth_methodoption toSnowflex.Transport.Http(:keypairdefault,:oauth):oauth, skip keypair validation and read a bearer token from a configurable source (e.g.,:tokenoption, or a{module, function, args}callback for refresh)X-Snowflake-Authorization-Token-Type: OAUTHinstead ofKEYPAIR_JWTThe token acquisition (browser flow, mix task, etc.) would be left to the consuming application — Snowflex would only need to accept and use the token.
Example configuration
Scope
Willingness to contribute
I'm happy to implement this and open a PR if the approach sounds reasonable. Would appreciate feedback on the interface design before starting — particularly whether a {m, f, a} callback vs. a simple :token string is preferred for the token source.