← Blog5 min read

Launching PgBeam: Safe Postgres for AI Agents

The last step before an agent touches a real database is the one I always felt worst about. You have the agent working. You have the database. Between them goes a connection string, and the one in your hand can read every table, write every row, and drop the schema.

You can write a careful prompt asking it not to. A prompt is a suggestion. It is not an enforcement boundary.

PgBeam is the enforcement boundary. It sits in the Postgres wire protocol between the agent and your database, authenticates a scoped credential that PgBeam issued, checks every statement against a policy, and only then forwards it upstream. Today it is live.

The 60-second version

Connect a database, create a policy, issue a credential:

Scope an agent in three commands
pgbeam db add --name app --username app_user --password ****
pgbeam policies create --name read-only --mode read_only
# → Policy profile created: pol_1a2b3c…
pgbeam agents create --name analytics-bot --policy pol_1a2b3c…

That last command hands you two front doors to the same policy engine:

# A guarded Postgres connection string
postgresql://agent_4f2c:****@a1b2c3.proxy.pgbeam.app:5432/app

# A hosted MCP endpoint, Bearer pba_…
https://<project>.proxy.pgbeam.app/mcp

Paste either one into Claude Code, Cursor, LangChain, or psql. Every Postgres driver and ORM works unchanged, because the thing on the other end speaks Postgres. There is no SDK, no extension to install in your database, and no migration.

The receipt

Here is what the agent gets when it tries to write through a read-only credential. This is the actual message, not a paraphrase:

ERROR:  blocked by PgBeam agent policy: this credential is read-only; update is not permitted; only SELECT, SHOW, and EXPLAIN are allowed

Two things matter about that string. First, the statement never reached your database. Second, it tells the agent what happened and what it may do instead, so a blocked call becomes a self-correcting step in the loop rather than a dead end. Errors written for an LLM consumer are a feature, not a nicety.

Masking works the same way, in flight. Name a column, choose redact, null, or hash, and the agent receives masked values it can still join and group on while your own application keeps reading the real ones. The agent never sees the plaintext, because the plaintext never leaves the wire.

What the policy decides

  • Read-only or read-write, per credential. Writes and DDL are refused before your database sees them.
  • Which schemas, tables, and columns the credential can reach. Everything else is blocked.
  • Which rows: a row-level policy appends a WHERE predicate to every query, so a per-tenant agent cannot read outside its tenant no matter what SQL it generates.
  • What gets masked: redact, null, or hash, matched by schema.table.column.
  • How much it can spend: queries per hour or day, and a row cap per result. A looping agent hits a ceiling instead of your primary.
  • Whether a write needs a human. Approval queues hold a statement until someone signs off.
  • Where writes land. A write can go to an isolated instant branch, or run in a transaction that always rolls back, so an agent can write freely without touching production.

Every statement, allowed or blocked, is recorded with its decision, reason, rows, bytes, and latency. The log is SHA-256 hash-chained, so editing or deleting an entry breaks the chain and a verify endpoint reports the first broken row. It streams to Splunk HEC, Datadog, or Elastic, or to any endpoint over signed webhooks. And there is a kill-switch: stop one agent or every agent on a project, and the next statement is refused. No credential rotation, no role changes.

Why the wire, and not the database

Every one of those controls could in principle live inside Postgres. Roles block writes. Views hide columns. The problem is that the database is the wrong place to put a policy about an agent.

A read-only role blocks writes and nothing else. It cannot mask a column, cannot budget query volume, cannot tell you what the agent ran, and revoking it means a role rotation that touches everything else using that role. Native agent features from a managed provider only reach databases that provider hosts. If your Postgres is on RDS, Aurora, or a box you run, they cannot help you.

Enforcement in the wire protocol is portable by construction. PgBeam works with RDS, Aurora, Neon, Supabase, or self-hosted, because it only needs to speak Postgres to both sides. I wrote more about that tradeoff in The proxy is the place.

The same position pays for itself twice. The proxy runs across 12 metros and routes to the nearest one, so it pools the connections agents leak and caches the questions they re-ask. Guardrails that make your agent slower would not survive contact with a real workload.

What I am not claiming

  • PgBeam is not SOC 2 or HIPAA certified. You get masking, a tamper-evident hash-chained audit log, SCIM and SSO, and per-organization data residency. You do not get a certificate, and I am not going to imply otherwise.
  • Masking is redact, null, or hash. There is no partial masking that shows the last four digits.
  • Relation allowlists do not see through views. If you want a view reachable, allowlist the view.
  • SET search_path is blocked for agent credentials, because allowing it would let an agent walk around an allowlist.
  • Query budgets are enforced per region, so on a globally distributed workload treat them as a close approximation rather than a globally coordinated counter.
  • Binary-format result columns are masked to NULL rather than a redaction token, since a redaction string is not a valid binary value.

I would rather you hit these in this list than in production.

Start

The dashboard is at pgbeam.com. New signups start on a 14-day free trial with no credit card. If you want to watch the policy engine make decisions before connecting anything of your own, the live demo is a real LLM agent running against a real database through PgBeam, with no signup, so you can watch it get allowed, masked, and blocked.

If you are wiring an agent into a production database this week, the honest question is not whether the agent is well behaved. It is what it is allowed to do when it is not.

Give your agent Postgres it can't wreck

Connect a database, issue a credential, and watch the audit log fill up. No credit card. 14-day trial.