Files
git.stella-ops.org/docs/policy/exception-effects.md
root 68da90a11a
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Restructure solution layout by module
2025-10-28 15:10:40 +02:00

9.3 KiB
Raw Blame History

Policy Exception Effects

Audience: Policy authors, reviewers, operators, and governance owners.
Scope: How exception definitions are authored, resolved, and surfaced by the Policy Engine during evaluation, including precedence rules, metadata flow, and simulation/diff behaviour.

Exception effects let teams codify governed waivers without compromising determinism. This guide explains the artefacts involved, how the evaluator selects a single winning exception, and where downstream consumers observe the applied override.


1·Exception Building Blocks

Artefact Description
Exception Effect Declared inside a policy pack (exceptions.effects). Defines the override behaviour plus governance metadata. See effect fields in §2.
Routing Template Optional mapping (exceptions.routingTemplates) used by Authority to route approvals/MFA. Effects reference templates by id.
Exception Instance Stored outside the policy pack (Authority/API). Captures who requested the waiver, scope filters, metadata, and creation time.

Effects are validated at bind time (PolicyBinder), while instances are ingested alongside policy evaluation inputs. Both are normalized to case-insensitive identifiers to avoid duplicate conflicts.


2·Effect Fields

Field Required Purpose Notes
id Stable identifier ([A-Za-z0-9-_]+). Must be unique per policy pack.
name Friendly label for consoles/reports. Forwarded to verdict metadata if present.
effect Behaviour enum: suppress, defer, downgrade, requireControl. Case-insensitive.
downgradeSeverity ⚠️ Target severity for downgrade. Must map to DSL severities (high, medium, etc.). Validation enforced in PolicyBinder (policy.exceptions.effect.downgrade.missingSeverity).
requiredControlId ⚠️ Control catalogue key for requireControl. Required when effect is requireControl.
routingTemplate Connects to an Authority approval flow. CLI/Console resolve to authorityRouteId.
maxDurationDays Soft limit for temporary waivers. Must be > 0 when provided.
description Rich-text rationale. Displayed in approvals centre (optional).

Authoring invalid combinations returns structured errors with JSON paths, preventing packs from compiling (see src/Policy/__Tests/StellaOps.Policy.Tests/PolicyBinderTests.cs:33). Routing templates additionally declare authorityRouteId and requireMfa flags for governance routing.


3·Exception Instances & Scope

Instances are resolved from Authority or API collections and injected into the evaluation context (PolicyEvaluationExceptions). Each instance contains:

Field Source Usage
id Authority storage Propagated to annotations and appliedException.exceptionId.
effectId Links to pack-defined effect Must resolve to a known effect; otherwise ignored.
scope.ruleNames Optional list Limits to specific rule identifiers.
scope.severities Optional list (severity.normalized) Normalized against the evaluators severity string.
scope.sources Optional advisory sources (GHSA, NVD, …) Compared against the advisory context.
scope.tags Optional SBOM tags Matched using sbom.has_tag(...).
createdAt RFC3339 UTC timestamp Used as tie-breaker when specificity scores match.
metadata Arbitrary key/value bag Copied to verdict annotations (exception.meta.*).

Scopes are case-insensitive and trimmed. Empty scopes behave as global waivers but still require routing and metadata supplied by Authority workflows.


4·Resolution & Specificity

Only one exception effect is applied per finding. Evaluation proceeds as follows:

  1. Filter instances whose effectId resolves to a known effect.
  2. Discard instances whose scope does not match the candidate finding (rule name, severity, advisory source, SBOM tags).
  3. Score remaining instances for specificity:
    • ruleNames1000 + (count × 25)
    • severities500 + (count × 10)
    • sources250 + (count × 10)
    • tags100 + (count × 5)
  4. Highest score wins. Ties fall back to the newest createdAt, then lexical id (stable sorting).

These rules guarantee deterministic selection even when multiple waivers overlap. See src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyEvaluatorTests.cs:209 for tie-break coverage.


5·Effect Behaviours

Effect Status impact Severity impact Warnings / metadata
suppress Forces status suppressed. No change. exception.status=suppressed.
defer Forces status deferred. No change. exception.status=deferred.
downgrade No change. Sets severity to configured downgradeSeverity. exception.severity annotation.
requireControl No change. No change. Adds warning Exception '<id>' requires control '<requiredControlId>'. Annotation exception.requiredControl.

All effects stamp shared annotations: exception.id, exception.effectId, exception.effectType, optional exception.effectName, optional exception.routingTemplate, plus exception.maxDurationDays. Instance metadata is surfaced both in annotations (exception.meta.<key>) and the structured AppliedException.Metadata payload for downstream APIs. Behaviour is validated by unit tests (src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyEvaluatorTests.cs:130 & src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyEvaluatorTests.cs:169).


6·Explain, Simulation & Outputs

  • Explain traces / CLI simulate Verdict payloads include appliedException capturing original vs applied status/severity, enabling diff visualisation in Console and CLI previews.
  • Annotations Deterministic keys make it trivial for exports or alerting pipelines to flag waived findings.
  • Warnings requireControl adds runtime warnings so operators can enforce completion of compensating controls.
  • Routing When routingTemplate is populated, verdict metadata includes routingTemplate, allowing UI surfaces to deep-link into the approvals centre.

Example verdict excerpt (JSON):

{
  "status": "suppressed",
  "severity": "Critical",
  "annotations": {
    "exception.id": "exc-001",
    "exception.effectId": "suppress-critical",
    "exception.effectType": "Suppress",
    "exception.status": "suppressed",
    "exception.meta.requestedBy": "alice"
  },
  "appliedException": {
    "exceptionId": "exc-001",
    "effectId": "suppress-critical",
    "effectType": "Suppress",
    "originalStatus": "blocked",
    "appliedStatus": "suppressed",
    "metadata": {
      "effectName": "Rule Critical Suppress",
      "requestedBy": "alice"
    }
  }
}

7·Operational Notes

  • Authoring Policy packs must ship effect definitions before Authority can issue instances. CLI validation (stella policy lint) fails if required fields are missing.
  • Approvals & MFA Effects referencing routing templates inherit requireMfa rules from exceptions.routingTemplates. When a template requires MFA, Authority will refuse to mint tokens containing exceptions:approve unless the authenticating identity provider exposes MFA capability; the failure is logged as authority.password.grant with reason="Exception approval scope requires an MFA-capable identity provider." Review /docs/security/authority-scopes.md for scope/role assignments and /docs/11_AUTHORITY.md for configuration samples.
  • Presence in exports Even when an exception suppresses a finding, explain traces and effective findings retain the applied exception metadata for audit parity.
  • Determinism Specificity scoring plus tie-breakers ensure repeatable outcomes across runs, supporting sealed/offline replay.

8·Testing References

  • src/Policy/__Tests/StellaOps.Policy.Tests/PolicyBinderTests.cs:33 Validates schema rules for defining effects, routing templates, and downgrade guardrails.
  • src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyEvaluatorTests.cs:130 Covers suppression, downgrade, and metadata propagation.
  • src/Policy/__Tests/StellaOps.Policy.Engine.Tests/PolicyEvaluatorTests.cs:209 Confirms specificity ordering and metadata forwarding for competing exceptions.

9·Compliance Checklist

  • Effect catalogue maintained: Each policy pack documents available effects and routing templates for auditors.
  • Authority alignment: Approval routes in Authority mirror routingTemplate definitions and enforce MFA where required.
  • Explain coverage: Console/CLI surfaces display appliedException details and exception.* annotations for every waived verdict.
  • Simulation parity: stella policy simulate outputs include exception metadata, ensuring PR/CI reviews catch unintended waivers.
  • Audit retention: Effective findings history retains appliedException payloads so exception lifecycle reviews remain replayable.
  • Tests locked: Binder and evaluator tests covering exception paths remain green before publishing documentation updates.

Last updated: 2025-10-27 (Sprint 25).