Deterministic rule engine Rule engine

Credential rules: no secret ever reaches the repo

available
Free in the CLI · every plan

Plaintext role passwords, user-mapping and subscription credentials, connection strings with embedded passwords, vendor-format API keys and private keys, literals seeded into secret-named columns. Every finding masks the value — the report never repeats a secret.

A migration must never carry a secret, because git history keeps it forever. The BC family fires on a role created or altered with a plaintext password (an md5 verifier is a warning, a SCRAM verifier stays silent), a foreign server, user mapping or subscription with an embedded credential, a connection string with the password inline, a vendor-format API key, JWT or PEM private key in any literal, and a secret-named column given a literal value.

Published formats only, never entropy: sk_live_, AKIA, ghp_, xoxb-, -----BEGIN PRIVATE KEY----- and friends fire. A uuid, a bcrypt or argon2 hash, a placeholder or an empty string stays silent.

-- BC001: fires
CREATE ROLE reporter LOGIN PASSWORD 'hunter2';

-- stays silent: a SCRAM verifier is not a secret
CREATE ROLE reporter LOGIN PASSWORD 'SCRAM-SHA-256$4096:...';

The report never repeats a secret

When a BC rule fires on a statement, the engine redacts the value in every finding on that statement — the terminal, the JSON, the PR comment and the run log all show a mask. A finding is proof that something was there, not a second copy of it.

Try it on your next migration

The CLI is open source and needs no account: npx bolvrk check migration.sql

Also in Deterministic rule engine