Policy shadows
A shadow is two policies covering the same (SCIM group, segment) pair
with the same action. Redundant. Probably safe.
A conflict is the same overlap with different actions. One says
ALLOW, the other says BLOCK_ACCESS. Whichever has the lower
RuleOrder wins, but the existence of both is a smell - the losing rule is
either dead or hiding intent that nobody documented.
Endpoint
GET /api/v1/analytics/policy-shadowsReturns
type PolicyShadowReport struct { PolicyA PolicySummary PolicyB PolicySummary // higher RuleOrder, the shadowed one SharedScimGroups []NamedRef SharedSegments []NamedRef Verdict string // "shadow" or "conflict"}
type PolicySummary struct { ID string Name string Action string // ALLOW | BLOCK_ACCESS RuleOrder int}PolicyA.RuleOrder < PolicyB.RuleOrder. PolicyA is the one that actually
fires; PolicyB is the one that gets reached only when PolicyA’s conditions
do not match.
Verdict semantics
PolicyA.Action | PolicyB.Action | Verdict |
|---|---|---|
ALLOW | ALLOW | shadow |
BLOCK_ACCESS | BLOCK_ACCESS | shadow |
ALLOW | BLOCK_ACCESS | conflict |
BLOCK_ACCESS | ALLOW | conflict |
How
For each policy, build the set of (scimGroupID, segmentID) pairs it
covers. Walk every pair of policies; if their pair-sets intersect,
produce a report. Quadratic in policy count - on a tenant with 500 policies
that is 125k comparisons, fast enough to do live.
Use it for
- Cleanup. Shadows are pure redundancy. Pick one, delete the other.
- Audit. Conflicts mean somebody added a
BLOCK_ACCESSlater without removing the originalALLOW(or vice versa). Find the author, ask why. - Refactor planning. Heavy overlap across many policies usually means the SCIM group or segment group hierarchy needs rethinking.