Skip to content
Cisco AI Defense logo
CiscoAI Security

Actions matrix — DefenseClaw

Overview

The actions matrix is the deterministic mapping from a finding's (severity, direction, guardrail.mode) tuple to a concrete action. It lives in policies/rego/data.json under actions.matrix and is applied by guardrail.rego.

The default matrix

Severity \ Modeobserveaction
CRITICALlogblock
HIGHlogblock
MEDIUMlogwarn
LOWloglog
INFOloglog

warn means the response is allowed but a notification and an audit row are emitted; block means the request is refused.

Per-direction overrides

In production most fleets want different thresholds on prompt vs completion. data.json supports:

{
  "actions": {
    "matrix": {
      "prompt":     { "CRITICAL": "block", "HIGH": "block", "MEDIUM": "warn", "LOW": "log", "INFO": "log" },
      "completion": { "CRITICAL": "block", "HIGH": "warn",  "MEDIUM": "log",  "LOW": "log", "INFO": "log" },
      "tool_call":  { "CRITICAL": "block", "HIGH": "block", "MEDIUM": "warn", "LOW": "log", "INFO": "log" }
    }
  }
}

Completion is intentionally looser because a mid-response block has worse UX than a pre-call block.

Why Rego owns the matrix

Keeping the matrix in data.json + guardrail.rego (rather than hardcoding it in Go) means:

  • Operators can override per deployment without recompiling.
  • The audit row records which version of the matrix was applied (via policy_hash).
  • The matrix is testable with opa test — every row and every edge case is covered by guardrail_test.rego.
  • Composing matrices across tenants becomes a data-merge, not a code change.

Custom severities

The severity enum is fixed (CRITICAL, HIGH, MEDIUM, LOW, INFO). You cannot add a new level. This is deliberate — keeping the enum small and stable is what makes the matrix auditable and dashboards readable across fleets.

If you need a "security team attention" bucket, use tags on the rule to route rather than inventing a new severity.

Related