ZDDC/zddc/internal
ZDDC d14516a74d fix(server): fail-close the reference Rego; stop claiming internal-decider parity
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>
2026-06-09 19:30:09 -05:00
..
apps chore(embedded): cut v0.0.27-beta 2026-06-09 10:30:20 -05:00
archive fix(archive): log swallowed walkdir errors during transmittal indexing 2026-05-21 16:41:29 -05:00
auth feat(server): self-issued bearer tokens + --no-auth flag 2026-05-08 07:40:28 -05:00
cache fix(cache): track background revalidation goroutines; drain on shutdown + in tests 2026-05-21 16:21:37 -05:00
config feat(server): local-only tool-HTML override; remove apps URL/version fetching 2026-06-04 08:59:28 -05:00
convert feat(browse): schema completion in the front-matter editor (keys + enum values) 2026-06-08 09:09:37 -05:00
fs feat(server): cascade-resolved display: labels for the canonical project peers 2026-06-05 17:48:46 -05:00
handler fix(server): MOVE must require config-edit authority for .zddc/.zddc.zip 2026-06-09 18:06:28 -05:00
jsonschema feat(forms): augment served schema with cascade field_codes + locks 2026-05-19 09:58:21 -05:00
listing feat(browse): render default_tool=tables dirs (mdl/rsk/ssr) as click-to-table leaves 2026-06-05 17:18:47 -05:00
policy fix(server): fail-close the reference Rego; stop claiming internal-decider parity 2026-06-09 19:30:09 -05:00
tlsutil feat(server): TLS hardening per NIST SP 800-52 Rev. 2 + HSTS 2026-05-04 17:55:52 -05:00
zddc fix(server): fail-close the reference Rego; stop claiming internal-decider parity 2026-06-09 19:30:09 -05:00
zipfs feat(zddc): serve a .zip as a virtual directory (zipfs + dispatch intercept) 2026-05-12 12:17:47 -05:00