connect a database
Connect PostgreSQL
Provisioning read-only credentials for PostgreSQL — the same instructions Evalyst shows you when a credential check fails.
Run as a superuser (or the database owner) in the database you want to attach.
-- 1. the role. Evalyst only ever logs in; it never needs CREATEDB/CREATEROLE/SUPERUSER.
CREATE ROLE evalyst_reader LOGIN PASSWORD '<STRONG_PASSWORD>'
NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS;
-- 2. let it reach the database and the schemas that hold your data
GRANT CONNECT ON DATABASE "<your_db>" TO evalyst_reader;
GRANT USAGE ON SCHEMA public TO evalyst_reader; -- repeat per schema
-- 3. SELECT on what exists today...
GRANT SELECT ON ALL TABLES IN SCHEMA public TO evalyst_reader;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO evalyst_reader;
-- 4. ...and on what gets created later. Run this AS THE ROLE THAT OWNS THE TABLES —
-- default privileges are per-granting-role, which is the step people miss and then
-- wonder why last month's new table is invisible.
ALTER DEFAULT PRIVILEGES FOR ROLE <table_owner> IN SCHEMA public
GRANT SELECT ON TABLES TO evalyst_reader;
-- 5. belt and braces: make read-only the default posture of every session it opens.
-- (The driver also sets it per connection; this survives a driver bug.)
ALTER ROLE evalyst_reader SET default_transaction_read_only = on;
ALTER ROLE evalyst_reader SET statement_timeout = '30s';
Check it yourself
SET ROLE evalyst_reader;
SELECT count(*) FROM <some_table>; -- works
CREATE TABLE probe(i int); -- must fail
UPDATE <some_table> SET <col> = <col> WHERE false; -- must fail: permission denied
RESET ROLE;
Notes
- Point Evalyst at a replica if you have one.
pg_is_in_recovery()is reported in the verify evidence, and a physical replica is read-only at the storage layer — the strongest guarantee available. - Row-level security. If your tables use RLS,
evalyst_readeris subject to it (the role is createdNOBYPASSRLSabove, deliberately). Grant it whatever policy exemption your analysts have, or the agent will quietly see a subset and report it as the whole. CREATEonpublic. Before Postgres 15, every role can create objects inpublic. Evalyst reports this as a warning and still activates: creating a new table cannot change what an existing query returns. Revoke it if you want a clean report:REVOKE CREATE ON SCHEMA public FROM PUBLIC;- Connecting over SSH. If the database is not exposed publicly, give Evalyst a bastion instead
of opening the port: set
config.ssh = {"host": …, "user": …, "key_secret_ref": "SSH_PRIVATE_KEY"}and keepconfig.hostas the address the bastion uses (often127.0.0.1). Host-key trust is per-source, not from~/.ssh/known_hosts— see the bastion notes. - TLS. Direct (non-SSH) connections default to
sslmode=require. Setconfig.sslmodetoverify-fullif you have the CA distributed, or topreferfor an SSH-tunnelled connection where the transport is already encrypted.