Decision: external OPA is a bring-your-own-policy escape hatch, not a
supported turnkey mode — so stop shipping access_federal.rego. A verb-blind
read-ACL policy under NIST AC-6 branding is a liability to hand a federal
evaluator, and (like access.rego before the fail-close) it over-granted writes
and ignored WORM. The HTTPDecider + Decider interface stay: operators who want
an AC-6 ancestor-deny-absolute posture write their own Rego.
- Delete rego/access_federal.rego, FederalRego, --print-rego=federal, and
federal_parity_test.go; trim the federal cases from rego_failclosed_test.go.
- Reframe every doc reference (rego.go, main.go, file.go, ARCHITECTURE.md,
README.md) to "operators write their own Rego"; rewrite the README
"Reference Rego policy" section to describe the single fail-closed read-ACL
skeleton accurately (it also still carried the now-removed "mirrors exactly"
parity claim).
Out of scope (flagged): the broader federal-readiness narrative
(FedRAMP/FIPS/IdP) and the separate website page federal.html still discuss
federal posture — the OPA bring-your-own-Rego path stays valid, but a
deliberate review with the federal go-to-market in mind is warranted.
go vet + full go test ./... green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>