Skip to main content
Version: MVP

Execution environment security

3 min readSecurityUpdated 2026-05-22

What you'll find here

How Craik records provider and sandbox decisions for persistent agents: capability grants, redacted environment receipts, denial receipts, and the state that may cross the execution boundary.

Receipts do not grant authority.

Environment receipts are evidence. The caller must already have made the provider, sandbox, or capability decision before recording the receipt.

Boundary model

Persistent agents execute through the same provider-backed run path as bounded task runs. The agent session contributes identity and continuity links; it does not add a separate side-effect authority surface.

Provider boundary

The prompt loop records provider id, policy envelope id, run id, handoff id, and provider result count.

Sandbox boundary

The prompt loop records the sandbox backend id, command reference, capability, and grant outcome.

Session boundary

Receipts carry the agent session id so operator views can correlate decisions without copying secrets into session state.

Explicit grants

Side effects require explicit capability grants. For the deterministic persistent-agent fixture path, Craik grants shell.execute only when the operator uses the default fixture approval path. When the grant is absent, prompt execution records a denial environment receipt for shell.execute and keeps the run blocked.

This shape keeps tests, demos, and direct runtime callers honest: a provider response alone is not enough to authorize a local action.

Receipt linkage

Each persistent prompt can record two environment receipts:

ReceiptCapabilityStatus
Provider actionmodel.chatpassed when provider execution returned a result.
Sandbox actionshell.executepassed only when the fixture action grant is present.
Sandbox denialshell.executedenied when the fixture action grant is absent.

Receipt metadata includes the session id, task id, policy envelope id, provider id, sandbox backend id, redacted command reference, run id, and handoff id. The session state stores the resulting receipt ids so inspection surfaces can move from a persistent agent to the exact provider and sandbox records for the prompt.

Redaction rules

Environment receipts store references, not raw payloads. Redaction removes or masks command payloads, raw commands, environment maps, stdin, stdout, stderr, target payloads, credentials, tokens, passwords, API keys, and secret-like metadata keys.

Command targets use a redacted command reference such as sandbox_action:fixture-action. Provider and sandbox identifiers remain as stable routing references; credential values never appear in receipt metadata.

TUI shell invocations

The terminal UI also supports explicit operator-triggered local commands with the ! prefix. These commands do not go through a model. Craik parses the command with shlex, executes it through the local-process backend with shell=False, records stdout and stderr previews, and writes full redacted side logs under ~/.craik/state/shell-output/.

Each invocation records a shell_invocation receipt with the working directory, exit code, output hashes, redaction labels, duration, and operator subject when an operator session exists. The receipt is HMAC signed before it is stored. On POSIX systems, side logs are written with owner-only permissions.

Treat ! as an audited operator shell convenience, not as delegated model authority. If a model suggests a local command, the operator still has to copy or type that command with the ! prefix.

Operator checks

Use these checks when reviewing a persistent-agent run:

  1. Confirm the agent session receipt_ids include the environment receipt ids for the prompt.
  2. Confirm provider receipts reference the expected provider and policy envelope.
  3. Confirm sandbox receipts show passed only when the capability grant was present.
  4. Treat denial receipts as expected protection, not as partial execution.

What's next