---
title: Quick start
description: Install nd7, run Claude Code inside the sandbox, and turn on recording, in five minutes.
order: 20
section: Getting started
---

Five steps, on macOS, from nothing to a sandboxed and recorded Claude Code session.

## Install both binaries

**Install `nd7` and `nd7-exec` with one cargo command.**

```sh
cargo install --locked --git https://github.com/nd7-dev/nd7-core
```

That single command installs both programs into `~/.cargo/bin`. They must stay side by side, because `nd7 run` finds `nd7-exec` by looking beside itself and refuses to start if it is missing or writable by anyone but you.

## Check that it worked

**`nd7 --help` lists the commands; `nd7-exec` on its own prints usage.**

```sh
nd7 --help
nd7-exec
```

`nd7 --help` prints `record`, `verify`, `enroll`, `ship`, `run`, `hook-prefix`, `allow` and `deny`. `nd7-exec` prints its own usage and exits 2, which is the expected result outside a session.

## Run Claude Code inside the sandbox

**Change into your project and start the session there.**

```sh
cd your-project
nd7 run claude
```

The directory you are in is **the project**: the one place the agent may write from the start. Before Claude Code starts, `nd7 run` prints one line naming the session:

```
nd7 run: session 41287 under nd7's policy; a sandbox the program applies itself is refused
```

## Let the agent write somewhere else, mid-session

**From another terminal, grant a path while the session is still running.**

```sh
nd7 allow ~/data
nd7 deny  ~/data
```

The next Bash command already runs under the new rules — no restart, no signal. Grants reach Bash commands but not the `Write` and `Edit` tools, which run inside the `claude` process.

## Turn on the audit log

**Register `nd7 record` as a hook in `~/.claude/settings.json` for every project, or in the project's own `.claude/settings.json`.**

```json
{
  "hooks": {
    "SessionStart":       [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "UserPromptSubmit":   [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "PreToolUse":         [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "PostToolUse":        [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "PostToolUseFailure": [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "Stop":               [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 5 }] }],
    "SessionEnd":         [{ "hooks": [{ "type": "command", "command": "nd7", "args": ["record"], "timeout": 1 }] }]
  }
}
```

`nd7 run` sets up the sandbox but does not register the recorder, so this is a separate, one-time step. Afterwards, check a session's hash chain:

```sh
ls ~/.local/state/nd7/sessions/
nd7 verify <session-id>
```

Each directory under `~/.local/state/nd7/sessions/` is one session, named after Claude Code's own session id; that name is the `<session-id>` argument.

## Next

- [A session, start to finish](/docs/session-walkthrough): the same session in detail, including what `nd7 run` passes to Claude Code and what happens at the first denial.
- [How the macOS sandbox works](/docs/sandbox): the exact rules, rule by rule.
- [Change the rules while the agent works](/docs/allow-deny): what `nd7 allow` and `nd7 deny` do, and when.
- [How the audit log works](/docs/audit-log): what ends up on disk, and what `nd7 verify` proves.
