Skip to content

Policy and Exceptions

Wakemeup edited this page Aug 25, 2026 · 2 revisions

Policy and Exceptions

Policies are strict YAML or TOML documents with schema version 1. Unknown fields, invalid glob patterns, duplicate IDs, malformed SPDX expressions, and invalid ranges are rejected.

version: 1
fail_closed:
  unknown_applicability: true
  unknown_licenses: true
default_outcome: warn
rules:
  - id: deny-critical-runtime
    priority: 100
    outcome: deny
    reason: Critical runtime findings are release blocking
    selectors:
      minimum_severity: critical
      scopes: [runtime]
  - id: deny-unfixed-cves
    priority: 90
    outcome: deny
    reason: Known CVEs without available fixes block release
    selectors:
      cves: [CVE-2026-1234]
      fix_available: false
  - id: allow-mit
    priority: 50
    outcome: allow
    reason: MIT is approved
    selectors:
      kinds: [license]
      license_expressions: [MIT]
exceptions:
  - id: temporary-ghsa-exception
    owner: security@example.com
    reason: Upgrade is being validated
    ticket: SEC-1234
    expires_at: "2026-08-01T00:00:00Z"
    compensating_controls:
      - Service is isolated from untrusted input
    selectors:
      advisory_id: GHSA-example

Rule selectors

Rules can match conjunctively on:

  • finding kinds;
  • minimum severity and confidence;
  • applicability states;
  • risk-score ranges;
  • dependency scopes;
  • package-URL globs;
  • rule-ID and advisory-ID globs;
  • exact license expressions;
  • fix availability; and
  • exact CVE or advisory identifiers matched against advisory IDs and aliases.

Rules are ordered by descending priority and then stable rule ID. Outcomes are allow, warn, and deny; default_outcome applies when no rule matches.

Fail-closed behavior

unknown_applicability denies vulnerability findings whose impact cannot be established. unknown_licenses denies components without known license expressions. These checks happen before ordinary rule selection.

Exceptions

Every exception requires an ID, owner, reason, ticket, RFC 3339 expiration, and at least one exact selector. Exception selectors do not accept globs. An exception applies only when every populated selector matches the finding and selected policy decision. Expiration is strict; an exception at its expiry instant is expired. A secret finding can be pinned exactly by the SHA-256 fingerprint recorded in its evidence.

Use compensating controls to record temporary defenses, not as a substitute for selectors or expiry.

Commands

hooray policy validate hooray-policy.yaml
hooray policy evaluate hooray-policy.yaml --run-id 'run:UUID' --format json

Policy documents, exceptions, optimistic updates, and audit records can also be managed through the HTTP API.

Clone this wiki locally