Guardrails
An ordered deny list, checked against every statement your agent sends. DROP TABLE, DELETE without a WHERE, TRUNCATE. Refused at the sidecar, before your database ever sees them.
Monitoring tells you a table was dropped. It tells you after. By the time an alert reaches a person, the statement has run and the rows are gone.
An agent does not wait for that window to close. It issues the next statement in milliseconds, then the one after.
88 minutes to revoke access
How it works
A guardrail is a rule in your config file. The sidecar checks every statement against the list before passing it upstream. A statement that matches never reaches your database.
Rules run in the order you wrote them, against every statement. The first match decides. No scoring, no ambiguity, same answer every time.
A rule names the operations it refuses: drop, delete, truncate. It reads the parsed statement, so it does not miss a variant that a regex would.
You write the refusal text. The client receives it as a real protocol error, not a dropped connection.
Every rule carries a name, and the name travels with the refusal. The log and the client cite the same rule.
What the agent sees
A blocked statement comes back as a real protocol error carrying the message you wrote. The agent reads why it was refused instead of guessing at a dropped connection.
So it does not retry the same statement, and it does not stall. It finds a compliant path on its own.
● postgres(DELETE FROM customers WHERE id = 1) ⎿ FATAL: destructive statements are not permitted hoop.dev · guardrail: no-destructive-sql
Name the operations you never want an agent to run, write the message it should read instead, and start the sidecar. Free and open source under MIT.