Skip to content
Merged
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
92 changes: 58 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,64 @@

Tools to let coding agents access the shell with opinionated defaults.

## Security model

Most agent actions should run under [`//sandbox`](sandbox/BUILD.bazel).
Command filtering complements sandboxing by narrowly delegating selected CLI
capabilities, including commands that intentionally use the user's ambient
credentials. It is not a substitute for sandboxing.

Command filtering is useful for narrowing which command lines an agent may run:
which binaries are allowed, which subcommands and flags are allowed, and which
logical paths may be passed as arguments. That is a least-authority delegation
mechanism, not a full security boundary.

If an allowed command can use the user's ambient credentials, network access,
or other external authority, then allowing that command is effectively
granting that capability to the agent. Path restrictions such as `<path:r>`
and `<path:w>` only constrain named file arguments; they do not constrain
unrelated side effects a command may have.

For example, a user might grant an agent permission to fetch GitHub Actions
logs via a narrow `gh` rule. That is different from allowing arbitrary `gh`
usage: the rule is a deliberate delegation of one credential-backed
capability, not blanket authority over the GitHub CLI.

Some allowed tools may execute hooks, helpers, pagers, editors, or other
user-controlled programs as part of their normal behavior.
Rules should be written with those secondary execution paths in mind.

Practical guidance:

- Prefer running agent actions in `//sandbox`.
- Use command filters to grant narrow, reviewable capabilities, especially for
tools that intentionally act with the user's ambient credentials.
- Write rules per operation, not per binary.
- Treat each allow-rule as a permission grant that should be reviewed.
## Components

- **[`sandbox`](sandbox/)** — nsjail-based execution sandbox. The container
boundary is the primary security model: the agent runs with full freedom
inside the sandbox but cannot access host credentials or mutate the host
filesystem.
- **[`command_filter`](command_filter/)** — rule language and filter for
host-side command execution. Complements sandboxing by narrowly delegating
specific CLI capabilities the agent may use with the user's ambient
credentials.
- **[`exec_service`](exec_service/)** — gRPC service for streaming command
execution over Unix sockets.
- **[`mcpmux`](mcpmux/)** — MCP proxy for developing and testing MCP servers.
The agent can edit a server, start it through `mcpmux`, and exercise it
through the same MCP session — a full edit-test cycle.

File access is out of scope. Agents use their native file tools for that.

## Compositions

The sandbox boundary can be drawn at different points.

**Agent inside the sandbox.** The agent process runs inside `sandbox` and
executes commands freely; the container wall is the only boundary.
`command_filter` governs any host-side commands the agent is granted.

**Agent outside the sandbox.** The agent runs on the host and sends commands
to `exec_service` inside the sandbox over a Unix socket. `command_filter`
is not needed for sandboxed execution but may still govern other host-side
commands.

## Development

Builds and tests are hermetic via Bazel. The main development loop is:

```sh
bazel test //...
```

This builds everything and runs all tests. Bazel's caching makes repeated
runs fast — only targets affected by your edits are rebuilt.

### Coverage

```sh
bazel coverage //... --combined_report=lcov
```

The combined LCOV report is printed at the end of the output. To render it
as HTML:

```sh
genhtml --output coverage-html "$(bazel info output_path)/_coverage/_coverage_report.dat"
```

### Distribution tarball

`bazel build //dist` packages the binaries into a single tarball.

## License

Expand Down
6 changes: 1 addition & 5 deletions command_filter/LANGUAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ A small language for defining allowed command invocations. Each rule file
describes the permitted argument shapes for a command, with path arguments
carrying read/write permission annotations.

This language describes which command lines are permitted. It does not by
itself provide process isolation. In this repository, most agent actions
should run under `//sandbox`; command filtering is used to narrowly delegate
specific CLI capabilities, including commands that intentionally use ambient
user credentials.
See [README.md](README.md) for the security model and practical guidance.

## Statements

Expand Down
40 changes: 40 additions & 0 deletions command_filter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Command Filter

A command filter evaluates a proposed command line against a developer-authored
rule file and returns allow or deny. It is used to narrowly delegate specific
CLI capabilities to an agent, including commands that intentionally use the
user's ambient credentials.

See [LANGUAGE.md](LANGUAGE.md) for the rule language specification.

## Security model

Command filtering complements sandboxing by narrowing which command lines an
agent may run: which binaries are allowed, which subcommands and flags are
allowed, and which logical paths may be passed as arguments. That is a
least-authority delegation mechanism, not a full security boundary. Most agent
actions should run under [`//sandbox`](../sandbox/BUILD.bazel); command
filtering is not a substitute for sandboxing.

If an allowed command can use the user's ambient credentials, network access,
or other external authority, then allowing that command is effectively
granting that capability to the agent. Path restrictions such as `<path:r>`
and `<path:w>` only constrain named file arguments; they do not constrain
unrelated side effects a command may have.

For example, a user might grant an agent permission to fetch GitHub Actions
logs via a narrow `gh` rule. That is different from allowing arbitrary `gh`
usage: the rule is a deliberate delegation of one credential-backed
capability, not blanket authority over the GitHub CLI.

Some allowed tools may execute hooks, helpers, pagers, editors, or other
user-controlled programs as part of their normal behavior.
Rules should be written with those secondary execution paths in mind.

## Practical guidance

- Prefer running agent actions in `//sandbox`.
- Use command filters to grant narrow, reviewable capabilities, especially for
tools that intentionally act with the user's ambient credentials.
- Write rules per operation, not per binary.
- Treat each allow-rule as a permission grant that should be reviewed.
Loading