Connect a project: what we store, what runs, how to revoke
Connecting a project gives RowShield a Postgres connection string. From that point the project is scanned on your plan's schedule, findings accumulate history, and remediation SQL is generated from your real columns rather than guesses.
This article covers what happens to that credential, precisely what a scan executes against your database, and how to revoke access later.
The connection string
Create a dedicated, minimal role for scanning rather than reusing a superuser or your application's service connection. Catalog views in pg_catalog are readable by any session that connects, so the only extra grants a scan benefits from are USAGE on the schemas you want covered and read access to storage.buckets for the bucket rule:
Handing the scanner a superuser works and buys nothing: catalog visibility is already complete for ordinary sessions, so the extra power only widens the blast radius of a mistake. The narrow role above is the intended shape, and it keeps bucket checks working through the storage grants.
Treat the credential as a production secret. It is transmitted over TLS, encrypted with AES-256-GCM envelope encryption before storage, and optionally sealed under a master key held in an external KMS. Additional authenticated data binds each ciphertext to its organisation and project, so a blob copied from one database row cannot be decrypted under another identity. Log scrubbing keeps connection strings out of our own logs.
Rotating the password later takes effect on the next scheduled run; updating the stored credential is done from the same project settings page where you first pasted it.
CREATE ROLE rowshield_reader LOGIN PASSWORD 'pick-a-long-password'; GRANT USAGE ON SCHEMA public TO rowshield_reader; GRANT USAGE ON SCHEMA storage TO rowshield_reader; GRANT SELECT ON storage.buckets TO rowshield_reader;
What a scan runs
Each scan runs six fixed introspection statements, builds one schema snapshot, then evaluates the seven catalog rules as pure functions over that snapshot. Concretely, the statements read: tables and their RLS flags; columns and types; policies with their commands, roles and expressions; indexes with their key columns; bucket metadata including the public flag; and the server version. Everything else is computed on our side.
The statement count is fixed no matter how many rules exist, none of the statements names a user table, and because rules are pure functions of the snapshot, improvements to rules can be replayed over snapshots already stored with past runs, sharpening history without opening another connection.
Connection strings routed through a transaction-mode pooler work as-is: the scanner drives its connection without prepared statements because poolers such as Supavisor and pgBouncer reject them.
When something cannot be read, for example a missing grant on storage.buckets, the scan does not fail. It completes, records a warning that names the skipped rule and the grant which would enable it, and the dashboard shows the warning alongside the results, so reduced coverage never masquerades as a clean bill of health.
Ending the access
Disconnect a project from its settings page at any time. Disconnecting stops scheduled scans, drops anything already queued for that project, and deletes the stored credential. Alert destinations stop receiving anything for that project immediately.
Cutting access off at the database works faster still: change the role's password or drop the role, and every subsequent attempt fails authentication. Both routes, including exactly what is deleted and when, are itemised in Revoking access.
Billing trouble does not interrupt monitoring either: while a payment is failing but the subscription has not been cancelled or left unpaid, scheduled scans continue, because pausing the watch is the worst possible response to an expired card.
One project per organisation is the free plan's allowance, and connecting a second is where paid plans begin; the connection form says which at the moment it matters rather than surprising you afterwards.
Related questions
- Can a scan modify my database?
- No. The introspection statements are read-only constants over pg_catalog and storage.buckets metadata, and nothing else is executed. There is no DDL, no INSERT and no UPDATE anywhere in the scanning path.
- Will scheduled scans load my database?
- A scan is a handful of catalog reads that never touch user tables, so its cost does not grow with row counts or traffic. Frequency is the only variable, and that follows your plan.
Did this answer your question? If not, tell us what is missing — article corrections go straight to the person who maintains it.