A single Go binary that is the front door to the traust security workflow: it sets up the environment, drives harness skills headlessly through the agent of your choice, validates the output, and shows you the results.
traust-cli init # uv + traust checkout + config home, one command
traust-cli skills # browse the catalog (TUI)
traust-cli run threat-model /src/myapp # first audit, through YOUR agent harness
traust-cli report myapp-threat-model.md # validate, lint, browseThe CLI is deliberately a thin, honest layer. Every deterministic operation
(reporting validate, registry models resolve, toolchain setup, …) is
delegated to the traust engine CLI from the managed venv — the CLI adds the
user experience, not a second engine.
Running traust today means cloning the harness repo, uv sync, creating
TRAUST_CONFIG_HOME from templates, optionally installing a scanner
toolchain, then driving skills by hand from inside an agent. traust-cli wraps
all of that, and adds the pieces the harness documents as gaps:
- Model-floor pre-flight — a run's model defaults to the registry's floor
resolution for the skill's role (
traust registry models resolve); explicit overrides are warned about and journaled (traust/docs/model-routing.md documents the missing runtime enforcement). - Budget bands — the shipped
budget-policy.yamlper-run output-token caps and warn/degrade/refuse bands, enforced live (warn 1.5×, degrade 2×, refuse 3× by default;--budget-override "<reason>"records an exception). - S9 isolation, centralized — agents always run from the harness root, never inside the audited checkout, and never load target-repo agent configuration. Enforcing this in one launcher is stronger than hoping every script does it right.
- Spend declaration — every run with reported usage appends a
registry models spendrow automatically. - Run journals — spec, raw stream, normalized events and result under
~/.traust/cli/runs/<id>/.
Priority order: claude code → codex → pi → opencode → crush → goose. Antigravity (agy) is deferred: it has no headless execution path.
| Harness | Headless invocation | Live stream | Usage | Permission posture |
|---|---|---|---|---|
| claude | claude -p --output-format stream-json |
✓ | ✓ | acceptEdits + the skill's allowed-tools (fail-closed); --unsafe-full-permission for the rest |
| codex | codex exec - --json --output-last-message |
✓ | ✓ | workspace-write sandbox, approvals never |
| pi | pi --mode json |
✓ | ✓ | tool grants mapped onto pi's builtin tools |
| opencode | opencode run --format json --auto |
partial | — | --auto |
| crush | crush server (client mode): workspace + SSE events, clean cancel; falls back to crush run |
✓ live | ✓ | workspace permission level; unanswered permission/question requests fail closed (exit 2) |
| goose | experimental (TRAUST_CLI_GOOSE_ARGS overrides the template) |
— | — | goose's own configuration |
Every adapter prints its honest caveats before a run. --unsafe-full-permission
is opt-in and journaled.
go install github.com/traust-security/traust-cli@latestor grab a static binary from the releases (linux/macOS/windows, amd64/arm64, checksummed). The only other thing you need is an agent harness you are logged into.
| Command | What it does |
|---|---|
init |
Bootstrap the managed workspace: pinned uv (checksum-verified, never curl | sh), traust checkout at a stable tag, uv sync, TRAUST_CONFIG_HOME from templates via install_traust, and the secure-code-audit scanner toolchain (covers every flow stage; --toolchain none skips, already-installed profiles are skipped). Idempotent; nothing is written to your shell profile (use eval "$(traust-cli env)" if you want it). |
doctor |
CLI checks + install_traust --doctor; --json for CI. |
update |
Move the pin to a newer tag and re-sync. |
skills |
Catalog parsed from the same SKILL.md frontmatter the harness reads; TUI picker on a TTY, table otherwise; --json. |
run [flags] <skill> [args…] |
Compose the SKILL.md into a prompt, pre-flight the model floor, and launch the run in the background (a detached worker process that survives the terminal), then attach. -d/--detach starts without attaching; --json/--no-monitor keep synchronous CI semantics. The journal records everything; artifacts are validated and spend declared. |
attach <run> |
Live monitor over a background run: full transcript replay + live tail with thinking, tool calls and tool results. Ctrl-C detaches without cancelling (the run keeps going); x twice cancels. Works on finished runs too (full replay + result). Non-TTY degrades to a plain tail. |
runs (ls/ps) |
List runs — running first, then newest — with state (running/done/failed/needs-input/budget-stop/aborted/orphaned), age and tokens; --json. |
stop <run> |
Graceful cancel: SIGINT (context-driven teardown: crush cancel endpoint, server shutdown) → SIGTERM → SIGKILL. |
peek <run-or-flow> |
One-shot snapshot: state, usage and the last dozen journal entries — for runs and flows alike (a flow peek shows the stage chain plus the current stage's snapshot). |
logs <run> |
The run's rendered journal transcript. |
result <run> |
The stored result: summary, artifacts, usage, error — exits with the run's own code. |
report <file-or-dir> |
Validate (reporting validate), lint threat models (reporting lint), render (reporting render), and browse findings (severity-colored TUI). |
ledger whoami|findings|layers|verify |
Read-only views over a ledger service (--url or TRAUST_LEDGER_URL; the token comes from the env var named by --token-env). No submissions, no countersign. |
traust-cli flow audit-triage <repo> # audit, then triage (--auto); output = triaged findings
traust-cli flow remediate-verify <triage.json> <repo> # patch the findings, then verify the patched code
traust-cli flow full <repo> # the whole loop end to end
traust-cli flow status [id] # list flows / show stage detailEvery stage is an ordinary background run (own journal, result, attach
session); each stage's inputs are derived from the previous stage's
artifacts — the audit report feeds triage, the triaged findings feed patch,
and verify runs against a fresh checkout with the generated patches
applied. Ctrl-C detaches without cancelling; flow status shows progress
and attach <id> follows the current stage.
| Code | Meaning |
|---|---|
| 0 | run completed |
| 1 | error (harness failure, failed artifact validation, aborted) |
| 2 | the skill needs interactive input a headless run cannot provide |
| 3 | the budget refuse band was hit |
- The audit target is always data, never configuration (harness rule S9):
the agent's cwd is the harness root; target-repo
.claude//AGENTS.md/ hooks are never loaded as agent config. - Credentials: the CLI never stores secrets. Harness logins are the harness's own; the ledger token is read from an environment variable you name.
- uv is installed from a pinned, checksum-verified GitHub release — no piped-to-shell installers.
make check # build + vet + test
make lint # staticcheck
go test ./... # integration tests run against fake harness binaries in
# testdata/fake-harnesses/ — no API keys neededThe catalog check command compares the embedded standalone profile
(internal/catalog/data/standalone.yaml, seeded from traust's
docs/standalone-usage.md and model-classes.md) against a traust checkout;
CI runs it on every push to catch drift.