How to Connect an AI Agent to Your Database (Safely)
To connect an AI agent to your database safely, give it a dedicated least-privilege, read-only role, point it at the schemas it should answer from, and turn on an audit log of every query it runs. Writes stay off by default and only execute behind human-in-the-loop approval and scoped RBAC. Get the role, the gates, and the logs right and the rest is mostly configuration.
Quick answer
To connect an AI agent to your database safely, give it a dedicated least-privilege, read-only role, point it at the schemas it should answer from, and turn on an audit log of every query it runs. Writes stay off by default and only execute behind human-in-the-loop approval and scoped RBAC. Get the role, the gates, and the logs right and the rest is mostly configuration.
Connect an AI agent to your database safely by giving it a dedicated least-privilege, read-only role, pointing it at the schemas it should answer from, and turning on an audit log that records every query it runs. Writes stay off by default and execute only behind human-in-the-loop approval and scoped RBAC. That is the whole safety model in one sentence, and the rest of this guide is the practical version of it.
Done right, this setup turns your production tables into a self-serve answer engine. A teammate asks "how many enterprise accounts churned last quarter?" and the agent generates the query, runs it under a scoped role, and replies with the number plus the SQL it used. No BI seat, no ticket to the data team, no waiting two days for a one-line answer.
Done wrong, the same connection is an open door to your most sensitive records. The difference between those two outcomes is not the model. It is the database role, the gates around writes, and the log that proves what ran. This guide walks through the exact steps, the worked example, the pitfalls that bite teams, and a simple framework for deciding read-only versus read-write.
What does connecting an AI agent to a database actually do?
Before wiring anything up, be precise about what happens under the hood. The phrase "connect an AI agent to your database" hides a four-step pipeline, and each step is a place where governance either holds or fails. An AI agent connected to a database does this in sequence:
- Reads your schema - table and column names, types, and relationships - so it knows what is queryable
- Translates a plain-language question into a SQL query grounded in those real names
- Executes that query through a connection scoped to a specific database role
- Returns the result, and ideally the generated SQL, so the answer is verifiable
The critical insight: the agent's power is bounded entirely by the database role it connects through. The model can be clever, persuasive, or jailbroken, but it can never do more than the connection's permissions allow. If the role can only SELECT, then no prompt - friendly or malicious - turns it into a DELETE.
This is why governance starts at the role, not at the prompt. A clever system prompt that says "never modify data" is a suggestion. A read-only Postgres role that lacks UPDATE privileges is a wall. You want the wall. Treat anything you write in the prompt as a usability nicety layered on top of permissions that are enforced by the database engine itself.
Step 1: Create a least-privilege, read-only database role
The single most important decision is the role the agent connects through. For analytics and question-answering use cases, that role should be read-only. Create a dedicated database user just for the agent. Never reuse an application service account or an admin account, because if the agent's credentials leak or its behavior goes sideways, you want the blast radius scoped to exactly what an analyst should see and nothing more.
Grant that role only the minimum it needs:
- GRANT SELECT only, on the specific schemas or tables the agent should answer from
- No INSERT, UPDATE, DELETE, DROP, or other DDL privileges, ever
- No access to tables holding secrets, credentials, API keys, or unrelated tenant data
- Column-level grants or restricted views that keep sensitive fields like PII, salary, and payment data out of reach
- A connection-level statement timeout so a runaway query cannot pin your primary database
If the agent only ever needs to read, a read-only role means a buggy or adversarial prompt simply cannot mutate data. The database rejects the attempt at the permission layer, before any application logic runs. That is defense in depth: the model can misbehave and the system still holds.
Two refinements matter for production. First, point the agent at a read replica rather than your primary when you can, so analytical queries never compete with transactional traffic. Second, for multi-tenant databases, scope the role further with row-level security or per-tenant views so the agent can only ever return rows the requesting user is allowed to see. Row-level security is the difference between "the agent reads the orders table" and "the agent reads only this customer's orders."
“Rule of thumb: give the agent a role you would be comfortable handing to a brand-new analyst on day one - read-only, scoped to a few schemas, and never the keys to the whole warehouse.”
How read-only and read-write setups compare
Most teams start read-only and add narrow write access later, table by table. The two postures carry very different risk and require different controls. Use this scorecard to decide what you actually need before you grant a single extra privilege.
| Capability | Read-only role | Governed read-write role |
|---|---|---|
| Answer plain-language questions | Yes | Yes |
| Generate and run SELECT queries | Yes | Yes |
| Modify or insert records | No, blocked by the engine | Yes, only on granted tables |
| Human-in-the-loop approval | Not required | Required on every write |
| Destructive ops (DELETE, DROP, bulk UPDATE) | Impossible by design | Approval-gated, off by default |
| Blast radius if compromised | Reads within scope only | Limited to granted tables and gates |
| Setup effort | Low | Moderate, per table |
| Best for | Analytics, reporting, self-serve Q&A | Status updates, record edits, maintenance |
The honest answer for most analytics and reporting use cases is the left column. You get the entire value of natural-language querying with almost none of the risk. Only reach for the right column when a real workflow needs to change data, and even then, grant the narrowest write you can.
Step 2: Connect the database through Onpilot
With the role in place, add the database as an integration. Onpilot connects to common SQL databases through its integration catalog, and the connection stores credentials securely rather than exposing them to the model or to end users. End users never type a connection string, never see a password, and never touch SQL.
The high-level setup is the same regardless of which SQL engine you run:
- Add the database from the integrations catalog and provide the connection string for your read-only role
- Point the agent at the schemas or views you want it to answer from, and exclude the rest
- Confirm the agent can read the schema so it can ground its SQL in real table and column names
- Test with a handful of known questions and compare the agent's answer against a query you trust
Because credentials live in the connection and not in the prompt, end users never see or touch them. They ask questions in plain language, and the agent runs the SQL on their behalf under the role you configured. The same governed connection backs every channel the agent runs on - web chat, Slack, Microsoft Teams, WhatsApp, or the API - so the rules you set once apply everywhere.
Spend real time on schema grounding. An agent that knows your tables are named orders, line_items, and accounts, and that revenue lives in a column called amount_cents, writes far better SQL than one guessing from question text alone. Restricted views with friendly column names also double as a documentation layer: they tell the agent exactly what it is allowed to see and what each field means.
How a single question becomes a governed answer
It helps to see the full path from a typed question to a returned answer, with the governance checkpoints called out. Here is what happens when someone asks the agent a question against your database.
- 1
User asks
A teammate types a plain-language question in Slack, Teams, or the web widget.
- 2
Agent grounds
The agent reads the allowed schema and maps the question to real tables and columns.
- 3
SQL generated
It writes a SELECT scoped to the read-only role; writes pause for approval here.
- 4
Query runs
The statement executes under the scoped role against your database or read replica.
- 5
Answer returned
The result comes back with the SQL shown, so a technical user can verify it.
- 6
Logged
Who asked, the SQL, the role, and the result land in an immutable audit log.
Every step runs under the scoped role, and every query lands in the audit log.
Notice where the safety lives. Step three is where a write-capable request stops and waits for a human. Step four is where the database role makes the final call on what is permitted. Step six is where you get the receipt. None of those depend on the model behaving; they are enforced around it.
A worked example: the churn question
Concrete beats abstract, so walk through a real one. It is Monday morning and a RevOps manager wants to know which enterprise accounts went quiet last month. Before the agent, this was a Slack message to the data team, a wait, and a CSV. With a governed connection, it is a sentence.
She types into the agent: "Which enterprise accounts had no logins in the last 30 days, with their account owner and last activity date?"
- The agent reads the allowed schema and recognizes accounts, users, activity_events, and a plan_tier column
- It writes a SELECT joining accounts to the most recent activity_events, filtered to plan_tier = 'enterprise' and a 30-day window
- The query runs under the read-only role against a read replica, so production transactions are untouched
- It returns a clean table of 14 accounts with owners and last-activity dates, and shows the SQL it generated underneath
- The whole exchange - her question, the SQL, the role it ran under, and the row count - lands in the audit log
Now suppose she follows up with "flag those 14 as at-risk in the CRM." That is a write, and it does not silently happen. The agent drafts the update and surfaces an Approve or Reject card showing exactly which records it wants to change and to what value. A human clicks approve, the scoped write executes on only the at_risk field, and that approval is logged too. The read was instant and ungated; the write was gated and recorded. That split is the entire design.
“The read was instant and ungated. The write paused for one human click and was recorded. Designing for that split - fast reads, gated writes - is what makes a database agent shippable rather than a demo.”
Step 3: Can the agent write to the database, and how do you gate it?
Most teams start read-only. But some workflows genuinely need writes: updating a record's status, inserting a new row from an intake form, or running a scheduled maintenance task. If you grant write access, do not rely on the prompt to keep it safe. Gate it with governance:
- Grant write privileges narrowly - only the specific tables and operations the workflow requires
- Turn on human-in-the-loop approval so any write pauses for a person to approve or reject before it executes
- Use least-privilege RBAC so only certain users, roles, or channels can trigger write-capable actions
- Keep destructive operations - DELETE, DROP, bulk UPDATE - approval-gated by default and ideally off entirely
With Onpilot, an approval gate surfaces the proposed action - including the exact statement the agent wants to run and the rows it affects - as an Approve or Reject card in chat or Slack. Nothing touches your data until a human says yes. That is the difference between an agent that drafts a change and one that silently commits it.
A useful mental model: writes should feel like a pull request against your data. The agent proposes, a human reviews the diff, and only then does it merge. You would not let code reach production without a review, and your production tables deserve at least the same care.
“Default to read-only. Add write access table by table, and put every write behind an approval gate. A governed write is a feature; an ungoverned one is an incident waiting for an audit.”
Step 4: Turn on audit logs for every query
Read-only roles and approval gates prevent bad outcomes; audit logs let you prove what happened. Onpilot records each query the agent runs, so you have a traceable record of who asked what, what SQL was generated, which role executed it, and what came back. When a security reviewer asks "how do you know the agent never touched the payments table?", the log is your answer, not a shrug.
Audit logs earn their place for three reasons:
- Trust - you can show stakeholders exactly what the agent did, not just what it claimed
- Debugging - when an answer looks wrong, you can inspect the generated SQL and the role it ran under
- Compliance - reviewers and auditors can verify that access stayed within policy, query by query
Pair audit logs with the read-only role and you get a system you can defend in a security review: scoped permissions limit the blast radius, approvals gate every change, and the log proves the controls held. For regulated teams, this trail is also what makes frameworks like SOC 2 tractable, because access reviews stop being a manual archaeology project and become a query against the log.
Where the safety actually comes from
It is worth being explicit about which controls do the heavy lifting, because teams often over-index on the prompt and under-invest in the boring layers that actually contain risk. The chart below shows a rough weighting of how much each control contributes to keeping a database agent safe. The model itself, and any instructions you give it, sit near the bottom on purpose.
Illustrative weighting to show emphasis, not measured benchmark figures.
The takeaway is uncomfortable for anyone who wants to fix safety with better wording: the prompt is the smallest lever. The role, the gates, the logs, and the scoping carry the load. If you spend a day on this, spend most of it on the database role and the approval flow, and very little of it trying to engineer the perfect system prompt.
Step 5: Let users ask questions in plain language
Once the connection is governed, the experience for end users is simple: they ask questions the way they would ask a colleague. No SQL, no dashboards to build, no BI seat required, no waiting on the analytics queue.
Typical questions an AI agent on your database handles well:
- "How many trials converted to paid last month?"
- "Which accounts have had no activity in the last 30 days?"
- "Show me the top 10 customers by revenue this quarter."
- "What's the average resolution time for support tickets, by priority?"
- "Which SKUs are below reorder threshold across all warehouses?"
The agent generates the SQL, runs it under the scoped role, and returns the answer - often alongside the query so a technical user can verify it. You can also schedule these: instead of someone asking the churn question every Monday, the agent runs it on a schedule and delivers the finished result to a Slack channel before standup. Across web, Slack, Teams, WhatsApp, and the API, the same governed connection backs every channel, so the rules you set once apply everywhere.
A decision framework: read-only or read-write?
Teams waste time debating whether to give the agent write access in the abstract. Make it concrete instead. Run the workflow through these questions in order and stop at the first one that gives you an answer.
- Does the workflow only answer questions or produce reports? Stay read-only. You are done - this covers the large majority of use cases.
- Does it need to change data, but only a single non-destructive field (like a status flag)? Grant write on that one table and that one column, and require approval on every write.
- Could a mistake be expensive or hard to reverse (financial records, customer-facing data, bulk changes)? Keep it approval-gated by default and restrict who can even trigger the write via RBAC.
- Is the operation destructive - DELETE, DROP, schema changes? Do not give the agent this. Have it draft the statement for a human to run manually, or keep it permanently behind a hard approval gate.
- Are you unsure? Default to read-only and revisit. It is trivial to widen access later; it is painful to explain a write you did not intend in a postmortem.
The pattern across all five: every step that touches data should be the smallest, most scoped, most reviewed version of itself. When in doubt, the agent reads and proposes, and a human commits.
What are the common mistakes to avoid?
Most database-agent problems trace back to a handful of shortcuts. Each of these has put a real team in a bad spot, so treat them as a pre-launch checklist of what not to do:
- Connecting with an admin or application service account instead of a dedicated, scoped role - this hands the agent far more than it needs
- Granting write access globally instead of table by table, so a single bad query can reach data the workflow never touches
- Skipping approval gates on writes because read-only testing went fine, then being surprised when a write goes wrong
- Exposing raw tables with sensitive columns instead of restricted views, leaving PII and payment data one query away
- Pointing the agent at the primary database instead of a read replica, so a heavy analytical query slows real users
- Treating the prompt as a security boundary - it is not; the database role is the only boundary the engine enforces
Get the role, the gates, and the logs right, and the rest is mostly configuration. The governance is what makes an AI agent on your production database something you can ship to a security review, not just something you can demo in a meeting.
Frequently asked questions
Can an AI agent query my database?
+
Yes. Through a governed connection, the agent reads your schema, translates a plain-language question into SQL, and runs it under a database role you control. With Onpilot, the connection is scoped to least-privilege access, so the agent can only query the tables and columns you allow.
Is it safe to connect an AI agent to production data?
+
It is, when you use a least-privilege, read-only role and audit every query. A read-only role means the database itself rejects any attempt to modify data, so a bad prompt cannot mutate your tables. Onpilot logs each query the agent runs, giving you a traceable record for debugging and compliance. Pointing the agent at a read replica adds another layer by keeping analytical queries off your primary.
Can the AI agent write or change data in the database?
+
Only if you explicitly grant write access, and you should gate it. Grant write privileges narrowly to specific tables, then put each write behind a human-in-the-loop approval so a person reviews the exact statement before it runs. Combined with least-privilege RBAC, this keeps destructive operations off by default.
Which databases can an AI agent connect to?
+
Common SQL databases connect through the Onpilot integrations catalog. You add the database, provide the connection string for your scoped role, and point the agent at the schemas or views it should answer from. Credentials live in the connection, not in the prompt, so end users never see them.
Do users need to know SQL to query the database with an AI agent?
+
No. Users ask questions in plain language and the agent generates and runs the SQL on their behalf. The agent often returns the query alongside the answer so technical users can verify it, but no one needs to write SQL or build a dashboard to get a result.
How does the AI agent stay within a user's permissions?
+
The agent's access is bounded by the database role it connects through, and you can scope it further with row-level security or per-tenant views. Least-privilege RBAC controls which users and channels can trigger write-capable actions, and the audit log records exactly what ran under which role.
Should I point the agent at my production database or a read replica?
+
Prefer a read replica when you have one. Analytical questions can produce heavy queries, and running them on a replica keeps that load away from the transactional traffic your application depends on. A connection-level statement timeout is also worth setting so a single runaway query cannot pin the database.
How do I prevent prompt injection from making the agent run a harmful query?
+
Do not rely on the prompt as a boundary. A read-only role means even a successful injection cannot modify data, because the database rejects writes the role lacks. For write-capable agents, every change pauses for human approval, so an injected instruction still cannot commit anything without a person clicking approve. The audit log then records the attempt for review.
Can the agent run database queries on a schedule and deliver results automatically?
+
Yes. Instead of someone asking the same question each week, the agent can run a query on a schedule under the same governed connection and deliver the finished result to Slack, Teams, or email. The scoped role, approval gates, and audit log apply to scheduled runs exactly as they do to on-demand questions.
Related
Put a governed AI agent on your database
See how Onpilot connects to your SQL database with a least-privilege read-only role, approval-gated writes, and an audit log of every query. Book a walkthrough with our team.
Book a demo