The bundled reference Rego (`zddc-server --print-rego`) modeled the read-ACL
cascade only, but its header claimed to "mirror the internal decider exactly,
validated on every CI run." It is verb-blind, role-blind, WORM-blind, and
admin-blind: an external-OPA deployment (ZDDC_OPA_URL=http(s)/unix) loading it
granted writes/deletes to read-only principals and ignored WORM zones. The
parity tests never exercised a write action, a role principal, a WORM level, or
is_active_admin — so the divergence shipped silently behind a false "mirrors
exactly" claim.
Make both shipped policies fail-closed instead of falsely-complete:
- access.rego / access_federal.rego: gate every cascade grant on a read action
(empty/absent == read); non-read actions fall through to default-deny.
access.rego honors the single is_active_admin bypass (the one write-capable
principal); access_federal.rego deliberately has none (strict AC-6).
- Rewrite the access.rego / access_federal.rego / rego.go headers: these are
read-ACL SKELETONS, NOT a tested mirror of the internal decider; operators
must add write/WORM/role/admin semantics before granting writes.
- policy.go: fix the stale AllowInput doc claiming the internal decider "treats
read and write identically — any allow grants full CRUD" (it honors the
action verb, with the WORM clamp and admin/elevation bypass applied).
Tests:
- rego_failclosed_test.go: pins the contract — reads allowed, every write verb
denied, active-admin writes allowed (commercial) / denied (federal).
- embedded_neutral_test.go: pins that EmbeddedDefaults() carries no top-level
worm: and no role members — the invariant that makes policy.SerializableChain
dropping PolicyChain.Embedded behavior-neutral (a latent wire-contract gap).
Existing read-cascade parity + federal-divergence tests stay green; full Go
suite + vet pass. The default in-process InternalDecider is unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>