prove-a-read-only-credential-cannot-write

Confirm that a database role handed to an agent actually refuses writes, by the permission check rather than by an error that happened to arrive first.

Procedure

  1. start start. Goes next to s1
  2. check The role holds no administrative membership. Goes on_fail to s11; next to s2
  3. check It can read what it is meant to read. Goes on_fail to s11; next to s3
  4. check The write privilege is absent, asked directly. Goes on_fail to s11; next to s4
  5. check And a write attempt is actually refused. Goes on_fail to s5; next to s6
  6. wait Fix the probe, then attempt the write again. Goes retry to s4; next to s11
  7. check A private table is out of reach. Goes on_fail to s11; next to s7
  8. check The grant list is the one that was intended. Goes on_fail to s11; next to s8
  9. decision Is there a pooler in front of this database?. Goes if pooled to s9; if default to s10
  10. check The same refusal holds through the pooler. Goes on_fail to s11; next to s10
  11. check The second line of defence is in force here. Goes on_fail to s11; next to __end_success
  12. escalate Escalate before the credential is used. Terminal
  13. end success. Terminal

Open the graph on its own page — larger, printable, and an address you can send.

Walk it without running it — you answer what your environment would answer, and the path, the capabilities, the approvals and the distance back to an undo come out of the document. Nothing executes; there is no Run button here and there will not be one.

Trust

T2 · attested 2026-10-11 · runbooks.directory

Nobody has attested this record. That is the ordinary case: T2 is what the catalog can check on its own, and T3 needs somebody to run the procedure and sign for it.

  • Link liveness has not been checked: it needs a network and the catalog builds without one. Run pnpm gates --online where there is one.

Steps

  1. s1 check — The role holds no administrative membership
  2. s2 check — It can read what it is meant to read
  3. s3 check — The write privilege is absent, asked directly
  4. s4 check — And a write attempt is actually refused
  5. s5 wait — Fix the probe, then attempt the write again
  6. s6 check — A private table is out of reach
  7. s7 check — The grant list is the one that was intended
  8. s8 decision — Is there a pooler in front of this database?
  9. s9 check — The same refusal holds through the pooler
  10. s10 check — The second line of defence is in force here
  11. s11 escalate — Escalate before the credential is used

Capabilities

This is a privilege request. Check it against your own allowlist before running.

  • cli:psql — used by s1, s2, s3, s4, s6, s7, s9, s10

Provenance

Source
https://runbooks.directory/r/std/prove-a-read-only-credential-cannot-write/source.md
Fetched
2026-09-04
Source last checked
not since it was captured on 2026-09-04 — recorded as current
Licence
CC-BY-4.0
How it got here
Written by this catalog's maintainers and reviewed in full.
Highest risk in this procedure
read-only

Take it with you

Run it under supervision

Runs here, on your machine, under supervision: every step is proposed before it happens, an approval gate stops for you, and a failed expectation goes where the procedure says rather than on to the next step. Nothing is sent anywhere. To supervise an agent that is doing the work instead, runbooks hook sits in its tool-call path.

npx @runbooks/cli run std/prove-a-read-only-credential-cannot-write@1.0.0 --as "$(whoami)" \
  --input role_url=<connection string for the role being proved, on the direct endpoint> \
  --input allowed_table=<a table the role is meant to read> \
  --input private_table=<a table the role must not reach>