docs(zddc): tighten inherit/strict-mode docstrings + AllowedAtLevel deprecation
Address two follow-ups from the security review of feat/zddc-inherit-directive: 1. file.go's Inherit docstring previously claimed "the internal decider treats it as inherit:true and emits a warning at evaluation time" — the decider does the first part but the warning was never wired up. Strike the over-promise; point operators at the cascade tracer (`/.profile/effective-policy`) which surfaces both `cascade_mode` and `chain.visible_start` so a fenced configuration that's being ignored under strict mode is visible. 2. AllowedAtLevel hardcodes ModeDelegated. Safe today (1-level synthetic chain, no ancestors) but a footgun if anyone migrates the shim to a real PolicyChain later. Add a `// Deprecated:` marker pointing at GrantedVerbsAtLevel for fence-aware paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ee50213e0b
commit
dc7bf8ab04
2 changed files with 16 additions and 5 deletions
|
|
@ -3,8 +3,16 @@ package zddc
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
// AllowedAtLevel is a thin shim over GrantedVerbsAtLevel preserved for
|
// AllowedAtLevel is a thin shim over GrantedVerbsAtLevel preserved for
|
||||||
// callers that only need the legacy boolean read decision. New code
|
// callers that only need the legacy boolean read decision on a single
|
||||||
// should call GrantedVerbsAtLevel directly.
|
// ZddcFile (no cascade chain).
|
||||||
|
//
|
||||||
|
// Hardcodes ModeDelegated — safe because the synthetic chain has only
|
||||||
|
// one level and no ancestors to fence — but callers that operate on a
|
||||||
|
// real PolicyChain must call GrantedVerbsAtLevel directly with the
|
||||||
|
// active mode.
|
||||||
|
//
|
||||||
|
// Deprecated: prefer GrantedVerbsAtLevel for any code path that may
|
||||||
|
// later need fence-aware or strict-mode evaluation.
|
||||||
func AllowedAtLevel(level ZddcFile, email string) (decision bool, matched bool) {
|
func AllowedAtLevel(level ZddcFile, email string) (decision bool, matched bool) {
|
||||||
chain := PolicyChain{Levels: []ZddcFile{level}, HasAnyFile: true}
|
chain := PolicyChain{Levels: []ZddcFile{level}, HasAnyFile: true}
|
||||||
v, m := GrantedVerbsAtLevel(chain, 0, email, ModeDelegated)
|
v, m := GrantedVerbsAtLevel(chain, 0, email, ModeDelegated)
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,12 @@ import (
|
||||||
//
|
//
|
||||||
// In strict cascade mode (federal / NIST AC-6), inherit:false is
|
// In strict cascade mode (federal / NIST AC-6), inherit:false is
|
||||||
// REFUSED — a leaf-level directive cannot widen access an ancestor
|
// REFUSED — a leaf-level directive cannot widen access an ancestor
|
||||||
// refused. The internal decider treats it as inherit:true and emits a
|
// refused. The internal decider silently treats it as inherit:true;
|
||||||
// warning at evaluation time. Operators running the federal Rego
|
// the cascade tracer (/.profile/effective-policy) reports both
|
||||||
// preset get the same behaviour from policy enforcement.
|
// `cascade_mode` and `chain.visible_start` so an operator can see
|
||||||
|
// that a configured fence is being ignored under the active mode.
|
||||||
|
// Operators running the federal Rego preset get the same behaviour
|
||||||
|
// from policy enforcement.
|
||||||
//
|
//
|
||||||
// Inherit is per-level and not itself cascading: an ancestor's
|
// Inherit is per-level and not itself cascading: an ancestor's
|
||||||
// `inherit: false` does not transitively block descendants from
|
// `inherit: false` does not transitively block descendants from
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue