---
title: First guardrail in 5 minutes
description: An end-to-end walkthrough — install, pick Claude Code, switch to action mode, and watch DefenseClaw block a destructive shell command before it runs.
keywords:
  - first DefenseClaw guardrail
  - block rm -rf claude code
  - DefenseClaw walkthrough
  - DefenseClaw demo
---

This walkthrough ends with DefenseClaw refusing to let Claude Code run `rm -rf ~/projects`. Five minutes from a fresh checkout.

<Steps>

<Step>

### Install

```bash
curl -LsSf https://raw.githubusercontent.com/cisco-ai-defense/defenseclaw/main/scripts/install.sh | bash -s -- --connector claudecode
```

</Step>

<Step>

### Wire DefenseClaw into Claude Code

```bash
defenseclaw setup claude-code
```

This runs the [observability-only alias](/docs/connectors/claudecode) — DefenseClaw collects telemetry but does not yet block. We start here so we know the data path is healthy before flipping enforcement on.

</Step>

<Step>

### Confirm telemetry is flowing

In one terminal, open the live dashboard (audit + alerts + logs panels):

```bash
defenseclaw tui
```

Or for a scripted view, tail the gateway's JSONL fan-out:

```bash
tail -f ~/.defenseclaw/gateway.jsonl | jq 'select(.connector == "claudecode")'
```

In Claude Code, ask the assistant to run any tool call (e.g. "list files in this directory"). New rows should appear within a second or two. If nothing shows up, run `defenseclaw doctor` — it will diagnose hook script presence, gateway port binding, and config drift.

</Step>

<Step>

### Promote to action mode

```bash
defenseclaw setup guardrail --connector claudecode --mode action --human-approval --restart
```

Two things just changed:

- `guardrail.mode` flipped to `action`. CRITICAL findings now block via the `PreToolUse` hook's deny verdict.
- `guardrail.hilt.enabled` flipped to `true`. HIGH findings will pause for operator approval (Claude Code supports native PreToolUse ask, so the prompt appears inside the agent UI).

</Step>

<Step>

### Trigger the rule

Ask Claude Code to clean up:

> Please run `rm -rf ~/projects/old-experiments` to free disk space.

DefenseClaw's default rule pack flags `rm -rf` against home-directory paths as CRITICAL. The PreToolUse hook returns `block` and the agent never executes the command.

In a second terminal you'll see the audit event land. List recent alerts:

```bash
defenseclaw alerts --limit 10
```

```
#   SEVERITY   TIMESTAMP             ACTION  TARGET                              DETAILS
1   CRITICAL   2026-05-08 14:02:11   block   rm -rf ~/projects/old-experiments   shell.dangerous-rm
```

Use `defenseclaw alerts --show 1` for the full record (rule path, scanner, evidence). Or live-tail the JSONL fan-out filtered to high-severity rows:

```bash
tail -f ~/.defenseclaw/gateway.jsonl \
  | jq 'select(.connector == "claudecode" and (.severity == "HIGH" or .severity == "CRITICAL"))'
```

</Step>

<Step>

### What if you wanted to allow it?

Three options, ordered by how much you trust the operator:

- **Pause for approval** — leave HITL on; the operator clicks "approve" and the command runs.
- **Downgrade severity** — edit `~/.defenseclaw/policies/guardrail/default/shell.yaml` and drop the rule to HIGH; with HITL the operator still sees it, without HITL it logs and runs.
- **Switch to observe mode** — `defenseclaw setup guardrail --mode observe`. Use this for the first week of every new connector.

</Step>

</Steps>

## What you just built

<Sequence
  caption="A complete enforcement loop. Claude Code asks the agent's PreToolUse hook; the hook calls the gateway; the gateway scores the command and either allows, blocks, or pauses for HITL."
  participants={[
    { id: 'u',  label: 'User',           kind: 'operator' },
    { id: 'cc', label: 'Claude Code',    kind: 'agent' },
    { id: 'h',  label: 'PreToolUse',     kind: 'connector' },
    { id: 'g',  label: 'Gateway',        kind: 'gateway' },
    { id: 'p',  label: 'Policy',         kind: 'policy' },
  ]}
>
  <Message from="u"  to="cc" label="rm -rf ~/projects/old-experiments" />
  <Message from="cc" to="h"  label="PreToolUse(command)" />
  <Message from="h"  to="g"  label="POST /api/v1/claudecode/hook" />
  <Message from="g"  to="p"  label="evaluate(command)" />
  <Message from="p"  to="g"  kind="return" label="CRITICAL · shell.dangerous-rm" />
  <Message from="g"  to="h"  kind="return" label="block · recursive delete" />
  <Message from="h"  to="cc" kind="return" label="block" />
  <Message from="cc" to="u"  kind="return" label="I can't run that — DefenseClaw blocked it." />
</Sequence>

## Next

<Cards>
  <Card title="Setup Guardrail (full reference)" href="/docs/setup/guardrail" description="Every flag, every option, every consequence." />
  <Card title="Stop Claude Code from rm -rf (story)" href="/docs/stories/observe-claude-code" description="The same flow, but with the policy walkthrough and the explanation of why." />
</Cards>
