Tawa docs

Policy rules

The rule schema evaluated on every scan, and the directives it can contribute to a verdict.

Every scan accepts a policyOverrides/policy_overrides array — additive rules evaluated on top of your app's saved policy, not a replacement for it. A matched rule contributes directives to the result's policy field; your application decides what to actually do with them, the same way it decides what to do with action (see Enforcing a policy below).

request body
{
  "text": "…",
  "policyOverrides": [
    {
      "id": "block-finance-tool-for-guests",
      "when": { "tool_name": "transfer_funds", "caller_role": "guest" },
      "directives": ["block"]
    }
  ]
}
response (relevant fields)
{
  "policy": {
    "directives": ["block"],
    "matchedRuleIds": ["block-finance-tool-for-guests"]
  }
}

A rule

  • id — your own identifier, echoed back in matchedRuleIds when the rule fires.
  • when — conditions, ANDed together. A rule with an empty when matches every request.
  • directives — strings your rule contributes to the verdict when it matches. Free-form except for a couple the engine treats specially (see below) — define whatever vocabulary makes sense for your application and branch on it at the call site.
  • force (optional) — "block" or "allow". A matching force rule short-circuits every other rule; force: "block" always wins if both a block and an allow force-rule somehow match (safety-first).

What you can match on

KeyMatches
tool_injection_flag, prompt_extraction_flag, jailbreak_flagBoolean detection flags for this scan
risk_gte, risk_lteThe scan's risk score
provenanceWhat kind of content this is (user_prompt, rag_chunk, tool_call, ...)
tool_name, tool_name_inThe tool being called (agent protection only)
caller_role, caller_role_notThe role you passed for whoever initiated the call
operation_typeYour own operation classification, if you set one
tool_call_scopeA coarse scope classification of the tool's arguments
sensitive_dataWhether sensitive data was detected
keywords_anyAny of a list of keywords appearing in the text
length_gte, length_lteThe text's length

Directives with built-in meaning

Two directive strings get special handling by the engine on top of the normal union-of-matched-rules behavior:

  • "block" — as a force rule's directive (or via force: "block" itself), short-circuits every other rule. As a plain directive from a normal rule, it's just unioned in like anything else — your app decides whether to treat it as authoritative.
  • "disable_tools" — automatically suffixed with the tool name at match time ("disable_tools:run_query"), so one rule can disable whichever tool triggered it without hardcoding the name.

"redact_pii" and "log_security_event" can also appear automatically, contributed by your app's PII detection settings rather than a rule you wrote — same field, same union.

Everything else is your own vocabulary — define whatever directive strings make sense ("strip_system_prompt", "require_human_review", ...) and branch on them where you enforce the policy.

The worker only signals directives — it never withholds a tool call or otherwise enforces anything on your behalf. Enforcement is always your application's responsibility, matching how action works.

Enforcing a policy

Activating a template or a custom rule in the dashboard's Policy Studio only changes what result.policy contains on future scans — it never blocks anything by itself. For the exact pattern per integration (raw HTTP, the SDKs, and the framework integrations), see:

On this page