Skip to content

Commit 46392fb

Browse files
committed
docs(tenant): keep CLAUDE definer path contract current
1 parent 6c0df8e commit 46392fb

1 file changed

Lines changed: 25 additions & 22 deletions

File tree

CLAUDE.md

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,30 @@
3737
principal check is transitive: once a caller can enter a user-schema
3838
`SECURITY DEFINER`, admission must recursively follow any further user-schema
3939
`SECURITY DEFINER` that the discovered owner can execute through schema `USAGE`
40-
plus routine `EXECUTE`, using a cycle-safe owner closure. A safe outer owner
41-
therefore cannot hide a dangerous inner definer that the caller cannot execute
42-
directly. PostgreSQL lets the membership administrator grant a role onward even
43-
when that administrator's own membership is `INHERIT FALSE, SET FALSE`; the
44-
recipient can then use the granted selectable path after a security-definer call
45-
returns. `SECURITY DEFINER` executes with its owner's privileges rather than the
46-
caller's privileges. Admission must re-prove the sole canonical tenant policy's
47-
command, role scope, permissive mode, `USING`/`WITH CHECK` predicates, and
48-
reviewed catalog dependencies before tenant binding or outbox SQL. Direct
49-
runtime `CREATEDB` and `CREATEROLE` are database/role administration
50-
capabilities; callable `CREATEROLE` is executable within the definer boundary,
51-
while `CREATEDB` remains covered when membership administration grants that
52-
authority onward for later invoker-context use. `REPLICATION` is separate
53-
cluster-level connection and slot authority whether held directly or anywhere
54-
in the callable-definer owner closure, and direct DML grant options, relation
55-
maintenance, authority-bearing role administration, and executable privileged
56-
definer authority are outside application DML. Runtime identities remain
57-
`NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS` and need only
58-
non-grantable outbox `SELECT` and `INSERT`. Migration success is point-in-time
59-
evidence, not continuing authority after policy, ACL, membership, routine, or
60-
role-attribute DDL.
40+
plus routine `EXECUTE`, using a cycle-safe owner closure. Every callable routine
41+
in that closure must also pin routine-level `search_path = pg_catalog, pg_temp`;
42+
absent or different name-resolution authority is rejected before tenant binding
43+
or outbox data SQL rather than inheriting caller temporary-schema state. A safe
44+
outer owner therefore cannot hide a dangerous inner definer that the caller
45+
cannot execute directly. PostgreSQL lets the membership administrator grant a
46+
role onward even when that administrator's own membership is `INHERIT FALSE,
47+
SET FALSE`; the recipient can then use the granted selectable path after a
48+
security-definer call returns. `SECURITY DEFINER` executes with its owner's
49+
privileges rather than the caller's privileges. Admission must re-prove the sole
50+
canonical tenant policy's command, role scope, permissive mode, `USING`/`WITH
51+
CHECK` predicates, and reviewed catalog dependencies before tenant binding or
52+
outbox SQL. Direct runtime `CREATEDB` and `CREATEROLE` are database/role
53+
administration capabilities; callable `CREATEROLE` is executable within the
54+
definer boundary, while `CREATEDB` remains covered when membership
55+
administration grants that authority onward for later invoker-context use.
56+
`REPLICATION` is separate cluster-level connection and slot authority whether
57+
held directly or anywhere in the callable-definer owner closure, and direct DML
58+
grant options, relation maintenance, authority-bearing role administration, and
59+
executable privileged definer authority are outside application DML. Runtime
60+
identities remain `NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION
61+
NOBYPASSRLS` and need only non-grantable outbox `SELECT` and `INSERT`. Migration
62+
success is point-in-time evidence, not continuing authority after policy, ACL,
63+
membership, routine, or role-attribute DDL.
6164
- Keep owner-enforcement relaxation, legacy backfill, constraint migration, and
6265
forced-RLS restoration inside one atomic PostgreSQL statement.
6366
- Keep `pg_llm_batch/schema.sql` and
@@ -66,4 +69,4 @@
6669
synchronized with every tenant security or migration change.
6770
- Maintain 100% production statement, branch, and public-docstring coverage.
6871
Add realistic migration, rollback, compatibility, security, and
69-
tenant-isolation tests before implementation changes.
72+
tenant-isolation tests before implementation changes.

0 commit comments

Comments
 (0)