Should a column named password or token get a literal value in a migration?
Secret-named column given a literal value
Warning: the name is the evidence: very likely a secret, reported so a human can decide.
What happens
A column called password, api_key, secret or token that receives a literal in a DEFAULT, an INSERT or an UPDATE is a credential written into the migration by hand, the seeded admin account with password 'admin', the api_key DEFAULT 'changeme' that ships to every row. The name is the evidence, so this is a warning rather than a certainty: the rule stays silent on hashed values (bcrypt, argon2, SCRAM, pbkdf2), on empty strings and placeholders, and on names that merely contain the word (password_hash, token_type, api_key_id).
Why it is dangerous on a populated table
Table size does not change this one: a committed credential is live from the first row, and git history keeps it after the fix.
Fires on
INSERT INTO users (email, password) VALUES ('admin@example.com', 'admin123');The safe pattern
Seed a hash, never the plaintext (and let the application own password hashing); for tokens and keys, seed nothing, or a placeholder the deploy substitutes, and have the value set at runtime. A DEFAULT on a secret column should be NULL or an empty string.
INSERT INTO users (email, password_hash) VALUES ('admin@example.com', '$2b$12$C6UzMDM.H6dfI/f/IKcEeO9rOsTbnR6Q3oFf9zGjHpMqU9ZAwK9Tu');Fixtures
The rule ships with these files and the test suite runs them on every change: the first set must fire, the second must stay silent.
Fires (4)
CREATE TABLE webhooks (id bigint PRIMARY KEY, url text NOT NULL, signing_token text DEFAULT 'shared-token');ALTER TABLE tenants ADD COLUMN api_key text NOT NULL DEFAULT 'changeme';INSERT INTO users (email, password) VALUES ('admin@example.com', 'admin123');UPDATE oauth_clients SET client_secret = 'local-dev-secret' WHERE name = 'dashboard';Stays silent (5)
INSERT INTO users (email, password) VALUES ('admin@example.com', '$2b$12$C6UzMDM.H6dfI/f/IKcEeO9rOsTbnR6Q3oFf9zGjHpMqU9ZAwK9Tu');ALTER TABLE users ADD COLUMN password_hash text DEFAULT 'pending';
ALTER TABLE oauth_clients ADD COLUMN token_type text DEFAULT 'bearer';
INSERT INTO api_keys (api_key_id, label) VALUES ('k_01', 'primary');ALTER TABLE tenants ADD COLUMN api_key text DEFAULT '';
ALTER TABLE tenants ADD COLUMN webhook_secret text DEFAULT NULL;INSERT INTO users VALUES (1, 'admin@example.com', 'admin123');INSERT INTO users (email, password) VALUES ('admin@example.com', '${ADMIN_PASSWORD}');How to check locally
This rule runs locally in the free CLI, or with the full corpus through the hosted service. No install, nothing leaves your machine:
npx bolvrk check migration.sql