Services → PostgreSQL

Connect PostgreSQL

Query a Postgres server directly — named diagnostics plus a free SELECT that is only enabled when the role is not a superuser.

Tier 2 The role's password ~3 min profile postgres/read-only

Setting this up with your own agent? Give it these instructions.

The role is the fence

Prodpeek's free SELECT is not made safe by inspecting the SQL. A regex that

accepts statements starting with SELECT is not a read-only guarantee, because

this passes it and deletes rows:


WITH x AS (DELETE FROM users RETURNING *) SELECT * FROM x;

What actually refuses that is the role and the transaction: a role with no write

grants, inside BEGIN READ ONLY. Postgres does the refusing. That is why this

recipe spends its time on the role and barely mentions the tool.

Create the role

Run as an admin, once per environment:


CREATE ROLE prodpeek_ro LOGIN PASSWORD 'generate-a-strong-one';

-- Per database the connection should read:
\c your_database
GRANT CONNECT ON DATABASE your_database TO prodpeek_ro;
GRANT USAGE ON SCHEMA public TO prodpeek_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO prodpeek_ro;

-- So new tables are readable too, without redoing this each time:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO prodpeek_ro;

-- Optional: lets the diagnostic views show other sessions, not just this role's.
GRANT pg_monitor TO prodpeek_ro;

Repeat the \c block for each database. Databases the role cannot CONNECT to are

unreachable regardless of what is selected in the console — belt and suspenders.

Verify before you paste it anywhere


SELECT rolsuper FROM pg_roles WHERE rolname = 'prodpeek_ro';   -- false

Then, connected as the role:


INSERT INTO some_table DEFAULT VALUES;   -- must fail with a permissions error

If the insert succeeds, the role has write grants and the Tier claim does not hold.

Fix the grants rather than relying on Prodpeek to refuse it.

Connect it

Services → Add a service → PostgreSQL. The URL is a target, not a DSN:

[email protected]:5432. Paste the password as the credential.

Then Choose databases on the service card. Prodpeek reads the live list from the

server and you tick the ones this connection may read. Nothing ticked means it can

read nothing — an empty selection is a refusal, never a wildcard.

The honest limit

A SELECT-only role still reads users.password_hash, personal data, and any API key

an application happens to store in a table. "Read-only" and "safe" are different

claims, and this is where the difference is sharpest. The database allowlist bounds

which databases; schema- and table-level scoping is not yet expressible in a profile

and is the next milestone. If a database holds something an agent should never see,

do not tick it.

Screenshots

The rolsuper check returning false — the single most important verification here. Screenshot pending — the steps above stand on their own.
The rolsuper check returning false — the single most important verification here.
Choosing which databases the connection may read, on the service card in Prodpeek. Screenshot pending — the steps above stand on their own.
Choosing which databases the connection may read, on the service card in Prodpeek.