Provision a hardened SELECT-only Postgres role so AI agents can safely read a production database. Works on Supabase and any Postgres. Use when the user wants agents to query prod data, says "read-only role", "safe prod DB access for agents", or is tired of running SQL by hand for agents. Differentiator: this skill CREATES the role and wiring; day-to-day querying belongs in a project-local skill.
76
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
The canonical home for this skill is create-readonly-db-role in davidondrej/skills
Battle-tested pattern (DeepAPI ADR 0093). A SELECT-only role kills catastrophic writes at the permission level. Residual risks (data leaks, heavy queries) are handled by a denylist and timeouts. Agents stop being blind on prod; the human stops being the SQL bottleneck.
public (via default privileges), then revoke the crown jewels (API keys, webhook payloads, secrets). Never grant the auth schema. Future tables are auto-readable by design; new sensitive tables need a manual revoke.default_transaction_read_only = on plus statement_timeout = '10s'.RLS trap: if prod tables have Row Level Security and no policy mentions the new role, every SELECT returns 0 rows. Fix with alter role ... bypassrls — safe, because bypass only skips row filtering; the SELECT-only grants and denylist still apply.
select rolname from pg_roles where rolname = 'agents_readonly'; — if it exists, you are updating, not creating.docs/database/create-agents-readonly-role.sql) with comments: what / why / how to apply / how to verify / how to revert. Never hand SQL only in chat.~/.zshrc (never committed), e.g. MYPROJ_READONLY_DB_URL. Supabase session pooler: username is agents_readonly.<project-ref>, port 5432. psql comes from Homebrew libpq if missing.-- 1. role + soft guardrails
create role agents_readonly with login password 'REPLACE_ME';
alter role agents_readonly set default_transaction_read_only = on;
alter role agents_readonly set statement_timeout = '10s';
-- 2. the real wall: SELECT-only grants, denylist model
grant usage on schema public to agents_readonly;
grant select on all tables in schema public to agents_readonly;
alter default privileges for role postgres in schema public
grant select on tables to agents_readonly; -- future tables auto-readable
-- 3. denylist: crown jewels stay invisible (adjust per project)
revoke select on table public.api_keys from agents_readonly;
revoke select on table public.email_webhook_events from agents_readonly;
-- 4. only if RLS is enabled and no policy covers this role
alter role agents_readonly bypassrls;Revert: drop owned by agents_readonly; drop role agents_readonly;
URL="$MYPROJ_READONLY_DB_URL"
psql "$URL" -X -c "select current_user;" # -> agents_readonly
psql "$URL" -X -c "show statement_timeout;" # -> 10s
psql "$URL" -X -c "select count(*) from public.<big_table>;" # -> real number, NOT 0
psql "$URL" -X -c "delete from public.<any_table> where false;"
# -> ERROR: read-only transaction (soft guardrail)
psql "$URL" -X -c "begin; set transaction read write; delete from public.<any_table> where false; rollback;"
# -> ERROR: permission denied (the hard wall)
psql "$URL" -X -c "select * from public.<denylisted> limit 1;" # -> ERROR: permission denied
psql "$URL" -X -c "select * from auth.users limit 1;" # -> ERROR: permission deniedWrites must be blocked twice over: once by the read-only guardrail, and again by permission denied with the guardrail off. If any check fails, fix the grants and re-run ALL checks.
bypassrls (step 4 of template).agents_readonly.<project-ref>, not bare agents_readonly.statement timeout on legit queries → query too heavy; add filters/limits. Do not raise the timeout as a first resort.revoke select next to the denylist block.alter role agents_readonly with password '...' then update the env var in ~/.zshrc.66860fb
Canonical home
since Jul 27, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.