Skip to main content

AgentSecCore Internal Commands

--trace-context and log-sandbox are hidden integration points used by hooks and plugins. Their contracts are documented here for audit and debugging. hidden=True controls help visibility only; it does not establish availability.

Inventory

SurfaceRoleInvoking it
--trace-context JSON (top-level option)Hidden integration pointWorks
log-sandboxHidden integration pointWorks
skill-ledger rotate-keysVisible, not implementedExplicit error, exit 1

The two hidden integration points support explicit --help.

log-sandbox

Records one sandbox pre-hook decision as a Security Event. This is the audit half of Copilot Shell's sandbox protection: the sandbox-guard hook decides how to treat a dangerous shell command, then spawns log-sandbox so the decision lands in the local event store.

agent-sec-cli log-sandbox \
--decision sandbox \
--command 'rm -rf /tmp/test' \
--reasons 'recursive-delete' \
--network-policy restricted \
--cwd /home/user/project

Options

Every option is a free-form string and defaults to empty. Nothing is rejected or normalized — the value you pass is what gets recorded.

OptionRecorded meaning
--decisionThe pre-hook verdict. sandbox-guard only ever emits block or sandbox
--commandThe shell command that was evaluated
--reasonsWhy the decision was made, as produced by the caller's rule labels
--network-policyNetwork posture of the sandboxed run: restricted or enabled. Omitted on the block path, so it lands as an empty string
--cwdWorking directory the command was about to run in

Those are the values sandbox-guard produces, not values the CLI enforces. Nothing is validated against an allowed set, so an unexpected value is stored verbatim and a typo becomes a silently mislabeled audit record rather than an error. If you filter events on these fields, filter on what the hook actually emits — there is no allow record and no unrestricted policy.

Output and exit codes

The command is silent by design — no stdout, no stderr on success, because the caller spawns it detached and never reads its output.

Exit codeCondition
0The logging-only backend ran to completion. This is the normal outcome, and it is not a confirmation that the event reached storage
Non-zeroAn unexpected internal failure propagated out of the middleware

Event writing itself is best-effort: if the JSONL or the SQLite writer fails, the failure is swallowed and the exit code stays 0. Never treat exit 0 as proof that a record exists — query the event store instead, as shown in Verifying the record. Combined with the fact that sandbox-guard spawns the process detached with output discarded, the exit code has no influence on sandbox enforcement — losing an audit record never blocks or unblocks a command.

What it does not do

log-sandbox and linux-sandbox are easy to confuse. Only one of them isolates anything.

linux-sandboxagent-sec-cli log-sandbox
FormStandalone binary at /usr/local/bin/linux-sandboxHidden agent-sec-cli subcommand
RoleActually runs a command under filesystem and network isolationRecords that a decision was made
Effect on the commandWraps and executes itNone — it never executes, blocks, or rewrites anything
How sandbox-guard uses itRewrites the tool call to run through itSpawns it detached, fire-and-forget

So a --decision block record does not block anything. The blocking already happened in the hook; log-sandbox only makes it auditable.

Verifying the record

Sandbox decisions are stored with event type sandbox_prehook under category sandbox:

agent-sec-cli events --category sandbox --last-hours 1
agent-sec-cli events --event-type sandbox_prehook --output json --limit 5

In the JSON output, details.request holds the five options as passed, and the decision is at details.result.decision. Events live in /var/log/agent-sec/ when writable, otherwise ~/.agent-sec-core/; AGENT_SEC_DATA_DIR overrides both.

--trace-context

A top-level option that lets a calling plugin attach its own correlation IDs to every Security Event the invocation produces, so security records can be joined with the host Agent's traces.

agent-sec-cli --trace-context '{"trace_id":"t-1","session_id":"s-1"}' \
log-sandbox --decision block --command 'rm -rf /'

The value is a JSON object. Recognized fields are trace_id, session_id, run_id, call_id, tool_call_id, and agent_name; each also accepts its camelCase spelling (traceId, sessionId, …). Unknown fields are ignored, and values longer than 256 characters are truncated with a ...[truncated] marker.

The first five land on the Security Event as correlation columns. agent_name is the exception: it is carried as Observability metadata (component.agent_name) and is not stored on the event, so do not expect to filter events by it.

It must appear before the subcommand — it is a process-level option, parsed ahead of the command so that a subcommand's own flags keep their meaning. Malformed JSON is rejected loudly: the CLI prints Error: invalid trace context JSON to stderr and exits 1 without running the subcommand. An empty value is treated as absent.

skill-ledger rotate-keys

Visible in ordinary help and marked as not implemented. Invoking it fails without touching any key material.

Behaviour
stdoutEmpty
stderrError: rotate-keys is not implemented; no keys were changed.
Exit code1
Key storekey.enc, key.pub, and the keyring are left unchanged

rotate-keys --help exits 0 and reports that the command is not implemented.

init --force-keys forces a fresh key pair and archives the previous public key for verification of historical signatures. It does not implement the complete rotation workflow reserved by rotate-keys.