Postgres can already log statements. So why is audit logging for AI agents on Postgres still a problem? Because the native log records what the connected role did, and your agents all connect as the same role. The log fills with app_user ran UPDATE and tells you nothing about which agent, under which task, with whose authorization. The statements are there; the accountability is missing.
This post covers what real audit logging for agents on Postgres requires and how hoop.dev produces it by attributing every statement to a named identity.
Statement logs versus an audit trail
A statement log answers "what ran." An audit trail answers "who ran it, when, with what authorization, and what came back." The gap between them is identity. If every agent shares one Postgres role, no amount of statement logging closes that gap, because the database only ever sees the role.
Attribution has to come from the access layer
The only place that knows which agent is connecting is the layer that authenticated it. Postgres sees a role; the access layer sees the identity. So audit logging that means anything must be produced where identity is resolved, then bound to the statements that follow.
How hoop.dev produces audit logging for Postgres
hoop.dev is an open-source Layer 7 access gateway. The AI agent authenticates to hoop.dev through your identity provider, hoop.dev resolves a named identity, and its agent proxies the Postgres connection at the wire-protocol level. Every statement is logged tied to that identity, not to the shared database role. Because logging happens at the gateway, outside the agent, the agent cannot edit or suppress its own entries.
The database still reaches its target with the credential on the connection. The audit attribution is added on top, at the gateway, where identity is known.
Why the access layer, not the database, owns attribution
It is tempting to push this problem into Postgres with per-agent database roles. That works until you have dozens of agents, short-lived ones, and agents that come and go with deployments. Managing a database role per ephemeral agent, with the grants and rotation that implies, becomes its own burden, and Postgres still cannot record the approval context or the request that justified a session. The access layer already holds that information because it authenticated the agent and evaluated policy. Producing audit logging there keeps attribution where the identity is actually known, and lets the database role stay simple. For how identity flows into authorization, see hoop.dev/learn.
What an audit entry should carry
- The named identity that issued the statement, human or agent.
- The exact statement, captured from the wire.
- The connection and database it ran against.
- The authorization context, including any approval that gated the session.
- A timestamp and session linkage so entries reconstruct in order.
Reading the trail when it matters
The test of an audit trail is the moment someone asks a hard question months later. Which agent touched the customer table on the day a record went wrong? Who approved the session that ran the migration? An identity-attributed log answers those by filtering on the principal and walking its statements in order. A shared-role statement log cannot, because every entry names the same actor and none of them carry the approval context. The difference is not how much you logged; it is whether the log can name who and why, not only what.
Pitfalls
- Do not treat the native Postgres log as your audit trail for agents. Without per-agent identity it cannot attribute actions.
- Do not let agents share one identity at the gateway either. Audit logging is only as granular as the identities you define.
- Keep the logs outside the agent's reach. A log the audited process can write is not an audit trail.
FAQ
Does this replace Postgres logging?
No. It adds identity-attributed audit logging at the gateway in front of Postgres. The database can keep its own logs.
How does the log know which agent ran a statement?
hoop.dev authenticates the agent and resolves its identity before proxying the connection, then binds that identity to each statement.
Can an agent alter its audit entries?
No. Logging happens at the gateway, outside the agent process.
hoop.dev is open source. See how identity-attributed audit logging works on a Postgres connection in the hoop.dev GitHub repository, or start from the getting started guide.