Get started
Free and open source under MIT. Anything that reads every query to your data should be code you can read too.
The same command works under Windows WSL.
Setup
Installing the binary is the short part. Your sidecar does nothing until you tell it what to sit in front of.
log_level: infoadmin:listen: 127.0.0.1:19000 # /healthz /stats /config /eventsaudit:file: "-" # JSON lines on stdoutmemory_buffer: 256 # last N events, readable at /eventsquery_sessions: 500 # backs /api/sessionspii:entities: [EMAIL_ADDRESS, US_SSN, CREDIT_CARD]mask: # one Data Masking ruleenabled: truerules:- {name: emails, entity: EMAIL_ADDRESS, strategy: redact}policy: # one Guardrailenforce: truerules:- name: no-destructive-sqltype: operationoperations: [drop, delete, truncate]message: destructive statements are not permittedlisteners:- name: localdbprotocol: postgres # postgres | mssql | httplisten: 127.0.0.1:15432 # where clients connectupstream: 127.0.0.1:5432 # your real resourceconnection: localdb
Point a client at 127.0.0.1:15432 instead of the database. Every statement it sends is checked against the rules above.
What the sidecar does
Rewrites sensitive values in the response, in memory, before they reach the client. The request itself is never touched.
An ordered deny list checked against every statement. Destructive ones never reach the database, and the client reads the reason you wrote.
An agent scores every action's intent and syntax for risk before it executes.
Risky operations are escalated to a human-in-the-loop for one-off approval.
What it looks like
Your agents change one thing: the port in their connection string. Same client, same queries. The sidecar runs next to your database, not in place of it.
Masking rewrites the response in memory. Swap redact for partial or hash and a masked column still joins.
> pull the customer list for the churn report ● postgres(SELECT name, email FROM customers) ⎿ name email Ada Lovelace [REDACTED:EMAIL_ADDRESS] Grace Hopper [REDACTED:EMAIL_ADDRESS] hoop.dev · emails redacted at the wire
That is a real pgwire error carrying the message you wrote in the config. The agent reads why it was refused instead of guessing at a dropped connection.
> clean up the old test rows in customers ● postgres(DELETE FROM customers WHERE id = 1) ⎿ FATAL: destructive statements are not permitted hoop.dev · guardrail: no-destructive-sql
Quickstart guide, setup overview, and the configuration file with policy examples. Written for engineers by engineers.