---
title: "Guardrails"
description: "Install tenant-wide checks and select their packs."
canonical_url: "https://docs.oz0.ai/build/plugins/verified/guardrails"
---
# Guardrails

> Install tenant-wide checks and select their packs.

For: tenant administrators and plugin users.

Install `ai.oz0/guardrails` to apply its [hooks](https://docs.oz0.ai/build/parts/hooks) to every tool call and job in the tenant. It is not installed by default and is not a member of [Essentials](https://docs.oz0.ai/build/plugins/verified/essentials). These checks run only after a tenant installs it.

The platform's [command rules](https://docs.oz0.ai/govern/command-rules) already ask about catastrophic shell commands on every node, using the same reader and default rules as this plugin's command guard. Guardrails is free under Apache License 2.0, as are the other checks that protect data. It provides six checks:

<table>
<thead>
  <tr>
    <th>
      Check
    </th>
    
    <th>
      Hook
    </th>
    
    <th>
      What it does by default
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Classified text
    </td>
    
    <td>
      <code>
        job_start
      </code>
      
      , <code>
        post_tool_call
      </code>
      
       and <code>
        job_end
      </code>
      
      , first: <code>
        oz0_guardrails.classified
      </code>
    </td>
    
    <td>
      A job's input, a tool's result or a job's output that carries a security-classification marking (HEMLIG and its levels, VS-NfD and the other VS grades, RESTREINT UE/EU RESTRICTED and above) is refused before a model reads it; nobody is asked
    </td>
  </tr>
  
  <tr>
    <td>
      Personal data
    </td>
    
    <td>
      <code>
        post_tool_call
      </code>
      
       and <code>
        job_end
      </code>
      
      : <code>
        oz0_guardrails.redact
      </code>
    </td>
    
    <td>
      Each match in a tool's result or a job's output becomes <code>
        [PII:&lt;label>]
      </code>
      
      , such as <code>
        [PII:personnummer]
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Secrets
    </td>
    
    <td>
      the same hook
    </td>
    
    <td>
      The tenant's own secrets become <code>
        [SECRET:&lt;name>]
      </code>
      
      , such as <code>
        [SECRET:TEAM_TOKEN]
      </code>
      
      , and well-known key formats <code>
        [SECRET:&lt;label>]
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Injection
    </td>
    
    <td>
      <code>
        post_tool_call
      </code>
      
      : <code>
        oz0_guardrails.injection
      </code>
    </td>
    
    <td>
      A result that reads like an injection waits for a person before the model reads it
    </td>
  </tr>
  
  <tr>
    <td>
      Shell commands
    </td>
    
    <td>
      <code>
        pre_tool_call
      </code>
      
      : <code>
        oz0_guardrails.command_guard
      </code>
    </td>
    
    <td>
      Uses platform command rules on current nodes and asks about catastrophic or unreadable commands on older nodes. See <a href="#command-checks-by-runtime-version">
        runtime coverage
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      Intent
    </td>
    
    <td>
      <code>
        pre_tool_call
      </code>
      
      : <code>
        oz0_guardrails.intent_check
      </code>
    </td>
    
    <td>
      Off. When on, a model is asked whether the call fits what the job was asked to do; when it says no, the call waits for a person
    </td>
  </tr>
</tbody>
</table>

### Command checks by runtime version

On a node whose runtime decides commands itself, as this release's does, the hook leaves commands to the platform's [command rules](https://docs.oz0.ai/govern/command-rules). Those rules ask about the same catastrophic commands by default.

On an older node, a harness shell command waits for a person when it is catastrophic or cannot be read with certainty. Examples include `rm -rf ~`, `mkfs`, a force push to `main`, and `curl ... | sh`. The request explains the reason; the hook refuses nothing. See [The command guard](https://docs.oz0.ai/build/plugins/verified/guardrails/commands#the-command-guard).

The classified check runs first, then redaction, then the injection check, so a person who is asked about a result
sees it redacted. Before a call, the command guard runs before the intent check: it asks no model. A tool `oz0_guardrails.scan`
(read-only) and the agent `oz0-guardrails-check` say what a text holds, by pack and position, without repeating it;
the scan reads the text and its folded form as the hooks do, and redacts it as the redaction hook would.

These are checks, not a guarantee. They find formats, not meaning: read [what they miss](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#what-the-checks-miss)
before you rely on them, and keep the [tool policy](https://docs.oz0.ai/govern/tool-policy), [taint and labels](https://docs.oz0.ai/govern/taint-and-labels)
and approvals as they are.

## Install

Its agent `oz0-guardrails-check` asks for the tenant's `default` [model alias](https://docs.oz0.ai/spend/models-and-keys/aliases#the-standard-aliases) with tools, never a vendor's model, so it runs on whichever provider the tenant set up first; map it elsewhere with `oz0 model alias set default <provider>/<model>`.

```bash [Terminal]
oz0 plugin install hub:ai.oz0/guardrails --accept-model
```

The hub is not public yet; until it is, install from a checkout: `oz0 plugin install plugins/guardrails --accept-model`.

`--accept-model` lets the intent check call a model in the calling job's name (see [The intent check](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#the-intent-check)).
The install is refused without it and says so. `oz0 plugin revoke-reads guardrails model` takes the grant back: the
other checks keep working, and the intent check, when on, sends every call to a person with the reason.

## Packs

The patterns are packs of data, each with its own tests (examples that must match and that must not) and a note on its
false positives. Every pack is on unless you turn it off.

<table>
<thead>
  <tr>
    <th>
      Pack
    </th>
    
    <th>
      Finds
    </th>
    
    <th>
      Checked with
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        pii.core
      </code>
    </td>
    
    <td>
      Email addresses, international phone numbers, payment card numbers, IBANs (with or without spaces)
    </td>
    
    <td>
      Luhn for cards, mod-97 for IBANs
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.se
      </code>
    </td>
    
    <td>
      Swedish personnummer and samordningsnummer (with or without the century, <code>
        -
      </code>
      
       or <code>
        +
      </code>
      
      ), Swedish mobile numbers
    </td>
    
    <td>
      The control digit (Luhn), a valid date; a samordningsnummer's day is 61 to 91
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.no
      </code>
    </td>
    
    <td>
      Norwegian fødselsnummer and D-nummer
    </td>
    
    <td>
      Both mod-11 control digits, a valid date
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.dk
      </code>
    </td>
    
    <td>
      Danish CPR numbers
    </td>
    
    <td>
      A valid date, and a word such as <code>
        CPR
      </code>
      
       near it (the control digit is not reliable since 2007)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.fi
      </code>
    </td>
    
    <td>
      Finnish henkilötunnus, with the century signs of 2023
    </td>
    
    <td>
      The mod-31 control character
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.is
      </code>
    </td>
    
    <td>
      Icelandic kennitala
    </td>
    
    <td>
      The mod-11 control digit, a valid date
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pii.de
      </code>
    </td>
    
    <td>
      The German Steuer-Identifikationsnummer and ID card number
    </td>
    
    <td>
      ISO 7064 MOD 11,10 for the tax ID, the ICAO 7-3-1 check digit for the card, and a context word near each
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        classified.core
      </code>
    </td>
    
    <td>
      Security-classification markings, one per level, in capitals as they are stamped: the Swedish security classes (<code>
        KVALIFICERAT HEMLIG
      </code>
      
      , <code>
        HEMLIG
      </code>
      
      , <code>
        KONFIDENTIELL
      </code>
      
      , <code>
        BEGRÄNSAT HEMLIG
      </code>
      
      ), the German VS grades (<code>
        STRENG GEHEIM
      </code>
      
      , <code>
        GEHEIM
      </code>
      
      , <code>
        VS-VERTRAULICH
      </code>
      
      , <code>
        VS-NUR FÜR DEN DIENSTGEBRAUCH
      </code>
      
       or <code>
        VS-NfD
      </code>
      
       in any case) and the EU classified markings (<code>
        TRÈS SECRET UE
      </code>
      
      /<code>
        EU TOP SECRET
      </code>
      
      , <code>
        SECRET UE
      </code>
      
      /<code>
        EU SECRET
      </code>
      
      , <code>
        CONFIDENTIEL UE
      </code>
      
      /<code>
        EU CONFIDENTIAL
      </code>
      
      , <code>
        RESTREINT UE
      </code>
      
      /<code>
        EU RESTRICTED
      </code>
      
      , and the short forms <code>
        TS-UE/EU-TS
      </code>
      
      , <code>
        S-UE/EU-S
      </code>
      
      , <code>
        C-UE/EU-C
      </code>
      
      , <code>
        R-UE/EU-R
      </code>
      
      )
    </td>
    
    <td>
      The words only, with any spaces, non-breaking spaces or line breaks between them; always on (see <a href="https://docs.oz0.ai/build/plugins/verified/guardrails/classified-text#classified-text">
        Classified text
      </a>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        secrets.formats
      </code>
    </td>
    
    <td>
      Cloud access key IDs, forge and chat tokens, payment live keys, API keys of common shapes, private key blocks, JWTs
    </td>
    
    <td>
      The format only
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        injection.core
      </code>
    </td>
    
    <td>
      Instruction overrides, "new instructions", role changes, chat-template markers, requests for the system prompt, exfiltration phrasing, forged tool calls; and hidden text (invisible characters)
    </td>
    
    <td>
      Patterns only
    </td>
  </tr>
</tbody>
</table>

The injection check uses patterns only. A small local classifier would need a model file downloaded at run time, which
the plugin does not do; so it catches phrasing, not intent, and the [threat model](https://docs.oz0.ai/concepts/threat-model/origins-and-results#checks-on-what-tools-return)
says what that leaves.

## Related tasks

- [Configure guardrails](https://docs.oz0.ai/build/plugins/verified/guardrails/settings): Look up settings that control the guardrail checks.
- [Check classified text](https://docs.oz0.ai/build/plugins/verified/guardrails/classified-text): Understand classification matching and refusal behaviour.
- [Check shell commands](https://docs.oz0.ai/build/plugins/verified/guardrails/commands): Understand command parsing and approval behaviour on current and older nodes.
- [Guardrail coverage and limits](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits): Configure intent checks and understand what redaction and detection can miss.

<legacy-sections>

- <span id="classified-text">

Section

</span>

: [classified text](https://docs.oz0.ai/build/plugins/verified/guardrails/classified-text#classified-text)
- <span id="invisible-characters-and-look-alike-letters">

Section

</span>

: [invisible characters and look alike letters](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#invisible-characters-and-look-alike-letters)
- <span id="settings">

Section

</span>

: [settings](https://docs.oz0.ai/build/plugins/verified/guardrails/settings#settings)
- <span id="the-command-guard">

Section

</span>

: [the command guard](https://docs.oz0.ai/build/plugins/verified/guardrails/commands#the-command-guard)
- <span id="the-intent-check">

Section

</span>

: [the intent check](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#the-intent-check)
- <span id="what-redaction-does-not-remove">

Section

</span>

: [what redaction does not remove](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#what-redaction-does-not-remove)
- <span id="what-the-checks-miss">

Section

</span>

: [what the checks miss](https://docs.oz0.ai/build/plugins/verified/guardrails/intent-and-limits#what-the-checks-miss)
- <span id="your-own-packs">

Section

</span>

: [your own packs](https://docs.oz0.ai/build/plugins/verified/guardrails/settings#your-own-packs)

</legacy-sections>


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
