Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,15 @@
"product/admin/tools-and-toolsets",
"product/admin/tool-call-hooks",
"product/admin/ai-clients",
"product/admin/audit-ai-tool-usage"
"product/admin/audit-ai-tool-usage",
{
"group": "Agent guardrails",
"pages": [
"product/admin/agent-guardrails",
"product/admin/agent-guardrails-configure",
"product/admin/agent-guardrails-reference"
]
}
]
},
{
Expand Down
281 changes: 281 additions & 0 deletions product/admin/agent-guardrails-configure.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
---
title: "Configure agent guardrails"
og:title: "Configure agent guardrails - C1 docs"
description: "Create a guardrail, bind it to a surface, author rules, attach hooks and tool gates, and promote rules from Observe to Enforce."
og:description: "Create a guardrail, bind it to a surface, author rules, attach hooks and tool gates, and promote rules from Observe to Enforce."
sidebarTitle: "Configure agent guardrails"
---

{/* Editor Refresh: 2026-07-30 */}

<Note>
**Activation required.** Agent guardrails must be enabled for your tenant before the surfaces below appear. To get started, [contact the C1 support team](mailto:support@c1.ai) for a walkthrough.

Check warning on line 12 in product/admin/agent-guardrails-configure.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/agent-guardrails-configure.mdx#L12

Did you really mean 'walkthrough'?
</Note>

Everything on this page lives under **AI > Guardrails**. The **General** tab holds guardrails, hooks, and tool gates; the **Settings** tab holds the untrusted content judge.

Check warning on line 15 in product/admin/agent-guardrails-configure.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/agent-guardrails-configure.mdx#L15

Did you really mean 'untrusted'?

The order below is deliberate: create the guardrail, bind it, then author rules in **Observe** mode and promote them to **Enforce** once you've seen what they catch on real traffic.

## Step 1: Create a guardrail

Start from **AI > Guardrails**, where every guardrail you create is listed alongside its bindings, rules, hooks, and tool gates.

<Steps>
<Step>
Go to **AI > Guardrails** and click **Create guardrail**.
</Step>
<Step>
Enter a **Name** (required, up to 128 characters) and optionally a **Description** (up to 1024 characters).
</Step>
<Step>
Set **Applies to** — **Agent** or **Gateway**. Choose deliberately: it determines which risk signals your rules can read, and which selector the guardrail appears in when you bind it.
</Step>
<Step>
Click **Create guardrail**. C1 creates it and opens its detail page.
</Step>
</Steps>

A new guardrail has no rules, so it matches nothing yet. Bind it first (Step 2), then add rules (Step 3) — that way the first rule you author is live in Observe mode immediately and starts producing signal.

<Note>
To rename a guardrail or change its description or surface later, click **Edit** on the **Details** card on its detail page.
</Note>

## Step 2: Bind the guardrail

<Warning>
A guardrail does nothing until it's bound. This is the step people skip — a carefully authored cascade that was never bound is evaluated on exactly zero calls.
</Warning>

Where you bind depends on the surface the guardrail applies to.

### Agent surface

For a tenant-wide default across your C1AI agents:

<Steps>
<Step>
Go to **AI > Guardrails**.
</Step>
<Step>
Under **Default C1AI Guardrail policy**, open the dropdown — it reads **No default guardrail selected** until you set one.
</Step>
<Step>
Pick your guardrail.
</Step>
</Steps>

To override the default for one agent, open that agent from **AI > Agents**, go to its **Guardrails** tab, and select a guardrail there. Choosing **Use the default agent guardrail** clears the override.

<Note>
Only guardrails whose **Applies to** is **Agent** appear in these dropdowns. The match is exact — a guardrail left at the legacy **Any surface** value appears in neither selector.
</Note>

### Gateway surface

For external AI clients connecting through the C1 Gateway:

<Steps>
<Step>
Go to **AI > C1 Gateway > Settings**.
</Step>
<Step>
Under **Default C1 Gateway Guardrail policy**, select your guardrail.
</Step>
</Steps>

The guardrail is now bound and evaluated on every call to that surface — but with no rules yet, it matches nothing.

## Step 3: Author a rule

A guardrail's cascade is empty until you add rules to it. Each rule you create is appended to the bottom of the cascade, so order them deliberately (see [Order the cascade](#order-the-cascade) below).

<Steps>
<Step>
On the guardrail's detail page, click **New guardrail rule**.
</Step>
<Step>
Enter a **Name** and optional **Description**. Name it for the behavior it prevents — this string is what you'll be reading in audit logs later.
</Step>
<Step>
Enter a **Condition (CEL)**. Leave it empty to match every tool call. Available variables:

| Variable | Values |
| :--- | :--- |
| `ctx.private_data` | `LOW`, `MEDIUM`, `HIGH` |
| `ctx.untrusted_content` | `LOW`, `MEDIUM`, `HIGH` — Agent surface only |
| `ctx.exfiltration` | `LOW`, `MEDIUM`, `HIGH` |
| `ctx.tool_name` | string |

For example, to match the untrusted-content exfiltration pattern:

Check warning on line 110 in product/admin/agent-guardrails-configure.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/agent-guardrails-configure.mdx#L110

Did you really mean 'exfiltration'?

```
ctx.untrusted_content == HIGH
&& ctx.exfiltration == HIGH
```
</Step>
<Step>
Choose an **Action**:

- **Block** — deny the call immediately. Gates and hooks are skipped, and the hook/gate pickers disappear from the form.
- **Evaluate hooks** — run the gates and hooks you select below, and let their outcome decide.
</Step>
<Step>
If you chose **Evaluate hooks**, select what this rule dispatches:

| Picker | When it runs |
| :--- | :--- |
| **Pre-tool hooks** | Before the tool call |
| **Post-tool hooks** | After the tool call |
| **Pre-output hooks** | Before the assistant's response is delivered |
| **Tool gates** | Must grant before the tool call executes |

Only hooks and gates with **Managed by guardrails** turned on appear in these lists, and each picker only offers hooks whose event matches it. If something you expect is missing, that's why — see Step 5.

**Pre-output hooks** behave differently from the other three: a rule only takes effect on the outgoing response if it uses **Evaluate hooks** *and* selects at least one pre-output hook. A **Block** rule never applies to outgoing responses. See [Pre-output hooks](/product/admin/agent-guardrails-reference#pre-output-hooks).
</Step>
<Step>
Set **Mode** to **Observe** for now. (**Enforce** applies the outcome; **Disabled** skips the rule.)
</Step>
<Step>
Optionally enter a **Deny reason** (up to 256 characters). It's shown to the caller when this rule denies a call, so write it for whoever hits it — a bare "policy violation" leaves the agent's user with nothing to act on.
</Step>
<Step>
Click **Create**.
</Step>
</Steps>

The rule is appended to the bottom of the cascade in **Observe** mode, where it logs matches without blocking anything.

### Order the cascade

Rules evaluate **top to bottom, first match wins**. Click **Manage guardrail rules** to reorder them with the move controls, or to edit and delete individual rules.

<Warning>
Put narrow rules above broad ones. A catch-all rule with an empty condition matches every call, so anything below it is unreachable.
</Warning>

Each rule renders as an **IF** / **THEN** card showing its condition and its action and mode chips, so you can read the cascade top-down without opening each rule.

## Step 4: Add a tool gate for approval

A tool gate turns a matching call into an approval request instead of a failure.

<Steps>
<Step>
In the **Tool gates** section on **AI > Guardrails**, click **New tool gate**.
</Step>
<Step>
Enter a **Name** (1–100 characters) and optional **Description**.
</Step>
<Step>
Pick a **Grant policy** — this determines who approves and how. Required.
</Step>
<Step>
Enter a **Filter (CEL expression)**. Gate filters read a different variable set than guardrail rules — the call's identity and target rather than the risk axes. The field's helper text names `ctx.tool_name` and `ctx.tool_input`; see the [full list](/product/admin/agent-guardrails-reference#gate-filter-variables).
</Step>
<Step>
Set **Priority** (0–1000, lower matches first) and leave **Enabled** on.
</Step>
<Step>
Turn **Managed by guardrails** **on** so this gate only fires when a rule selects it, then click **Create**.
</Step>
<Step>
Go back to your rule and select the gate under **Tool gates**.
</Step>
</Steps>

<Warning>
If a rule selects more than one tool gate, they don't all apply — **only the first gate whose filter matches runs**, and its grant policy decides the call. Order is enabled-first, then ascending **Priority**, then oldest first, across the gates your rule selected *plus* every gate with **Managed by guardrails** off. Give the gate whose approver should win the lower priority number. See [Only the first matching gate runs](/product/admin/agent-guardrails-reference#only-the-first-matching-gate-runs).
</Warning>

<Note>
Leaving **Managed by guardrails** **off** means the gate evaluates on every matching call independently of any guardrail. That's sometimes what you want — a blanket approval requirement — but it makes the gate invisible to your rule cascade.
</Note>

## Step 5: Attach hooks

Hooks do the inspection and rewriting. Create them in the **Hooks** section of **AI > Guardrails** — see [Tool call hooks](/product/admin/tool-call-hooks) for the full field reference and the built-in patterns.

To make a hook selectable by a guardrail rule, turn on its **Managed by guardrails** toggle, either in the hook form or directly from the toggle column in the hooks table.

<Warning>
Hooks are **fail-closed**: if a hook errors, times out, or its filter expression fails to evaluate, the call is **denied**. A hook selected by an Enforce-mode rule can therefore block traffic because it's broken, not because it matched. Check the recorded status rather than assuming a denial means the guardrail worked.
</Warning>

## Step 6: Promote from Observe to Enforce

Until you do this, a rule in **Observe** is a reporting mechanism, not a control.

<Steps>
<Step>
Leave the rule in **Observe** and run real traffic through it.
</Step>
<Step>
Review what it would have caught — see [Where to find Observe results](#where-to-find-observe-results) below.
</Step>
<Step>
Check both directions: rules that would have fired on calls you consider legitimate (too broad), and risky calls that matched nothing (too narrow).
</Step>
<Step>
Edit the rule and set **Mode** to **Enforce**.
</Step>
</Steps>

Because an Observe match falls through to the next rule, you can safely stage a whole cascade in Observe and promote it rule by rule.

### Where to find Observe results

Every rule that matches a call — enforcing or observing — writes an event to the [C1 system log](/product/admin/system-log). There is no per-guardrail activity view in C1, so the system log is where you read Observe results.

<Warning>
C1 does not surface these events in the admin UI, and nothing notifies you when an Observe rule would have fired. To read them you need a [system log exporter](/product/admin/system-log#sync-c1-system-logs-into-your-siem) configured to your SIEM or data source. Set that up **before** you start an Observe rollout, or the traffic you were staging against passes unrecorded from your point of view.

Check warning on line 232 in product/admin/agent-guardrails-configure.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/agent-guardrails-configure.mdx#L232

Did you really mean 'rollout'?
</Warning>

In the exported OCSF events, guardrail decisions carry:

| Field | Value |
| :--- | :--- |
| `activity_name` | `guardrail_decision` |
| `api.operation` | `aigov.guardrail.decision` |
| `would_have_fired` | `true` for an Observe match; absent or `false` when a rule actually acted |
| `policy_rule_id` | Which rule matched — the rule's ID, not its name |
| `guardrail_id` | Which guardrail the rule belongs to |
| `mode`, `action` | The rule's mode and action at evaluation time |
| `tool_name`, `session_id` | What was called, and in which session |
| `a1_private`, `a2_untrusted`, `a3_exfiltration` | The three risk scores as evaluated |

To count what a rule would have caught, filter on `activity_name = "guardrail_decision"` plus `would_have_fired = true` and your `policy_rule_id`.

<Note>
Observe records are written at **informational** severity — only an actual block is raised above that. A severity filter tuned to warnings and above will exclude exactly the records you're staging against.
</Note>

System log events are retained for 365 days by default.

## Step 7: Configure the untrusted content judge

Check warning on line 256 in product/admin/agent-guardrails-configure.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/agent-guardrails-configure.mdx#L256

Did you really mean 'untrusted'?

The judge produces the `ctx.untrusted_content` signal. It's on by default and needs no setup — but you can turn it off.

<Steps>
<Step>
Go to **AI > Guardrails** and open the **Settings** tab.
</Step>
<Step>
Under **Untrusted content judge**, click **Edit** and toggle it.
</Step>
</Steps>

<Warning>
Turning the judge off doesn't just stop the scoring — `ctx.untrusted_content` then **always evaluates as low risk**. Any rule that gates on it silently stops matching, so a cascade that looks correct is no longer protecting anything. Leave it on unless you have a specific reason, and if you do turn it off, disable the rules that depend on it rather than leaving them in place.
</Warning>

## Delete a guardrail

Open the guardrail and click **Delete** in the top bar. The confirmation dialog names the guardrail and warns the deletion can't be undone. Any binding that pointed at it stops applying.

## Next steps

- Rule fields, CEL variables, and evaluation order: [Agent guardrails reference](/product/admin/agent-guardrails-reference).
- Hook configuration and built-in patterns: [Tool call hooks](/product/admin/tool-call-hooks).
- Controlling which tools exist to be gated at all: [Govern tools and toolsets](/product/admin/tools-and-toolsets).
Loading