---
title: "How PgBeam works"
description: "The mechanism: an enforcement boundary in the PostgreSQL wire protocol between an AI agent and your database. The path of a statement, why the policy lives in the wire rather than in the database, and how pooling, caching and nearest-region routing keep the guard fast enough to leave in the path."
canonical: "https://pgbeam.com/architecture"
last-updated: "2026-09-07T12:07:53.666Z"
---

# How PgBeam works

PgBeam is an enforcement boundary in the PostgreSQL wire protocol, between an AI agent and your database. The agent connects to PgBeam with a credential PgBeam issued, never to Postgres directly and never with your database credentials. Every statement it sends is parsed, checked against the policy attached to that credential, and only then forwarded upstream.

This is the permanent reference for the mechanism. The dated announcement is at https://pgbeam.com/blog/launching-pgbeam.md and does not describe the current mechanism authoritatively; this page does.

## Shape
- Data plane: the proxy the agent connects to. Speaks the PostgreSQL frontend/backend protocol, so every driver, ORM, and agent framework works unchanged. Runs across 12 metros; a connection is routed to the nearest one.
- Control plane: dashboard, API, and audit store, in `us-east-1`. Policies are authored here and distributed to every region, so a revoke or a kill-switch takes effect without a deploy or a database role rotation.
- Your database credentials stay in the control plane, encrypted at rest, and are used only to open the upstream connection. The agent never sees them.

## Path of a statement
1. The agent connects over TLS with a PgBeam-issued credential or an MCP bearer token. The project is resolved from the hostname.
2. PgBeam authenticates the credential (SCRAM-SHA-256) and resolves its policy profile: access mode, allowed statement types, reachable schemas/tables/columns, row predicates, masked columns, query budget, row cap.
3. The statement is parsed with the PostgreSQL grammar itself, not regular expressions. Unparseable SQL is refused: agent credentials fail closed.
4. The policy decides and can rewrite. Statement type is checked against the access mode; every relation in the parse tree against the allowlist; a row-level policy appends a WHERE predicate the agent cannot remove. COPY, multi-statement batches containing a blocked statement, and SET search_path are refused for agent credentials.
5. A blocked statement never reaches your database. It returns a PostgreSQL ErrorResponse carrying a reason written for a model to read: what was blocked, why, and what the credential may do instead.
6. An allowed statement is forwarded on an already-authenticated pooled upstream connection.
7. The result is masked on the way out. Columns matched by schema.table.column are redacted, nulled, or hashed before the rows leave the wire. Masking runs at serve time, so masked values still join and group, your application keeps reading the real ones, and one cache entry can serve both.
8. Rows and bytes count against the budget and row cap, and the statement is recorded with its decision, reason, rows, bytes, latency, region, credential, and timestamp. The audit log is SHA-256 hash-chained with a verify endpoint.

## Why the wire, not the database
A read-only role blocks writes and nothing else: no column masking, no query budget, no per-agent record, and revoking it means rotating a role everything else depends on. A managed provider's native agent features only reach databases that provider hosts. The agent itself is the thing you do not trust, and a prompt is not an enforcement boundary. The wire is the one layer every client passes through and the one that sees the statement before the database does, so enforcing there is portable: RDS, Aurora, Neon, Supabase, or self-hosted, with no extension, no schema change, and no migration.

## What keeps the guard in the path
A policy only holds if every statement goes through the thing enforcing it, so the guard has to be fast enough that nobody routes around it. Pooling, caching, and nearest-region routing are what make that true. They are the substrate, not the product.
- Warm upstream connections: a new PostgreSQL connection is four round trips (TCP, TLS, startup, auth), 400-800ms Virginia to Tokyo. Agents open a connection per tool call and drop it. PgBeam maps the session onto a pre-authenticated upstream connection, cutting connection establishment by 3-7x and keeping leaked sockets off your primary.
- Cached read results: cached in the region that served them, stale-while-revalidate, opt-in per query via a SQL annotation or a dashboard rule. Serve-time masking is what lets one entry serve masked and unmasked readers.
- A short client hop: the client lands on the nearest region while the upstream connection is made from the region nearest the database. Cached results stay in the region that produced them, which is also what makes per-organization residency enforceable.

## Two front doors, one policy engine
A guarded connection string (any driver or ORM) and a hosted MCP endpoint (ten policy-enforced tools: `briefing`, `query`, `validate_sql`, `list_tables`, `describe_table`, `explain`, `schema_catalog`, `my_permissions`, `search_docs`, `read_doc`), both backed by the same policy and the same enforcement path. Call `briefing` first: it returns the schema, the credential's limits, and how to query within them together.

## Honest limits
- Technical Preview. No SLA. No SOC 2 Type II and no HIPAA certification; a tamper-evident hash-chained audit log is a different thing from a certificate.
- Relation allowlists do not see through views. Allowlist the view.
- SET search_path is blocked for agent credentials.
- Binary-format result columns are masked to NULL rather than a redaction token.
- Masking is redact, null, or hash. No partial masking.
- Query budgets are counted per region: a close approximation, not a globally coordinated counter.
- Caching is reads only, opt-in per query, up to 60s stale by default. Writes always pass through, and each region's cache expires on its own TTL.
- PostgreSQL only.

## Links
- Docs: https://pgbeam.com/docs/how-it-works
- Policies: https://pgbeam.com/docs/policies
- Features: https://pgbeam.com/features
- Security: https://pgbeam.com/security
- Live latency benchmark: https://pgbeam.com/benchmark
