Snowflake (Key Pair Auth)

Live

KEY PAIR

DATA WAREHOUSE

Analytics

Every database, schema, and analytical workload your backend connects to lives in Snowflake. Snowflake (Key Pair Auth) MCP gives your agent server-to-server authenticated access using an RSA key pair — no user OAuth required.

  • Key pair configured once: An RSA private key is vaulted once by an admin. No user OAuth flow required.
  • Credentials stay vaulted: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: Permissions enforced. 90-day audit trail.
Snowflake (Key Pair Auth)
agent · Acme Q3
Run
Run a query for monthly active users by product tier over the last 6 months.
S
sfkp_query_run
1.3s
Analytics agent
6-month MAU complete. Enterprise: 3,840 avg/month (+11%). Pro: 12,200 avg/month (+4%). Starter: 28,400 avg/month (-2%). Query scanned 8.1 GB, 0.07 credits used.
Sources: analytics.active_users, 6 months
snowflakekeypairauthmcp
1 query
18:29
Message Claude...

Tools your analytics agent reaches for on Snowflake (Key Pair Auth), scoped per key pair identity.

CALL ANY TOOL
List databases and schemas, inspect tables, run SQL queries under key pair identity, and monitor query cost.
sfkp_databases_list
List databases
List all databases accessible under the key pair identity.
Parameters
Name
Type
Required
Description
No parameters required
sfkp_schemas_list
List schemas
sfkp_tables_list
List tables
sfkp_query_run
Run query
sfkp_query_status
Get query status
Build your Agent
Drop the toolkit in, point it at the user, and your analytics agent can use Snowflake (Key Pair Auth) from the first run.
import { ScalekitClient } from "@scalekit-sdk/node";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { z } from "zod";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["snowflakekeypairauth"], toolNames: ["sfkp_databases_list", "sfkp_schemas_list", "sfkp_tables_list"] },
pageSize: 100,
});

const lcTools = tools.map((t) => new DynamicStructuredTool({
name: t.tool.definition.name,
description: t.tool.definition.description,
schema: z.object({}).passthrough(),
func: async (args) => {
const { data } = await sk.tools.executeTool({
toolName: t.tool.definition.name,
identifier: "user_123",
params: args,
});
return JSON.stringify(data);
},
}));

const agent = createReactAgent({ llm, tools: lcTools });
import { ScalekitClient } from "@scalekit-sdk/node";
import OpenAI from "openai";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["snowflakekeypairauth"], toolNames: ["sfkp_databases_list", "sfkp_schemas_list", "sfkp_tables_list"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
type: "function",
function: {
name: t.tool.definition.name,
description: t.tool.definition.description,
parameters: t.tool.definition.input_schema,
},
}));

const resp = await openai.responses.create({
model: "gpt-4o", input: prompt, tools: llmTools,
});
import { ScalekitClient } from "@scalekit-sdk/node";
import Anthropic from "@anthropic-ai/sdk";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["snowflakekeypairauth"], toolNames: ["sfkp_databases_list", "sfkp_schemas_list", "sfkp_tables_list"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
name: t.tool.definition.name,
description: t.tool.definition.description,
input_schema: t.tool.definition.input_schema,
}));

const msg = await anthropic.messages.create({
model: "claude-sonnet-4-6", max_tokens: 1024,
tools: llmTools,
messages: [{ role: "user", content: prompt }],
});
import { Agent } from "@google/adk/agents";
import {
MCPToolset, StreamableHTTPConnectionParams,
} from "@google/adk/tools/mcp";

const toolset = new MCPToolset({
connectionParams: new StreamableHTTPConnectionParams({
url: "https://mcp.scalekit.com/snowflakekeypairauth",
headers: { Authorization: `Bearer ${userScopedToken}` },
}),
});

const agent = new Agent({
name: "agent", model: "gemini-2.0-flash",
tools: await toolset.getTools(),
});
Try these prompts
Paste any prompt into your agent to start using Snowflake (Key Pair Auth).
Schema & discovery
Copy the prompt
Copied
List all databases accessible via key pair.
Copy the prompt
Copied
Show schemas in [database].
Copy the prompt
Copied
List tables in [database.schema].
Copy the prompt
Copied
Get column types for [table].
Query & analysis
Copy the prompt
Copied
Monthly active users by tier for last 6 months.
Copy the prompt
Copied
Daily churn rate last 30 days.
Copy the prompt
Copied
Top 10 accounts by revenue this quarter.
Copy the prompt
Copied
Run: SELECT date_trunc('month', ts), count(distinct user_id) FROM sessions GROUP BY 1.
Monitoring & ops
Copy the prompt
Copied
Which queries scanned the most data today?
Copy the prompt
Copied
Get status for query [id].
Copy the prompt
Copied
Credits used this month.
Copy the prompt
Copied
List tables modified in the last 24 hours.
SEE HOW AUTH WORKS
Configure the key pair once. Scalekit vaults it, resolves at request time, and logs every call.
1
Authorize
Your user connects
Snowflake (Key Pair Auth)
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Snowflake (Key Pair Auth)
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Snowflake (Key Pair Auth)
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Snowflake (Key Pair Auth)
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
Same per-user auth pattern across other analytics agents and MCP connectors. Working code, live demos, fork what fits.
GTM
Salesforce customer insights agent
Surface Salesforce account activity, NPS signals, and renewal flags into Slack threads for the account team.
ENGINEERING
DevOps assistant agent
Triage GitHub incidents, open Linear tickets, and notify the on-call channel in Slack with context already attached.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
Other connector libraries treat auth as a demo afterthought. Scalekit starts with user identity, scope enforcement, and audit.
01.
Shared tokens break per-user analytics
A shared token looks fine in a demo. In production every call looks like a service account. Scalekit resolves the real user credential so attribution, audit, and scope stay accurate.
// shared token
 audit → bot_service_account
 user_filter → broken

 // scalekit
 audit → user_abc
 scope → enforced ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Snowflake (Key Pair Auth) today. Others tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent use a service account or a user credential?
A key pair. A Snowflake RSA private key is configured once by an admin and vaulted in Scalekit. Every call runs under that key pair identity — no user OAuth flow required.
Where is the Snowflake (Key Pair Auth) private key stored?
In Scalekit's managed AES-256 token vault. The PEM key is never stored on disk or passed to the LLM. Rotation is a single vault update. The key never appears in prompts, logs, or agent context.
Can I limit what the agent is allowed to query in Snowflake?
Yes. Pass a tool name filter to listScopedTools so the analytics agent only sees the subset you authorize. Scope the Snowflake role to the minimum warehouses and databases required — Scalekit enforces both layers.
What happens if the RSA key is rotated?
Update the key in the Scalekit vault. No code changes required. Subsequent calls resolve the new key automatically. The old key can be deactivated in Snowflake immediately after the vault update. The event is logged for audit.
Can the agent run write operations under the key pair identity?
Yes, if the Snowflake role grants write access. The key pair identity has the same object-level privileges as the role it is mapped to. Restrict write access by scoping the Snowflake role to read-only where appropriate.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""snowflakekeypairauth"": {
""url"": ""https://mcp.scalekit.com/snowflakekeypairauth"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.snowflakekeypairauth]
url = ""https://mcp.scalekit.com/snowflakekeypairauth""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""snowflakekeypairauth"": {
""url"": ""https://mcp.scalekit.com/snowflakekeypairauth"",
""type"": ""http""
}
}
}