githubinferredactive
carranca
provenance:github:pboueke/carranca
Isolated agent runtime with verified audits, deep observability, policy enforcement, and adversarial hardening
README
<div align="center">
<img src="doc/page/carranca.jpg" alt="Carranca" width="600" />
<p><em>A Carranca photographed by Marcel Gautherot in 1946. Instituto Moreira Salles collection.</em></p>
<h1>Carranca</h1>
<p>
<img src="https://img.shields.io/badge/version-0.17.6-blue" alt="version: 0.17.6" />
<img src="https://img.shields.io/badge/tests-982%2F982_passed-brightgreen" alt="tests: 982/982 passed" />
<img src="https://img.shields.io/badge/coverage-100%25_(147%2F147_functions)-brightgreen" alt="coverage: 100%" />
<img src="https://img.shields.io/badge/license-MIT-green" alt="license: MIT" />
</p>
<p><strong>Isolated agent runtime with reviewable evidence, deep observability, policy enforcement, and adversarial hardening.</strong> Named after the carved figureheads on boats in Brazil's São Francisco river, believed to protect sailors. Carranca protects engineers from coding agents by running them in hardened containers with tamper-evident logs, kernel-level tracing, enforceable guardrails, and forgery detection.
</p>
</div>
## Documentation
| Doc | What it covers |
|-----|---------------|
| [Quickstart](doc/quickstart.md) | Get from zero to a running agent session in under five minutes |
| [Objective](doc/objective.md) | Current product position, intended users, non-goals, and comparison with other sandbox models |
| [Usage](doc/usage.md) | Detailed CLI command reference, options, and operator workflows |
| [Architecture](doc/architecture.md) | Container layout, data flow, directory structure |
| [CI/CD integration](doc/ci.md) | Headless execution, timeouts, exit codes, session artifacts, and GitHub Actions patterns |
| [Configuration](doc/configuration.md) | `.carranca.yml` reference, Containerfile, init flags |
| [Examples](doc/examples/README.md) | Persona-based example `.carranca.yml` and `.carranca/Containerfile` setups |
| [Session log](doc/session-log.md) | JSONL schema, event types, `jq` query examples |
| [Trust model](doc/trust-model.md) | Threat table, failure behavior, honest scope |
| [FAQ](doc/faq.md) | Preemptive answers: why Bash, eval safety, HMAC scope |
| [Versioning](doc/versioning.md) | Semver policy, changelog format |
Open [doc/page/index.html](https://pboueke.github.io/carranca/) for the full technical reference. The markdown files in [`doc/`](doc/) remain the source chapters and companion guides. Run `carranca help <command>` for command-specific options. See [usage.md](doc/usage.md) for the full CLI reference and [configuration.md](doc/configuration.md) for the `.carranca.yml` schema. Persona-oriented example setups live under [doc/examples/](doc/examples/).
## How it works
Carranca invokes the container runtime CLI directly. Supported engines are
Podman and Docker, selected by `CARRANCA_CONTAINER_RUNTIME` or
`runtime.engine`; `auto` prefers Podman and falls back to Docker.
Each `carranca run` session creates a small set of runtime resources:
- an **agent container** built from `.carranca/Containerfile`
- a **logger container** that receives events and writes audit artifacts
- an optional **observer container** for independent execve and network tracing
- a shared **tmpfs volume** containing a Unix FIFO for event transport
The user-controlled surface is the project configuration:
`.carranca.yml` defines the agent command, runtime settings, and policy;
`.carranca/Containerfile` defines the toolchain available inside the agent
container. Carranca manages the logger, observer, transient images, and session
state.
During execution, the agent container receives the workspace as a bind mount and
runs with a hardened baseline: read-only root filesystem, all capabilities
dropped, and seccomp filtering (with an optional strict allowlist profile via
`runtime.seccomp_profile: strict`). On Linux, it runs as the invoking host UID:GID,
or with `--userns keep-id` on rootless Podman, so workspace writes retain
usable host ownership.
The shell wrapper inside the agent container emits events to the FIFO. The
logger consumes those events and writes a structured JSONL session log, a
checksum file, and a per-session HMAC key that the agent cannot access. When
enabled, the independent observer records a second view of process execution and
network activity from outside the agent's namespaces.
```
carranca run
│
├── <runtime> run -d (logger: FIFO + file observation + JSONL/HMAC)
├── <runtime> run -d (observer: strace + /proc/net/tcp, optional)
└── <runtime> run -it (agent: shell-wrapper + configured agent command)
```
After the session, `carranca log` inspects, verifies, or exports the resulting
artifacts, and `carranca status` shows active and recent sessions for the
current repository.
## Example session
```console
$ carranca run --agent codex
[carranca] Session: a3f7c91d2e4b8016
[carranca] Runtime: podman (rootless)
[carranca] Building logger image...
[carranca] Building agent image...
[carranca] Logger started
[carranca] Agent started — codex
# ... agent works, operator interacts ...
[carranca] Agent exited (0)
[carranca] Session complete: a3f7c91d2e4b8016
```
Inspect the session with `carranca log --timeline`:
```
Timeline: session a3f7c91d2e4b8016
──────────────────────────────────────────────────────────────
TIME EVENT
──────────────────────────────────────────────────────────────
14:00:00 >> session start (codex via podman)
14:00:03 $ git status (exit=0, 312ms)
14:00:07 F~ /workspace/src/main.py MODIFY
14:00:08 $ python -m pytest tests/ (exit=0, 2847ms)
14:00:12 F+ /workspace/tests/test_main.py CREATE
14:00:15 N 142.251.46.206:443 tcp ESTABLISHED
14:00:30 . heartbeat
14:01:45 << agent stop (exit=0)
──────────────────────────────────────────────────────────────
Duration: 1m 45s | 2 commands | 2 file events | 0 failures
```
Session logs are structured JSONL with HMAC-signed event chains:
```jsonl
{"type":"session_event","source":"carranca","event":"start","ts":"2026-03-27T14:00:00.000Z","session_id":"a3f7c91d2e4b8016","agent":"codex","engine":"podman","seq":1,"hmac":"d4f8..."}
{"type":"shell_command","source":"shell-wrapper","ts":"2026-03-27T14:00:03.421Z","session_id":"a3f7c91d2e4b8016","command":"git status","exit_code":0,"cwd":"/workspace","seq":2,"hmac":"8b1a..."}
{"type":"file_event","source":"inotifywait","ts":"2026-03-27T14:00:07.893Z","session_id":"a3f7c91d2e4b8016","event":"MODIFY","path":"/workspace/src/main.py","seq":3,"hmac":"c2e7..."}
```
Verify log integrity after a session:
```console
$ carranca log --verify
[carranca] Verifying session a3f7c91d2e4b8016...
[carranca] HMAC chain: valid (47 events)
[carranca] Checksums: valid
[carranca] Result: PASS
$ carranca log --verify # after tampering with the log
[carranca] Verifying session a3f7c91d2e4b8016...
[carranca] HMAC chain: BROKEN at event 23 (expected a1b2..., got f4e5...)
[carranca] Result: FAIL — log integrity compromised
```
## Platform support
- **Linux**: Full support for current logging model, including `inotifywait`
file mutation events.
- **macOS/Windows**: Experimental. Container runtime behavior varies, and file
mutation logging is Linux-only today.
## License
MIT
PUBLIC HISTORY
First discoveredMar 26, 2026
IDENTITY
inferred
Identity inferred from code signals. No PROVENANCE.yml found.
Is this yours? Claim it →METADATA
platformgithub
first seenMar 22, 2026
last updatedMar 25, 2026
last crawled22 days ago
version—
README BADGE
Add to your README:
