Operator decision: use research as design input, adopt tooling only where it is
an established standard with broad application, otherwise build ground up so we
can refactor freely.
Settles two open recommendations. AuthZEN qualifies (OpenID Final Spec,
multi-vendor interop) and stays as the proposed A4 rung; OWASP stays as a
baseline; PostgreSQL RLS mechanics are facts, not tooling. pgrls and pgTAP are
out as dependencies - we take pgrls's rule taxonomy as a checklist for probes
we write into the existing isolation-test.sh harness, which already found four
real defects and has no dependency tree. Its SAFE/BREAKING policy-diff idea is
the structural contribution worth reimplementing.
Also records that gap G1 was designed rather than deferred, and the finding
that came out of it: per-consumer physical retention is not implementable on
CNPG, so the erasure horizon is the instance maximum and retention becomes a
placement trigger.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Checked the repo rather than trusting the search snippet. Confirms the
capability claims (MIT, 67 rules, 54 of them security, Z3 isolation proofs,
SAFE/BREAKING policy-diff for CI gating, pytest plugin, PG 15-17) and corrects
the auto-fixable count from 20 to 19.
It is also 26 stars and self-described beta. That does not change the
recommendation to adopt the approach, but it does change the recommendation to
adopt the tool: it is a supply-chain decision, not a free win. pgTAP is
long-established and carries no such caveat. Saying so now is cheaper than
having a reviewer discover it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four search-and-read passes against AWS Well-Architected SaaS Lens, Azure
Architecture Center, OWASP, the OpenID Foundation, and PostgreSQL practitioner
literature. Each digest holds one of our ladders against outside practice and
lists its sources.
Headline: the draft-1 -> draft-2 reframe is corroborated. Microsoft states
"isolation is a spectrum, not a discrete property" and derives our E/P coupling
independently. The shape is sound; the details are not.
Five corrections draft-2 needs:
- E3 overclaims. Any session can re-SET the GUC, so RLS is strong against a
forgotten predicate and useless against SQL injection or a compromised
process. The ADR says "the application cannot trivially route around" - the
exact overclaim it prohibits elsewhere.
- The pooling claim in section 16 is backwards. Transaction-scoped SET LOCAL is
what makes E3 safe under pooling; statement-level pooling is what serves
other tenants' rows, only under production concurrency.
- E3 layers on E2 rather than superseding it.
- Placement cannot be expressed per tenant, but the commercial section requires
exactly that - a tier bought by some tenants puts a service at two P levels
at once, which the posture vector cannot represent.
- FORCE ROW LEVEL SECURITY is mandatory: ADR-0001 already established that our
migration role owns the tables it creates, so it would silently bypass every
policy.
Also: pgTAP and pgrls make the E3 evidence artifact far cheaper than assumed;
OWASP publishes a Multi-Tenant Security Cheat Sheet we reference nowhere; our
tenant-boundary gap is BOLA, OWASP API1, top of that list since it launched;
AuthZEN 1.0 went Final in January and flex-auth is pre-standard; and no plane
covers tenant offboarding, which OWASP makes a MUST.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>