Skip to content

pboueke/carranca

Repository files navigation

Carranca

A Carranca photographed by Marcel Gautherot in 1946. Instituto Moreira Salles collection.

Carranca

version: 0.17.6 tests: 982/982 passed coverage: 100% license: MIT

Isolated agent runtime with reviewable evidence, deep observability, policy enforcement, and adversarial hardening. 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.

Documentation

Doc What it covers
Quickstart Get from zero to a running agent session in under five minutes
Objective Current product position, intended users, non-goals, and comparison with other sandbox models
Usage Detailed CLI command reference, options, and operator workflows
Architecture Container layout, data flow, directory structure
CI/CD integration Headless execution, timeouts, exit codes, session artifacts, and GitHub Actions patterns
Configuration .carranca.yml reference, Containerfile, init flags
Examples Persona-based example .carranca.yml and .carranca/Containerfile setups
Session log JSONL schema, event types, jq query examples
Trust model Threat table, failure behavior, honest scope
FAQ Preemptive answers: why Bash, eval safety, HMAC scope
Versioning Semver policy, changelog format

Open doc/page/index.html for the full technical reference. The markdown files in doc/ remain the source chapters and companion guides. Run carranca help <command> for command-specific options. See usage.md for the full CLI reference and configuration.md for the .carranca.yml schema. Persona-oriented example setups live under 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

$ 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:

{"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:

$ 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

Packages

 
 
 

Contributors

Languages