Blog
guide

How to Securely Connect Your Database to AI Agents

Musthaq Ahamad
Musthaq Ahamad

On April 25, 2026, a Cursor agent running Claude Opus 4.6 deleted PocketOS's production database in nine seconds. The agent was working in staging on a routine task, hit a credential mismatch, and decided to "fix" it. It went looking for an API token, found one in an unrelated file, and ran a single GraphQL volumeDelete mutation.

The production volume was gone. So was every volume-level backup, because Railway stored them inside the same volume. The most recent recoverable copy was three months old. Zenity's writeup and the founder's first-person thread are both worth reading in full.

This was not a prompt injection. No malicious ticket, no poisoned tool description, no attacker anywhere in the loop. It was an autonomous agent making a confident, wrong call with a credential that should never have reached it.

Our MCP security guide covers the threat-model side of AI database access, and our intro to MCP is a good first read if the protocol is new to you. This piece is the practical companion: how to wire the connection so a single moment of bad judgment cannot end your data.

What secure means for an AI-to-database connection

A secure database connection for an AI agent is a different problem than a secure connection for a person clicking around a BI tool. A person is slow, deterministic, and accountable. An agent is fast, probabilistic, and willing to compose tool calls you never imagined. The blast radius is wider.

Three questions cover most of it:

  • What can the agent do? The privilege of the database user behind the connection.
  • What can the agent reach? The network and environment scope.
  • What do you know after the fact? The query log, and the identity attached to it.

You can hear the same three concerns when developers talk among themselves. A recent r/CursorAI thread spelled out the fear plainly: a hallucinated UPDATE without a WHERE clause, or an accidental read of a table of hashed passwords.

Screenshot of an r/CursorAI thread titled "Is anyone else terrified of giving Cursor/Claude direct access to their database?" The OP describes anxiety about an AI hallucinating an UPDATE without a WHERE clause or reading a table of hashed passwords.

Source: r/CursorAI thread, November 2025

The next four controls map onto those three questions. Each one is useful on its own. Stacked, they turn most worst-case outcomes into noisy "permission denied" errors.

The four controls that do the real work

Least-privileged database role

Rule: The AI agent connects through a database user that can only run SELECT, scoped to the schema it actually needs.

A read-only role runs SELECT and nothing else. INSERT, UPDATE, DELETE, DROP, and TRUNCATE all fail at the database layer with a permission error. Even if the model writes a perfect DELETE statement and a tool dutifully executes it, the row never leaves.

OWASP's excessive agency entry for LLM applications names the exact anti-pattern: a read tool that connects with permissions broader than read. The fix is a few lines of SQL, walked through in our read-only Postgres user guide.

What bad looks like: the agent's connection string points at the same database user the application uses. The Replit incident in July 2025 went this way. An agent with full write access to a production database deleted live records for 1,200 executives and 1,196 companies, then fabricated thousands of fake users to cover the gap.

Jason Lemkin's tweet from July 18 2025, announcing that Replit's AI agent went rogue during a code freeze and deleted the entire production database. The post has 2.7 million views and 3.7 thousand likes.

Source: @jasonlk on X, July 18, 2025

A read-only role would have made the DELETE a no-op.

Network and environment isolation

Rule: The agent reaches a read replica or a non-production environment. It cannot reach production directly, even by accident.

A read replica is a copy of your data that accepts queries and rejects writes at the network layer. Pointing the AI there gives you three things at once: production query latency stays unaffected by AI workloads, the agent cannot issue a destructive statement against the live primary, and the connection itself can live behind a VPC, private IP, or IP allowlist that the application never needed.

Most managed databases ship this primitive. AWS RDS read replicas and Neon's read-only replicas are one click each.

What bad looks like: a staging agent with a token that works against production. The Railway API token PocketOS lost data to "had blanket authority across Railway's entire GraphQL API, including destructive operations on production volumes," per Zenity's analysis. The agent was in staging. The blast radius was prod.

Credential discipline

Rule: Database credentials live in a secret manager or an environment outside the repo. They rotate. Each agent gets its own.

The Cursor community has been asking the right question since 2023. One of the most-viewed threads on the forum is honest about the confusion: "Sometimes people will initially code using database credentials directly in code before moving them to a dotenv file. Are these credentials then stored anywhere at all? Are dotenv files safe?"

That confusion is the threat. A connection string typed into a chat, pasted into a file the agent reads, or committed to git by accident becomes a connection string the agent will eventually find and use.

The cleaner pattern is one credential per agent, issued from a secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, Doppler, 1Password), rotated on a schedule, and revoked the moment that agent stops being used. Where IAM auth is available, prefer it. AWS RDS and Cloud SQL both let you skip passwords entirely.

Observability

Rule: Every query the agent runs is logged with the human who started it, the time, and the result size.

If a destructive call somehow lands, or a read does something nobody expected, the only useful artifact is the log. Without it, you are reduced to asking the agent what it did, which is exactly the PocketOS aftermath: the only audit trail was the agent's own post-hoc confession. That is not a control.

What good looks like is database-side query logging (Postgres log_statement = 'all' on the read role, or your warehouse's query history) plus an MCP-layer log that captures the human identity and the prompt that produced the query. Supabase's own defense-in-depth guidance puts it simply: monitor and log all MCP queries.

The cost is small. The value shows up the first time something goes wrong.

A worked example: connect Supabase to Claude Code through Sequel

Supabase hosts the database. Sequel sits in the middle as a hosted MCP service. Claude Code is the AI client. The four controls land cleanly on this stack: the read-only role lives in Supabase, the network boundary is Supabase's project firewall, credentials live in Sequel encrypted (not in your Claude Code config), and Sequel logs every tool call.

Step 1: Create a read-only role in Supabase

Open the Supabase SQL Editor and run:

CREATE USER sequel_reader WITH PASSWORD '<a-strong-secret>';
GRANT CONNECT ON DATABASE postgres TO sequel_reader;
GRANT USAGE ON SCHEMA public TO sequel_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO sequel_reader;

For default privileges on tables added later, see our read-only Postgres user guide. Supabase's own defense-in-depth guidance for MCP walks through project- and schema-scoping recommendations on top.

Step 2: Add the Supabase connection to Sequel

Sign in to sequel.sh, open Data Sources, click New Connection, and pick PostgreSQL. Use the connection string from your Supabase project's database settings with sequel_reader as the user:

postgresql://sequel_reader:<password>@db.<project-ref>.supabase.co:5432/postgres

Sequel stores the credential encrypted. Claude Code never sees it.

Step 3: Install the Sequel MCP server in Claude Code

Generate a workspace-scoped API key in Settings → API Keys (it starts with sql_), then register Sequel as a remote MCP server in Claude Code:

claude mcp add --transport http sequel https://api.sequel.sh/mcp \
  --header "Authorization: Bearer sql_your_api_key"

Verify with claude mcp list. Open a Claude Code session and ask, in plain English, to delete a row. The model will compose a DELETE statement; Supabase will reject it: ERROR: permission denied for table users. That rejection is the four controls doing their job in one line of output.

What changes for other database stacks

The four controls do not change. The primitives you reach for do.

Managed Postgres (RDS, Cloud SQL, Neon)

For managed Postgres outside Supabase, the playbook is the same shape with different primitives: IAM database authentication so you never carry a password, a read replica so the agent never touches the primary, and a VPC, private IP, or IP allowlist so the connection is unreachable from the open internet. Neon offers read replicas in a single click; Cloud SQL supports the same IAM model as RDS.

Warehouses (BigQuery, Snowflake)

Same controls, warehouse vocabulary. BigQuery has a dedicated bigquery.readonly OAuth scope; a service account bound to that scope cannot write or delete. Snowflake's docs walk through creating a read-only role with GRANT USAGE and GRANT SELECT on the schemas the agent should see. Tag queries with the agent's identity for downstream audit.

Self-hosted on a VM

Add SSH tunnel access from the agent's host, a firewall that drops everything else, and a dedicated read replica on a separate VM. The agent never sees the primary, and the network path itself is the second line of defense.

The scenario × controls cheat sheet

One survey of MCP server builders found that half of them rank security and access-control complexity as their top challenge, and a quarter run with no authentication on their MCP servers at all. That is the gap this table is meant to close.

ScenarioLeast privilegeNetwork isolationCredential disciplineObservability
Local PostgresRead-only role on publiclocalhost only.env outside repolog_statement = 'all'
Managed Postgres (RDS, Cloud SQL, Neon)Read-only role on schemaRead replica + VPCIAM auth or secret managerCloud-native query logs
SupabaseRead-only role, not serviceProject-scoped keyRotated keysPostgres + Supabase logs
BigQuerybigquery.readonly scopeOrg/project boundaryService account in Secret ManagerINFORMATION_SCHEMA.JOBS
SnowflakeCustom read-only roleNetwork policies + private linkKey-pair auth + secret managerQuery history + query tags
Self-hostedRead-only DB userSSH tunnel + firewallVault or DopplerPostgres logs + central sink

Where Sequel fits

Every control above is something a small team can build with care and a couple of hours of work. If you want one fewer thing to maintain, Sequel's MCP server ships the safe path as the default rather than the option. Sequel is a hosted service that connects to cloud-hosted databases (RDS, Supabase, Neon, BigQuery, Snowflake, and others); it is not aimed at databases running on your laptop.

What that means in practice: the connection runs read-only by default, with no write tools exposed for the model to misuse. Access keys are scoped to a workspace, so revoking a key cuts off a single agent without touching the rest. Every tool call is logged with the human identity attached to the workspace key. There is no persistent session on the server between calls, which removes one entire class of state-based vulnerability.

You can self-host all of this. Sequel just means you don't have to. See the MCP product page for the full surface, or walk through a real query end-to-end.

Your pre-flight checklist

Before any AI client connects to your database, confirm:

  1. The AI agent's database user is read-only and scoped to one schema.
  2. The connection points at a read replica or a non-production environment.
  3. Credentials live in a secret manager (or a .env outside the repo) and rotate on a schedule.
  4. The network path is restricted by VPC, private IP, IP allowlist, or SSH tunnel.
  5. Every query the agent runs is logged with the caller's identity.

If all five are true, the agent can do its job, and the worst case is a permission-denied error. Want the governance-side companion to this checklist? Read the MCP security guide.

Want a database MCP server that defaults to read-only, scopes access by workspace, and logs every query? Get started free, or read the governance companion first.

Try Sequel

Meet your always-on data analyst.

An AI data analyst that connects to all your data and answers questions with reports and visualizations. Free for up to 3 seats - no credit card required.

Get started free

Frequently asked questions

Is it safe to connect Claude or Cursor directly to my production database?

Direct, unscoped access is the pattern behind every public AI-agent database incident in 2025 and 2026. Safe means connecting through a read-only user, on a read replica or non-production copy, with credentials in a secret manager and every query logged. If you cannot tick all four, do not point an agent at production.

How do I give an AI agent read-only access to Postgres?

Create a dedicated user, grant CONNECT on the database, then grant SELECT on the schema (or specific tables) you want the agent to see. The full SQL, including the ALTER DEFAULT PRIVILEGES line for future tables, is in our [read-only Postgres user guide](/blog/read-only-user-postgres).

Should an AI agent query production or a read replica?

A read replica. It removes write capability at the network layer, keeps production query latency unaffected by AI workloads, and lets the connection live behind tighter network rules. Most managed databases (RDS, Cloud SQL, Neon) make this one click.

Where should I store database credentials for an MCP server?

In a secret manager (AWS Secrets Manager, GCP Secret Manager, Vault, Doppler, 1Password) or an environment variable that is not committed to git. Issue a separate credential per agent and rotate on a schedule. Never paste a connection string into a chat or a file the agent has read access to.

Can an AI agent over MCP run DELETE or DROP on my database?

Not if the connection uses a read-only database user. The database itself rejects the statement with a permission error, no matter what the model generated. This is why a least-privileged role is the single highest-value control.

What's the safest way to connect a cloud-managed Postgres to an AI agent?

A read-only role on a read replica, reached through IAM database authentication (no static password), with the connection restricted to a private network or IP allowlist. RDS, Cloud SQL, and Neon all support this combination natively.

Does Sequel see or store my database credentials?

Sequel's MCP server runs read-only by default and stores credentials encrypted. Tool calls are logged for audit, but query results are not retained after the call returns. Workspace-scoped access keys mean revoking a key cuts off one agent without touching the rest.

How do I audit what queries an AI agent ran on my database?

Combine database-side query logging (Postgres `log_statement = 'all'` for the read role, or your warehouse's query history) with MCP-layer logs that attach the human identity behind each call. Our [MCP security guide](/blog/mcp-security-governance) covers the full audit pattern.

Written by

Musthaq Ahamad
Musthaq Ahamad

Co-founder and CEO of Sequel. Previously built developer tools and data infrastructure. Passionate about making data accessible for everyone.