How a Snowflake MCP server actually works

Snowflake announced managed MCP servers in July 2025; they reached public preview in October 2025 and GA in November 2025. The goal is straightforward: let an AI agent pull data from a Snowflake account remotely without you standing up your own server infrastructure. The managed server bundles four tool types. Cortex Analyst turns natural language into SQL over semantic views. Cortex Search does semantic retrieval over unstructured data. Cortex Agents lets you invoke an agent as a tool. And there's plain direct SQL execution.

Two details carry most of the security weight. First, the SQL execution tool can be locked down with a read_only option. Second, every tool call runs inside Snowflake's governance perimeter, under RBAC, as the authenticating role. Snowflake frames the managed server as a governed gateway where the same masking policies and row-level security that guard your tables automatically guard tool access, with no separate permission model. That is a real convenience, and it is also why overprivilege is a design question here rather than something you bolt on afterward.

Why one natural-language question can overprivilege an agent

Think about how a human analyst used to hit production. They wrote SQL, and buried in that SQL was a LIMIT, a WHERE, some instinct that says "I don't need ten million rows to answer this." That habit quietly bounded how much data any one query returned.

Route the same question through a Cortex or SQL MCP tool and that habit is gone. One innocent prompt, say "summarize our highest-value customers," can resolve to a query that yanks large volumes of regulated data such as PII or PHI straight into the model's context in a single call. The tool executes under the connecting role's RBAC, so the agent sees exactly what that role can see, and nothing narrows it further. If the role behind your MCP server can read raw CUSTOMERS, so can any agent that reaches it, and so can any hijacked agent that reaches it. The role's grants are the blast radius.

What the MCP authorization spec requires

The MCP authorization spec, revision 2025-11-25, is where the guardrails turn normative. A protected MCP server acts as an OAuth 2.1 resource server, and the client acts as an OAuth 2.1 client. Authorization is optional overall, but HTTP-transport servers SHOULD conform. The load-bearing bits:

  • Servers MUST validate that access tokens were issued specifically for them (audience binding, per RFC 8707).
  • Clients MUST send the RFC 8707 resource parameter on authorization and token requests.
  • Tokens MUST ride in the Authorization: Bearer header on every request, and MUST NOT show up in the URI query string.
  • Clients MUST implement PKCE with S256.
  • Authorization servers SHOULD issue short-lived access tokens.

Scope minimization gets a hook too. Clients follow least privilege using the scope from the server's WWW-Authenticate challenge, and step-up authorization returns an HTTP 403 insufficient_scope when more permission is genuinely warranted. Ask for what the task needs. Escalate only when a real 403 tells you to.

Why token passthrough is the trap

The spec is blunt about one anti-pattern. An MCP server MUST NOT accept tokens that weren't issued for it, and when it calls an upstream API, it MUST NOT forward the token it got from the client. It has to use a separate token issued by the upstream authorization server.

Skip that and you've built a confused deputy. Your MCP server, sitting on broad Snowflake privilege, starts accepting or forwarding tokens minted for something else, and now the audience check that was supposed to bound access is purely decorative. Audience binding plus no passthrough is the pair that keeps one server from turning into a universal key, and you want both in place. If you want the general version of the argument, we wrote it up over on MCP server security.

Snowflake's token model, and where teams get it wrong

Most Snowflake MCP setups authenticate with Programmatic Access Tokens (PATs) or a shared service account. PATs are actually decent primitives when you configure them well. Per Snowflake's docs, a PAT can be restricted to a single role (ROLE_RESTRICTION), the token's role governs object ownership and privilege evaluation, the user must be subject to a network policy unless an authentication policy relaxes it, and expiry is set with DAYS_TO_EXPIRY. There's also MINS_TO_BYPASS_NETWORK_POLICY_REQUIREMENT, a temporary exemption you should use sparingly, plus a documented cap of 15 PATs per user counting disabled ones.

The problem is rarely the primitive itself. It is almost always the configuration: long-lived expiry, a role that is too broad, or one shared service account fanned out across every agent you own. A PAT defaults to a 15-day expiry and can be stretched all the way to 365, so DAYS_TO_EXPIRY can be short. Teams set it long and forget it exists. A long-lived, broadly-scoped, shared token is exactly the kind of credential attackers hunt for, and it is often the one they find.

The incidents that make this concrete

Two real events, and it is worth being precise about what each one is.

UNC5537 (in-the-wild, 2024). Mandiant tracked a financially motivated actor that, from around April 2024, compromised roughly 165 Snowflake customer instances using valid credentials harvested by infostealer malware, some of those credentials reportedly dating back to 2020. There was no breach of Snowflake's own environment. The common thread was customer accounts leaning on single-factor credentials without enforced MFA. Publicly reported victims include Ticketmaster/Live Nation, AT&T, Santander, and Advance Auto Parts. The takeaway for MCP is direct: a valid credential against an overprivileged account is enough to carry the whole attack.

EchoLeak / CVE-2025-32711 (proof-of-concept). Aim Labs disclosed a zero-click indirect prompt-injection chain in Microsoft 365 Copilot, reported publicly on June 11, 2025, carrying CVSS 9.3. They named the technique "LLM Scope Violation": untrusted email content makes the model reach for and exfiltrate privileged in-context data. Per the vendor reporting, it was reported to Microsoft in January 2025, patched server-side by around May 2025, and Aim Labs states it is not aware of any customers being impacted. This was research rather than an active campaign, and it shows how a hijacked agent can turn its own privilege against you.

Where OWASP's agentic Top 10 fits

On December 9, 2025 the OWASP GenAI Security Project released the OWASP Top 10 for Agentic Applications, the first flagship list built specifically for autonomous agents. ASI01 Agent Goal Hijack ranks number one. OWASP puts prompt-injection-style attacks in this bucket (hidden instructions in emails, documents, RAG results) and cites EchoLeak as an example. ASI02 Tool Misuse and Exploitation and ASI03 Identity and Privilege Abuse round out the ones that matter here.

You don't have to imagine the tool-misuse case. Researchers demonstrated a GitHub MCP prompt-injection where a malicious public issue steered an agent into exfiltrating private repository data using the agent's own permissions. Map the pattern onto Snowflake: a broadly-scoped role or shared service account (ASI03) lets a hijacked agent (ASI01) turn a harmless natural-language request into unauthorized bulk data access (ASI02). The overprivileged MCP role is the pivot that wires all three together.

How to secure a Snowflake MCP server: best practices

Here's the checklist I'd actually run, ordered roughly by leverage.

1. Bind every token to the specific MCP server with RFC 8707 audience validation, and refuse token passthrough. This closes the confused-deputy path. 2. Issue short-lived tokens, and retire long-lived shared PATs and service accounts. One credential per agent identity, expiring in minutes to hours, not months. 3. Scope the Snowflake role to least privilege. Dedicated role, read_only where you can, semantic views instead of raw tables. Grant to the question, not to the whole schema. 4. Enforce a Snowflake network policy on the token's user, so a stolen credential is dead weight off the allowed network. 5. Enforce MFA and require it through an authentication policy. Single-factor accounts with no enforced MFA were the entire root cause of UNC5537. Snowflake now enforces MFA for human users by default, but pin it with an authentication policy so it can't quietly get switched off, and keep agent identities on network-restricted PATs rather than a bare password. 6. Enable read_only on the SQL execution tool unless a tool genuinely needs to write. 7. Log and audit every tool call with enough fidelity to answer "which agent read which rows, when, under whose authority."

These are standard least-privilege controls applied to a new execution surface, not anything exotic. One caveat: treat this as an engineering threat model rather than exhaustive security advice. Your data classification, regulatory posture, and identity provider will each add their own line items.

Govern the data plane, not just the prompt

Every control above bounds what the agent will do. The stronger move is to also bound what the agent can reach, down at the data layer, before a prompt ever runs.

That's the angle we build for at DataShield, as a complement to Snowflake and Horizon rather than a replacement, and definitely not a prompt proxy. Two ideas do most of the work. First, tokenize sensitive fields at ingest, so a hijacked agent that somehow wins the RBAC lottery finds tokens where raw PII used to live. The reachable data collapses to something non-sensitive. Second, authorize per tool call. DataShield issues scope-ceiling MCP tool tokens and caps every individual call at that ceiling through a per-call dispatch pipeline, supports on-behalf-of delegation, and keeps Snowflake credentials in an encrypted connection vault instead of a shared PAT. Revoke an agent mid-session and it dies on its next call, not whenever a token happens to lapse.

Then make it provable. Every call gets sealed into a tamper-evident audit chain you can verify after the fact. Native RBAC tells you what a role could do. A verifiable chain tells you what an agent actually did. If you want the full picture, the architecture and security pages go deeper than one blog section should.

Snowflake agent workflows in practice, plus the identity and MCP risks to lock down.

Build Agent-Powered Workflows With Snowflake Cortex video

Agent-powered workflows with Snowflake (Snowflake Developers)

AI Privilege Escalation: Agentic Identity and Prompt Injection video

AI privilege escalation and agent identity (IBM Technology)

Model Context Protocol: MCP Security Risks and Prevention video

MCP security risks and prevention (Giskard)

Frequently asked questions

How do you secure a Snowflake MCP server so an AI agent isn't overprivileged?

Cap access in three layers. Give the server a dedicated, read-only, least-privilege Snowflake role that sees semantic views rather than raw tables. Bind each MCP token to that specific server with RFC 8707 audience validation, keep it short-lived, and refuse token passthrough. Enforce a network policy on the token's user, enable read_only on the SQL execution tool, and log every call. The agent inherits the connecting role's grants, so a narrower role directly reduces the blast radius.

Why is a natural-language question a bigger risk than a normal SQL query?

A human analyst usually bounded a query with LIMIT and WHERE clauses out of habit. A natural-language tool call has no such reflex, so one benign prompt can pull large volumes of regulated data such as PII or PHI into the model's context in a single call. Because the call executes under the authenticating role's RBAC, the agent can retrieve anything that role can see.

What does the MCP authorization spec require for token handling?

Per the 2025-11-25 revision, MCP servers act as OAuth 2.1 resource servers and MUST validate that tokens were issued specifically for them (RFC 8707 audience binding). Clients MUST send the resource parameter and implement PKCE with S256. Tokens go in the Authorization: Bearer header on every request and MUST NOT appear in the query string. Token passthrough to upstream APIs is forbidden, and servers SHOULD issue short-lived tokens.

Are Snowflake Programmatic Access Tokens safe to use for MCP?

They can be, if you configure them tightly. A PAT can be restricted to a single role, its role governs privilege evaluation, and the user must be subject to a network policy. The risk is configuration: a PAT defaults to a 15-day expiry and can be stretched to 365, so teams leave DAYS_TO_EXPIRY long, use a role that's too broad, or share one token across many agents. Keep expiry short, keep the role narrow, and avoid shared service accounts. Snowflake's docs also note a per-user cap of 15 PATs.

Which OWASP agentic categories apply to an overprivileged Snowflake MCP agent?

From the OWASP Top 10 for Agentic Applications, released December 9, 2025, the direct hits are ASI03 Identity and Privilege Abuse and ASI02 Tool Misuse and Exploitation, usually triggered by ASI01 Agent Goal Hijack (ranked number one, with EchoLeak as its cited example). A broadly-scoped role lets a hijacked agent turn a harmless request into unauthorized bulk data access.