guide
guide7 min read

How to govern MCP servers and agents accessing a data warehouse

Approvals, audit logs and write control for agents that touch production data

To govern MCP servers and agents accessing a data warehouse, put a policy layer between the agent and the database: default every connection to read-only, route every write through an approval step, give each agent its own scoped identity, and record every tool call in an audit log the agent cannot edit. The MCP specification defines how clients and servers talk, but it leaves authorization policy and change control to the people who deploy the server. That gap is where governance has to live.

Key Takeaways

  • •An MCP server is a database client with a natural-language front door. Govern it the way you govern any service account with warehouse access, then add controls for the fact that a model chooses the queries.
  • •Read-only by default is the single highest-value control. Writes should require an explicit, reviewable change request rather than a standing permission.
  • •Each agent needs its own identity and a scoped grant. A shared service account makes audit logs unattributable.
  • •Audit logs are only useful if they record the prompt context, the tool call, the SQL actually executed, who approved it and the result, and if the agent cannot modify them.
  • •Governance applied per tool (one server at a time) leaves gaps. Policy has to follow the data across every agent and every tool.

How to govern MCP servers and agents accessing a data warehouse

We frame the problem as one decision: should an agent's write to the warehouse go through a change request, the way a human engineer's schema migration does? Our answer is yes for anything that changes data or structure, and no for reads that stay inside a scoped, logged boundary. Everything below follows from that split.

The reason is simple. A raw MCP server exposes whatever tools its author wrote, with whatever credentials it was started with. If those credentials can write, then any prompt that reaches the model, including text inside a table, a ticket or a document the agent reads, can in principle cause a write. The OWASP Top 10 for LLM applications lists prompt injection and excessive agency as named risks for this reason. We treat excessive agency as the central design constraint: give the agent the least authority that still lets it do the job.

Step 1: Start every connection read-only

Create the warehouse role for the MCP server with SELECT on an explicit list of schemas, and nothing else. Do not rely on the server's tool descriptions to keep the model from writing; enforce it in the database role. A read-only role fails closed: if the model produces a DROP or an UPDATE, the warehouse refuses it regardless of what the prompt said.

This is also how our open-source edition behaves. The Apache 2.0 release runs locally and is read-only by default, so a team can let agents answer questions such as "What changed in the orders schema since last deploy?" or "What tables haven't been queried in 90 days?" without granting any write path at all.

Step 2: Give each agent its own scoped identity

One shared credential for every agent means the audit log can say only that "the MCP service" ran a query. Issue a distinct identity per agent, and ideally per human session the agent acts for, then grant that identity only the schemas, columns and row filters its task needs. Column-level rules matter most for PII: an agent answering a freshness question has no reason to see raw email addresses.

Our Governance Agent handles this part of the job: PII detection, RBAC policy generation and mapping controls to SOC2, GDPR and HIPAA requirements. It answers questions like "Who has access to PII columns in analytics?" so reviewers can check the grants against reality instead of against a spreadsheet that went stale months ago.

Step 3: Put writes behind a change request

Writes should not be a permission an agent holds. They should be a proposal it submits. The agent describes the change, the system shows the exact SQL, the affected objects and the downstream blast radius, and a named approver accepts or rejects it. Only then does a separate, narrowly scoped executor run it.

This mirrors how teams already handle schema migrations in code review, and it keeps the model out of the credential path entirely. The reviewer gets the answer to "What's the blast radius if I drop this column?" before approving, not after the incident. In our Pro edition, writes, approval workflows and audit trails are part of the same package, so the approval step is not something a team has to bolt on.

Step 4: Decide autonomy per domain, not globally

Not every write deserves the same scrutiny. Refreshing a derived table in a sandbox schema is a different risk from altering a finance table. A per-domain autonomy dial lets a team auto-approve low-risk classes of change, require one approver for medium risk, and require two for anything touching regulated data. The dial is a policy setting reviewed like any other, not an informal habit.

This is how our Autonomous Data Conductor is designed to work: the goal is to reduce routine data operations to zero human effort, while the autonomy level in each domain stays an explicit choice that someone owns. We wrote more about that model in our posts on autonomous data operations.

Step 5: Log every tool call in a tamper-evident audit trail

An audit log for agents needs more than a query history. For each action we want to be able to reconstruct the following:

  • •Which agent identity acted, and on whose behalf
  • •The MCP tool that was called and its arguments
  • •The SQL actually executed against the warehouse, not only the natural-language request
  • •The approver and timestamp for any write
  • •The result: rows touched, errors, and any policy that blocked the call

Store the log outside the agent's reach and make it tamper-evident, for example by chaining entries with hashes so that edits are detectable. If an agent can rewrite its own history, the log is a convenience, not a control.

Why per-tool governance leaves gaps

Most data tools secure their own silo. A warehouse has its permissions, an orchestrator has its own, a catalog has a third set, and an agent that moves between them inherits whichever is weakest. PII flows across warehouses, pipelines and notebooks, so the policy has to follow it. Data Workers enforces SAML SSO, RBAC, encryption at rest and in transit, PII redaction, retention controls and customer data isolation at the framework level across every agent, and data stays inside the customer's infrastructure.

Governance also depends on context. Our Catalog Agent keeps lineage and ownership current, which is what lets a reviewer see that a proposed change touches a gold table with a freshness SLA. Without that context, an approver is just clicking a button on SQL they cannot evaluate.

A short checklist before you expose a warehouse to agents

  • •The MCP server's warehouse role is read-only and limited to named schemas
  • •Each agent has its own identity and a column-level grant for PII
  • •Every write path is a change request with a named approver
  • •Autonomy is set per domain and documented
  • •Audit logs record the executed SQL and are not writable by agents
  • •Someone owns a quarterly review of grants against actual usage

Frequently Asked Questions

Is a read-only MCP server safe enough on its own? It removes the largest risk, accidental or injected writes, but it does not solve exposure. A read-only agent can still read PII it should not see, so column-level scoping and logging still apply.

Should agent writes to a data warehouse always require human approval? Not always. We recommend approval by default and then relaxing it per domain for low-risk, reversible changes. The decision should be explicit policy, with the exceptions written down, rather than a side effect of whatever credentials the server was started with.

Does the MCP specification handle authorization for us? The MCP specification describes the protocol and includes authorization guidance for transport, but what a given tool is allowed to do against your warehouse is defined by the server you run and the database role behind it. Treat the protocol as the transport and build policy around it.

Can we govern agents without changing the clients our engineers already use? Yes. Governance lives in the server and the warehouse role, not the client. Because every Data Workers agent is an MCP server, any MCP-compatible client connects to the same policy layer, so engineers keep their existing tools.

What should we log for audit purposes? Log the agent identity, the tool call, the executed SQL, the approver for writes, and the outcome. Keep the log in a store the agent cannot write to, and make tampering detectable.