Ship a second parity-tested Rego policy that flips the cascade's
leaf-allow-overrides-parent-deny rule for NIST AC-6 conformance.
Standard cascade (existing access.rego, mirrors internal Go evaluator):
Bottom-up walk; first explicit match wins; deny-first within a level.
A leaf-level allow CAN override an ancestor's deny. This is the
cascade's intentional delegation property — a project-owner who
re-allows a previously-denied collaborator works as expected.
Federal mode (new access_federal.rego):
Any deny anywhere along the chain is absolute. An allow only matters
if no level (any depth) has denied the same email. Required by
NIST AC-6 default expectations: a central admin's deny at the root
must be unbypassable by a tenant who controls a subtree's .zddc.
Operators run real OPA with this Rego and point ZDDC_OPA_URL at it;
the internal Go evaluator stays on the commercial cascade. The
toggle is "which policy does your OPA evaluate," not a knob inside
zddc-server.
Surfaced via --print-rego flag:
zddc-server --print-rego # standard (default)
zddc-server --print-rego=standard # same
zddc-server --print-rego=federal # AC-6 strict variant
Parity test (federal_parity_test.go) compiles both Regos and asserts:
* They AGREE on every cascade scenario where no ancestor-deny
intersects a leaf-allow (most cases).
* They DISAGREE — by design — on the three scenarios where the
AC-6 rule differs:
- "leaf allows what parent denied" → standard allows, federal denies
- "deep leaf re-allows after middle deny" → same
- "glob deny at root + specific allow at leaf" → same
Cross-checks the divergence flag explicitly so any future change that
accidentally collapses the two policies fails the test.
Closes the AC-6 row of the federal-readiness gap analysis (now marked
"partially complete" in zddc/README.md — the full bullet would be a
built-in --policy-mode=federal toggle that also flips the in-process
Go evaluator).
Production binary unchanged at 13.1 MB (Rego files embedded as bytes;
OPA library remains test-only).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 lines
1.9 KiB
Go
46 lines
1.9 KiB
Go
package policy
|
|
|
|
import _ "embed"
|
|
|
|
// ReferenceRego is the canonical Rego policy bundled with zddc-server.
|
|
// It mirrors the InternalDecider's semantics exactly — every release CI
|
|
// run validates parity via parity_test.go (which imports the OPA library
|
|
// as a test-only dependency, so the production binary stays OPA-free).
|
|
//
|
|
// Operators running an external OPA can use this as the starting point
|
|
// for their own policy bundle:
|
|
//
|
|
// 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
|