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>
52 lines
2.4 KiB
Go
52 lines
2.4 KiB
Go
package policy
|
|
|
|
import _ "embed"
|
|
|
|
// ReferenceRego is a read-ACL Rego SKELETON bundled with zddc-server for
|
|
// external-OPA deployments. It models the read cascade ONLY and is NOT a
|
|
// semantic mirror of the InternalDecider: it does not implement per-verb
|
|
// authorization (write/create/delete/admin), WORM zones, roles, fences, or
|
|
// config-edit, so it is FAIL-CLOSED — every non-read action is denied except
|
|
// for an elevated admin (input.user.is_active_admin). The InternalDecider
|
|
// remains the production source of truth. parity_test.go (OPA as a test-only
|
|
// dependency, so the production binary stays OPA-free) checks the modelled
|
|
// read-cascade dimension only — it does NOT prove full parity.
|
|
//
|
|
// Operators running an external OPA can use this as a STARTING POINT — they
|
|
// must add the unmodelled write/WORM/role/admin semantics before relying on
|
|
// it for write authorization:
|
|
//
|
|
// zddc-server --print-rego > /etc/opa/policies/zddc-access.rego
|
|
//
|
|
// Customizations typical for federal deployments:
|
|
//
|
|
// - Flip the leaf-allow-overrides-parent-deny semantics so parent denies
|
|
// are absolute (NIST AC-6 least-privilege posture). For this specific
|
|
// case zddc-server ships a parity-tested federal-mode variant; see
|
|
// FederalRego and `--print-rego=federal`.
|
|
// - Add role-based access via additional input fields (input.user.roles
|
|
// populated by the upstream proxy from SAML/OIDC claims).
|
|
// - Add time-of-day or IP-range constraints.
|
|
// - Emit decision logs in a SIEM-friendly format via OPA's logging
|
|
// plugins.
|
|
//
|
|
//go:embed rego/access.rego
|
|
var ReferenceRego string
|
|
|
|
// FederalRego is the strict-least-privilege variant of ReferenceRego
|
|
// where parent denies are absolute (NIST AC-6). Drop-in for federal
|
|
// customers who need the AC-6 posture without writing Rego from
|
|
// scratch:
|
|
//
|
|
// zddc-server --print-rego=federal > /etc/opa/policies/zddc-access.rego
|
|
//
|
|
// The internal Go evaluator does NOT implement these semantics — it
|
|
// stays on the commercial cascade. Federal-mode is reachable only by
|
|
// running OPA with this policy and pointing ZDDC_OPA_URL at it. See
|
|
// zddc/internal/policy/rego/access_federal.rego for the policy itself
|
|
// and federal_parity_test.go for the divergence-test fixtures (cases
|
|
// where federal-mode and commercial-mode disagree, asserting each gives
|
|
// the expected verdict).
|
|
//
|
|
//go:embed rego/access_federal.rego
|
|
var FederalRego string
|