Security
A3S Code exposes security controls at session creation time and through
session lifecycle hooks. Treat direct host calls such as session.tool() and
session.bash() as privileged host operations: the application that calls them
is responsible for deciding whether to expose that power to a user.
Delegated child runs intersect their local permissions with the parent
permission checker and inherit the parent process sandbox. A child can narrow
its capabilities but cannot replace the host boundary. Child-local approval
behavior applies only to an Ask introduced by the child policy; a parent
Ask, or a tool-owned escalation after both policies allow, remains under the
parent confirmation provider. Missing providers fail closed before a HITL
request is emitted. Keep high-risk release or publish commands behind explicit
policy.
A permission prompt should explain the operation, reason, scope, and risk—not just present two buttons.
Enforced Execution Boundary
Permission policy decides whether an operation is allowed, denied, or needs
approval. It does not, by itself, confine a process. Every local A3S Code
session binds a concrete native BashSandbox before capability construction.
The same handle reaches direct tools, model-governed tools, workflows, Skills,
and delegated runs. Hosts use SessionOptions::with_sandbox_handle only to
replace this default with an equivalent boundary; non-local workspace backends
retain their explicit command-runner contract.
Core and the Code TUI use the A3S-owned a3s-sandbox Rust library through its
NativeBashSandbox adapter. It selects the native boundary for the host
platform—Seatbelt on macOS, Bubblewrap namespaces plus seccomp on Linux, and
AppContainer plus a kill-on-close Job Object on Windows—and probes that
boundary before enabling Bash. No Node.js, npm package, or global runtime
installation is required or selected.
Capability probing is necessary before readiness. macOS requires the system
/usr/bin/sandbox-exec; Linux requires /usr/bin/bwrap and permitted
unprivileged user namespaces; Windows uses PowerShell 7 from the system
Program Files directory and the native AppContainer APIs. The TUI runs a
bounded command through the actual OS boundary before enabling its deferred
handle. Failure marks that handle unavailable, so Default can request one exact
escalated host invocation and Auto denies Bash. Embedded Core sessions also
fail closed: initialization failure installs an error-only handle instead of
falling back to the local workspace runner.
The adapter fails closed and never silently retries on the host. It denies
network egress, local binding, and Unix sockets; limits writes to the workspace
and a private scratch directory; protects .git, .a3s, .agents, .codex,
.claude, .vscode, .idea, and control files; masks common credential
stores; and scrubs ambient secrets. Delegated tasks, Skills, and workflow steps
retain the same handle.
Because built-in file tools execute in-process, the TUI separately enables Core's local workspace credential policy. It covers direct and range reads, writes, edits, patches, and both manifest-backed and fallback grep. Explicit sensitive paths fail closed, broad grep omits protected candidates, and source-tree hardlink aliases are denied before mutation. Ordinary package-store hardlinks remain usable unless they alias a discovered credential inode. Read-only Git diff regenerates output only for allowed changed paths, option-like revisions cannot become Git flags, and displayed remotes omit embedded HTTP credentials and query tokens.
The release gate exercises the native backend on macOS, Linux, and Windows. It proves normal workspace writes and offline toolchain commands remain usable, while outside and symlink writes, protected metadata mutations, credential reads, network egress, local listeners, and Unix sockets remain blocked.
The terminal execution modes apply this boundary as follows:
Threat Model
The protected assets are host files outside the active workspace, repository and agent-control metadata, credential stores, host network and listener capabilities, process lifetime, and the user's authority to approve a specific operation. Model output, repository content, command output, fetched content, Skill instructions, and MCP results are untrusted inputs. A malicious dependency or child process is assumed able to close output pipes early, fork descendants, create symlinks, inspect its environment, and attempt filesystem, socket, or network escapes.
The trusted computing base is the running CLI/Core binary, the verified release support tree, the exact resolved Node executable, the selected sandbox provider and operating-system enforcement, and host code that invokes direct SDK helpers. A configured MCP server or native integration is a separately trusted extension; missing or unsafe behavior annotations cause confirmation rather than granting read-only status.
Trust does not waive process ownership. Each local stdio MCP server leads a dedicated Unix process group. Closing or dropping its transport stops pipe tasks, clears pending requests, reaps the leader, and terminates descendants. The stderr pipe is drained independently so diagnostics cannot stall protocol traffic.
This local boundary does not claim kernel-level protection against a compromised sandbox provider, Node runtime, CLI binary, or operating system. It also does not turn the privileged host-direct SDK into end-user authorization. Use a stronger workload provider for hostile multi-tenant code, kernel attack resistance, or OCI-level isolation.
Invocation Ingress
Every session-owned path enters one scoped invocation kernel:
Low-level ToolRegistry and standalone ProgramExecutor APIs are deliberately
ungoverned building blocks for hosts that own the registry. AgentSession and
the TUI do not use those APIs as a fallback.
Complete TUI Decision Matrix
The cells below are the terminal outcomes for model and ordinary governed nested invocations. “Deny” means no confirmation event is created. “Confirm once” means one exact invocation ID is pending; cancelling or expiring it cannot settle another prompt.
Origin modifies that matrix only as follows:
Decision precedence is fail-closed: active-Skill restrictions and hard
guardrails first, then hook blocks, origin authority, mode/permission policy,
tool-owned escalation, confirmation availability, and finally execution.
Terminal policies always use TimeoutAction::Reject; Core's generic
AutoApprove option is not accepted by the TUI.
Treat the native sandbox as a local enforcement provider, not as the stack-wide
execution contract. A3S Code owns agent policy and its BashSandbox interface.
A3S Runtime owns durable, provider-neutral Task and Service lifecycle and
placement. A3S Box owns OCI and stronger isolation. A3S Observer and A3S Sentry
can add execution evidence and adaptive runtime enforcement as defense in
depth; they do not replace the deterministic per-process sandbox boundary.
Secure Downloads
download is a bounded workspace mutation, not an unrestricted network or
filesystem primitive. It is registered only when the session has a writable
local workspace. Model-selected calls pass through the same permission policy,
HITL confirmation, hooks, timeout, cancellation, and workspace checks as other
mutations. Direct session.tool('download', ...) calls remain privileged host
operations and require authorization in the embedding application.
Its network boundary accepts only HTTP(S), rejects user information and non-public targets, and revalidates every bounded redirect hop. Direct connections reject DNS answers containing any private or otherwise reserved address and pin the validated public addresses for that hop. Cross-origin redirects drop credentials and resource validators. Explicit proxy mode leaves hostname resolution to the configured proxy but retains literal-host and redirect checks.
Signed query parameters are preserved because object stores and release systems
need them to authorize the request. They are removed from diagnostics and
source_anchors, so successful and failed tool results do not expose those
secrets in metadata.
The destination must remain below the local workspace and may not cross
symlinks. Content is streamed to an adjacent temporary file under byte and time
limits. Strict Range validation, optional expected_sha256, sync-before-promote,
and atomic replacement keep incomplete or unverified data away from the final
path. Cancellation and failure remove the temporary file; overwrite defaults
to false.
See Tools for the complete parameter contract.
Permission Policy
Avoid permissive defaults for release or production sessions. Make dangerous commands explicit and auditable.
Hooks
Hooks are registered on a session with an event type, matcher, optional config, and handler:
Verification
Verification reports and summaries are available from the session and selected result fields. Release workflows should require tests, package checks, CI checks, and provider evidence.