Quickstart
This quickstart takes you from nothing installed to a real agent running under enforcement: its outbound calls are checked against policy, allowed or denied, and written to the audit log.
The default install path uses a single precompiled static binary. You do not need a build toolchain, or any API keys, unless you choose to build from source.
Install
Section titled “Install”OpenFirma can be installed with a one-line script or built from source. The script downloads the right binary for your platform, puts it on your PATH, and offers to scaffold your first project.
-
Run the installer.
On Linux and macOS:
Terminal window curl -fsSL https://install.openfirma.ai | shOn Windows (PowerShell):
Terminal window iwr -useb https://install.openfirma.ai/install.ps1 | iex -
Confirm
firmais on yourPATH.Terminal window firma --versionIf the command is not found, open a new terminal so your shell picks up the updated
PATH, then try again.
The installer drops the binary in ~/.local/bin by default and adds it to your shell’s PATH.
Prerequisites:
- Rust 1.88 or newer.
protoc, the Protocol Buffers compiler.git.
Clone the repository:
git clone https://github.com/Firma-AI/openfirma.gitcd openfirmaInstall the current source checkout:
cargo install --path crates/firma --lockedThis installs firma into Cargo’s binary directory, usually ~/.cargo/bin. If firma --version is not found, make sure that directory is on your PATH.
Set up a project
Section titled “Set up a project”Start in the project directory you want to protect. Scaffold a local OpenFirma layout for this demo:
firma config --yes \ --name quickstart \ --posture dev \ --mapping github \ --extra-hosts api.github.comThis creates .firma/ with a unified firma.toml (authority, sidecar, and run profiles), mapping files, policy files, and local signing material under the platform state directory. The GitHub mapping enables HTTPS interception for api.github.com; --extra-hosts adds a catch-all rule for the public profile endpoint used below.
Run an agent under enforcement
Section titled “Run an agent under enforcement”firma run launches a command inside a sandbox and routes its outbound traffic through the enforcement Sidecar. Unless you point it at an already-running stack, it autostarts a local Sidecar and a local Authority, then tears down whatever it started when the command exits.
The command after -- is whatever you want to govern. Here it’s a one-line curl to keep the demo dependency-free, but in practice it could also be an AI agent such as Claude Code or Codex — see Secure a local coding agent. Inside the sandbox, firma run sets HTTP_PROXY / HTTPS_PROXY so cooperative clients route through the Sidecar; on Linux the sandbox also confines traffic structurally, so even a process that ignores those variables can’t bypass it (how interception works).
On Linux, firma run uses the bwrap backend and structurally confines outbound traffic.
On macOS and Windows (WSL2), the default backends (vz and wsl2) provide proxy-only enforcement: traffic is mediated for cooperative HTTP clients like curl, but firma run requires an explicit opt-in before starting. Pass --allow-non-structural, or set allow_non_structural = true under [run.defaults] in .firma/firma.toml. See The sandbox boundary for details.
firma run --config .firma/firma.toml -- \ curl -kfsS https://api.github.com/users/firma-aifirma run --config .firma/firma.toml --allow-non-structural -- \ curl -kfsS https://api.github.com/users/firma-aiEvery outbound call the wrapped command makes is normalized, checked against its capability, and evaluated against the Cedar policy bundle supplied by the Authority. -k just lets this single curl skip certificate setup; for real agents firma run installs and trusts its generated CA inside the sandbox automatically, so you rarely need it. To inspect or install that CA yourself, see Enable HTTPS MITM.
Try observe-only mode first
Section titled “Try observe-only mode first”If you want to see what firma would classify and deny before writing mapping rules, use monitor mode. In this mode every request is allowed through — the enforcement pipeline still runs and classifies the call, but any DENY is overridden to ALLOW. firma monitor shows the original deny reason prefixed with monitor_mode: so you can see exactly what would have been blocked.
Enable it for a single run without editing any file:
firma run --monitor --config .firma/firma.toml -- \ curl -kfsS https://api.github.com/users/firma-aifirma run --monitor --config .firma/firma.toml --allow-non-structural -- \ curl -kfsS https://api.github.com/users/firma-aiOr set it permanently in .firma/firma.toml:
[sidecar]mode = "monitor"When active, the sidecar prints a warning at startup:
MONITOR MODE ACTIVE — enforcement is observing only; all calls are allowed through. Never use in production.In firma monitor, overridden decisions appear with the original reason:
2024-05-08T14:15:51Z ALLOW GET api.github.com/users/firma-ai class=communication.external.send agent=generic reason=monitor_mode: scope_mismatchSwitch back to enforcing mode by removing the mode line or changing it to mode = "enforce".
Watch the decisions
Section titled “Watch the decisions”After the command exits, read the audit log:
firma monitor --no-follow --format jsonEach line is one signed execution event. For the GitHub call, expect ALLOW events ("decision":1) for resources like api.github.com/ and api.github.com/users/firma-ai.
What just happened
Section titled “What just happened”For this run, three local pieces work together (autostarted on demand, or reused if already running):
- An Authority, which signs a capability token and streams policies and revocations.
- A Sidecar, which receives outbound requests and decides ALLOW or DENY.
- Your wrapped command, sandboxed and routed through the Sidecar. On Linux (
bwrap), egress is structurally confined; on macOS and WSL2, enforcement is proxy-based and depends on the agent honoringHTTP_PROXY.
Every request takes the same path:
flowchart LR
agent["Wrapped agent"] -->|"Outbound request"| sidecar["Sidecar"]
sidecar --> normalizer["Normalizer"]
normalizer --> stage1["Stage 1: Capability validation"]
stage1 --> stage2["Stage 2: Policy evaluation"]
stage2 -->|"ALLOW"| forwarded["External service"]
stage2 -->|"DENY"| denied["403 response"]
stage2 --> audit["Signed audit event"]
authority["Authority"] -. "Capability and policy stream" .-> sidecar
The important detail is that the Sidecar does not ask the Authority on every request. Once it has the public key, policy bundle, capability seed, and revocation state, the decision path is local.
Stage 1 checks whether the agent has a valid capability for the normalized action. Stage 2 evaluates the current Cedar policy. Both stages must pass before the call is forwarded.
Read the docs in order
Section titled “Read the docs in order”The rest of the docs are organized from mental model to hands-on work.
Start with these Concepts pages:
- Architecture & invariants — the three processes and the four design invariants everything else builds on.
- The enforcement pipeline — the stage chain in detail.
- Action classes — the canonical vocabulary that connects raw HTTP traffic to policy.
- Capabilities and Policies — the two layers that decide what an agent may do.
Then move to the guide that matches your next task:
- Run the Sidecar standalone if you want to write a small config yourself.
- Start and monitor the daemon with
firma sidecarandfirma monitorif you want one-command daemon control and a live tail of decisions. - Diagnose with
firma doctorif anything looks wrong after install or after a config change. - Write your first Cedar policy if you want to change what gets allowed.
- Wrap an agent with
firma runif you want a sandbox boundary, not only proxy environment variables. - Secure a local coding agent if your immediate goal is governing Claude Code, Codex, Cursor, or a similar tool.
Useful references
Section titled “Useful references”- Rust API Reference — every public item in the workspace, auto-generated from rustdoc.
- Diagnose with
firma doctor— run this first iffirma runmisbehaves after install. - Blog — release notes and design write-ups.