The six clauses every agent access policy needs
A production database access policy for AI agents needs six clauses: a unique identity per agent, an explicit table and operation scope, approval thresholds for risky actions, logging requirements, a revocation procedure, and an escalation path. Write one policy record per agent, phrase every clause as a testable statement, and treat the document as an engineering artifact that maps one-to-one onto grants and gateway rules. This is an engineering checklist, not legal advice: if your industry has regulatory obligations, involve counsel as well.
Most teams already have an access policy for humans. It usually says something like "production access requires a ticket, credentials are personal, and admin actions are reviewed." That policy quietly assumes the principal can be interviewed, disciplined, and trusted to hesitate. An AI agent is a non-human principal: it executes at machine speed, never hesitates, and will act on whatever text reaches its context window, including text an attacker planted. The moment agents hold credentials, the human policy stops covering your riskiest principal, and you need a document that does.
The rest of this guide walks the six clauses, gives you a copy-paste template and a filled-in example, shows what the policy looks like when it lands in Postgres, and maps the clauses to the SOC 2 and EU AI Act obligations they generate evidence for. All of it is bundled as a downloadable kit if you would rather start from the file.
The policy as a gate: the six clauses define which agent operations reach the database and which are denied.
Start from your human access policy, then close the gaps
If you already have a production database access policy for people, do not throw it away: every assumption it makes points at the clause your agent policy needs. The mapping is almost mechanical.
| Human policy assumption | Why it breaks for an AI agent | The clause that replaces it |
|---|---|---|
| Credentials are personal | Agents are software; their credentials hide among service accounts | 1. Identity per agent |
| Access "as needed", judgment applies | The agent's "judgment" is whatever text reached its context window | 2. Explicit scope, default deny |
| Admins hesitate before risky commands | Agents execute at machine speed and never hesitate | 3. Approval thresholds |
| We can ask whoever did it | You can only replay what was logged | 4. Logging requirements |
| Offboarding removes access | Nobody offboards an agent; it is not in the HR system | 5. Revocation and expiry |
| Incidents start with a human noticing | Violations fire at machine speed, off-hours included | 6. Escalation |
Teams that write the agent policy as a delta from the human policy get two benefits: reviewers recognize the structure, and the generic clauses (ticketing, personal accountability, periodic review) stay shared instead of being duplicated.
Walking the six clauses
1. Identity per agent. Every agent gets its own named principal: its own database role, its own API credential, its own entry in your inventory. No shared "automation" user, and never the application's connection string. Identity is the clause everything else hangs on, because scope, logging, and revocation all attach to a principal. If two agents share a login, you can revoke neither one alone and attribute nothing to either. Why grants alone are not the whole story is covered in read-only isn't enough.
2. Table and operation scope. Name the schemas and tables the agent may touch and the operations it may perform on each, and state that everything else is denied. "Read access to reporting tables" is a policy statement; "access as needed" is not. Scope should be written in terms the database can enforce: SELECT on these objects, INSERT on those, nothing on the rest. PostgreSQL's privilege system supports exactly this granularity through GRANT and REVOKE on individual tables (PostgreSQL docs).
3. Approval thresholds. Define which operations run autonomously and which pause for a human. A useful default: bounded reads run freely; schema changes, bulk writes, and anything touching tables tagged sensitive require a named approver before execution. Put numbers on it where you can (rows affected, tables touched) so the threshold is mechanical, not a vibe. The design of that approval gate, and how to keep it from becoming a bottleneck, is its own topic: see human-in-the-loop database migrations.
4. Logging requirements. State what gets recorded for every operation: the agent identity, the exact statement, the objects touched, the decision (allowed, denied, or approved and by whom), and a timestamp. State where the log lives and how long it is kept. If you deploy agents in the EU, note that the AI Act's Article 26 requires deployers of high-risk AI systems to keep automatically generated logs for at least six months (EU AI Act, Article 26); even outside that regime, six months is a sane floor. Why that record has to live outside the agent itself, and what a tamper-evident version looks like, is covered in audit trails for AI agents.
5. Revocation. Write down, in advance, how access is removed and how fast. Credential expiry should be automatic: in Postgres, CREATE ROLE ... VALID UNTIL puts a hard expiry date on a password at creation time (PostgreSQL docs). The policy should also name a kill switch: the single command or console action that severs the agent's connectivity immediately, and who is allowed to pull it. If revoking an agent requires a change request, you do not have revocation, you have a suggestion.
6. Escalation. Define what happens when the policy is violated or nearly violated: who gets paged when a denied operation fires, what counts as an incident versus noise, and when the default response is to suspend the agent rather than investigate while it keeps running. Agents fail at machine speed, so the escalation clause should bias toward stopping first and asking questions second.
The copy-paste template
Tool-agnostic AI agent database access policy template. One record per agent. Replace the bracketed values, delete nothing without a reason, and store it next to your infrastructure code so changes go through review.
# AI Agent Database Access Policy: one record per agent
# Engineering checklist. Not legal advice.
agent:
name: [agent-name, e.g. support-copilot]
owner: [team or person accountable]
purpose: [one sentence: what this agent does and why it needs data access]
principal: [dedicated credential, e.g. db role "agent_support_copilot"]
shared_credentials: forbidden
scope:
databases: [list]
allowed:
- object: [schema.table or pattern]
operations: [SELECT | INSERT | UPDATE | DELETE | DDL]
conditions: [row limits, column exclusions, tenant filters]
default: deny # anything not listed above is denied
approval:
autonomous: [e.g. SELECT under 10000 rows on non-sensitive tables]
requires_human:
- all DDL (schema changes)
- writes affecting more than [N] rows
- any operation on tables tagged [sensitive-tag]
approvers: [named role or group, not an individual]
approval_record: [where approvals are stored]
logging:
record_per_operation:
- agent identity and session id
- exact statement or operation
- objects touched and rows affected
- decision: allowed | denied | approved_by [who]
- timestamp (UTC)
destination: [append-only store, outside the agent's reach]
retention: [>= 6 months]
revocation:
credential_expiry: [max lifetime, e.g. 90 days, auto-enforced]
kill_switch: [exact command or console action]
kill_switch_owners: [who may execute it]
max_time_to_revoke: [target, e.g. 5 minutes]
escalation:
on_denied_operation: [alert channel and severity]
on_repeated_denials: [suspend agent pending review]
on_sensitive_data_access: [page on-call, open incident]
review_cadence: [re-review this policy every N days]
Every line in that template is checkable. That is the test of a good policy clause: someone can look at the running system and say true or false, the system matches the document.
Take the whole kit. The template above, the filled-in example below, the Postgres commands, a quarterly review checklist, and the compliance cross-reference are bundled as one file you can drop into your repo: download the AI Agent Database Access Policy Kit (Markdown, no signup).
A filled-in example: the support copilot
Templates hide the hard part, which is committing to actual values. Here is the same record completed for a real-shaped agent: a support copilot that reads tickets and tags them, and nothing else.
agent:
name: support-copilot
owner: support-engineering
purpose: Summarizes and tags inbound tickets using ticket history.
principal: db role "agent_support_copilot"
shared_credentials: forbidden
scope:
databases: [app]
allowed:
- object: support.tickets
operations: [SELECT]
conditions: no customer_email column; max 5000 rows per query
- object: support.ticket_messages
operations: [SELECT]
conditions: max 5000 rows per query
- object: support.ticket_tags
operations: [SELECT, INSERT]
conditions: inserts limited to 1 row per operation
default: deny
approval:
autonomous: all reads within scope; single-row tag inserts
requires_human: [all DDL, any UPDATE or DELETE, anything outside scope]
approvers: support-engineering on-call
approval_record: "#agent-approvals" channel, mirrored to the audit log
logging:
destination: append-only audit store (separate credentials)
retention: 12 months
revocation:
credential_expiry: 90 days
kill_switch: REVOKE CONNECT ON DATABASE app FROM agent_support_copilot;
kill_switch_owners: [dba on-call, support-engineering lead]
max_time_to_revoke: 5 minutes
escalation:
on_denied_operation: alert #agent-alerts, low severity
on_repeated_denials: 3 denials in 10 minutes suspends the agent
on_sensitive_data_access: page on-call, open incident
review_cadence: 90 days
Notice what committing to values forced: a column exclusion (the copilot never needs customer_email), a row cap that makes "bounded read" mean something, and a kill switch that is one SQL statement two named people can run. Those decisions are the policy. The template is just where they live.
Landing the policy in Postgres
The template is database-agnostic on purpose, but here is what clauses one, two, and five look like when they hit a Postgres instance. Any engine with roles and grants can express the same shape.
-- Clause 1: identity per agent, with clause 5's expiry built in CREATE ROLE agent_support_copilot LOGIN VALID UNTIL '2026-10-17'; -- credential auto-expires in 90 days -- Clause 2: explicit scope, default deny REVOKE ALL ON ALL TABLES IN SCHEMA public FROM agent_support_copilot; GRANT SELECT ON support.tickets, support.ticket_messages TO agent_support_copilot; GRANT SELECT, INSERT ON support.ticket_tags TO agent_support_copilot; -- Clause 5: the kill switch -- REVOKE CONNECT ON DATABASE app FROM agent_support_copilot;
Clauses three, four, and six do not fit inside the engine, and that is the honest limit of grants: Postgres can say what a role may do, but it cannot pause a statement for approval, attach an approver's name to it, or page anyone when a denied operation fires. Those clauses need something on the connection path in front of the database; the full architecture is the subject of safe AI agent access to production databases.
What the policy is worth to SOC 2 and the EU AI Act
The six clauses were designed for safety, but they double as compliance evidence, because auditors ask the same questions the policy answers: who is this principal, what may it do, who approved that, where is the record. As a rough map, not a compliance checklist:
| Policy clause | SOC 2 (Trust Services Criteria) | EU AI Act |
|---|---|---|
| 1. Identity per agent | CC6.1: logical access restricted to authorized principals | Art. 26: deployer oversight of the system |
| 2. Scope, default deny | CC6.3: access granted by role, least privilege | none |
| 3. Approval thresholds | CC8.1: changes authorized before execution | Art. 26: human oversight by competent persons |
| 4. Logging | CC7.2: anomalous activity monitored | Art. 26: retain system logs at least six months |
| 5. Revocation | CC6.2: credentials managed over their lifecycle | none |
| 6. Escalation | CC7.3 / CC7.4: security events evaluated and responded to | Art. 26: incident duties when risks materialize |
Two honest caveats. First, mappings like this satisfy an auditor only when the clause is enforced and generates records, which is the argument for putting enforcement on the connection path. Second, whether your agent deployment is "high-risk" under the AI Act is a legal determination, not an engineering one; the six-month log floor is simply a sane default either way.
Rolling it out without stopping the team
Day 0: inventory and write. List every agent that currently holds a database credential. This step embarrasses almost everyone: copilots wired up in a hackathon, an "analytics bot" using the app's connection string. Write one policy record per agent describing what it does today, even where today's reality is ugly. You cannot tighten what you have not written down.
By day 30: identity and scope. Give each agent its own role and cut grants down to the written scope. This is pure engine work, the SQL above, and it removes the worst risks (shared credentials, unbounded scope) without any new infrastructure. Stand up logging wherever operations already pass through a choke point.
By day 90: gates and escalation. Put a gateway on the connection path so approval thresholds and default-deny are enforced rather than hoped for, wire denied operations to an alert channel, and run the first scheduled review. From here the policy is alive: the review cadence keeps it matched to reality.
A policy the agent can read is not enforcement
One failure mode deserves its own warning. Teams sometimes implement the policy by pasting it into the agent's system prompt: "you may only run SELECT on the support schema." That is documentation. It enforces nothing. Prompt injection is the top entry in the OWASP Top 10 for LLM Applications because models cannot reliably separate trusted instructions from untrusted input in the same context window (OWASP LLM01), so any rule the agent can read is a rule a crafted input can talk it out of.
The policy document defines the boundary. The database grants and a gateway on the connection path enforce it, outside anything the agent's context can influence. How those two enforcement layers fit together is the subject of safe AI agent access to production databases; this guide is about getting the boundary written down well enough that there is something coherent to enforce.
Five mistakes that make the policy useless
- One blanket policy for "automation". Scope, revocation, and attribution only work per principal. A policy that covers "all bots" governs none of them.
- Scope written as intentions. "The agent only handles support data" is a hope.
GRANT SELECT ON support.ticketsis a scope. If a clause cannot be checked against the running system, rewrite it until it can. - The policy lives in the system prompt. See above: that is documentation the agent is free to be talked out of, not enforcement.
- A kill switch nobody owns. If the answer to "who can cut this agent off right now" is a discussion, the revocation clause is fiction. Name the owners and have them run the drill once.
- Logs the agent can reach. An audit trail stored in the same database, readable and writable with the same credential, is not a record of what the agent did. It is a draft the agent can edit.
Keep the document alive
Two habits keep the policy from rotting. First, re-review on a schedule (the review_cadence line exists for a reason): agents gain capabilities, schemas grow, and a scope that was tight in March is stale by September. Second, treat every denied operation as data. A denial either caught a real overreach, in which case the escalation clause did its job, or it blocked legitimate work, in which case the scope clause needs a deliberate, reviewed amendment. Either way the document moves, and it moves through review rather than through someone quietly widening a grant.
Where Datapace fits
Datapace is building the context layer for AI on databases: a living, reviewed account of what's there, what it means, how it connects, and what it costs to run, served to agents over MCP, so the scope you write in this policy refers to data that is actually documented, with a policy gate over what AI may do and access, so clauses like scope, approval thresholds, and logging are enforced outside the agent's prompt rather than trusted to it. We fix the base so your team can work on better things. If you are writing this policy for your own team, we would like to compare notes: start at datapace.ai or book a call.