Skip to content

Security Model

Content is classified by trust source:

SourceTrust Level
User instructionsTrusted
Project policyTrusted
AgentZero core codeTrusted
Skill instructionsUntrusted
Document contentUntrusted
Tool outputUntrusted
Network contentUntrusted

Untrusted content never becomes trusted instruction.

LevelRemote ModelsHandling
publicAllowedNo restrictions
internalPolicy checkRequires explicit policy
privateRedact or denyMust redact before remote
piiRedactAlways redacted for remote
secretDeniedNever sent remotely
credentialDeniedNever sent remotely
unknownDeniedFails closed as private

When uncertain, AgentZero denies:

  • Unknown data classification → treat as private
  • Unknown permission → deny
  • Unknown runtime safety → deny
  • Failed redaction → deny remote call
  • Failed policy load → deny privileged actions
  • Failed audit init → deny session start
  • AES-256-GCM for all encryption at rest
  • Argon2id key derivation (memory-hard)
  • Random salt + nonce per encryption
  • Per-line encryption for audit logs (appendable)
  • Per-secret files in vault

Skills execute at different isolation tiers per ADR 0006:

TierUse CaseIsolationStatus
NoneInstruction-only skillsNo code executed✓ shipped
Host ReadonlySafe read-only toolsFilesystem access, path-restricted✓ shipped
Host SupervisedTools with write/shellPolicy-gated ShellCommand capability, full audit trail✓ shipped
WASM SandboxPortable toolsNo filesystem, no network, fuel-limited✓ shipped
MVM MicroVMHigh-risk executionFull VM isolationplanned
DenyBlockedNothing executes✓ shipped

WASM skills run inside a wasmtime sandbox with:

  • No ambient filesystem — all WASI access denied
  • Network access controlledSandboxNetworkPolicy with three tiers: Deny (default), AllowEgress (unrestricted), AllowEgressFiltered (host allowlist)
  • Memory cap — 64 MB default
  • Time limit — fuel-based, 30 seconds default
  • Policy-gated — requires wasm_execution = "allow" in policy

The .agentzero/ directory is blocked from tool access. Tools cannot read, write, or list files inside this directory. This prevents policy files, vault secrets, and audit logs from being disclosed to the model or exfiltrated through tool calls.

Paths are canonicalized before policy evaluation. This prevents time-of-check-to-time-of-use attacks where a symlink could point to a different file between the policy check and the actual file operation.

Tool arguments are redacted in ToolCallRecord and the approval flow. Secrets are replaced with [REDACTED_SECRET] and PII with [REDACTED_PII]. Redaction placeholders include a random hex suffix (e.g., [SECRET_a1b2]) to prevent placeholder collision.

Tool output is scanned for secrets before audit event logging. The scanning functions (scan_for_secrets(), redact_json_value()) are extracted to agentzero-core as shared utilities.

WASM modules with undeclared imports are rejected before execution. Only imports declared in the WIT interface (az:host) are linked. This prevents modules from requesting capabilities they were not designed for.

The approval prompt supports three responses:

ResponseScope
yApprove this one tool call
yes-all / aApprove all calls to this tool for the current session
nDeny

Session-scoped approvals are cached per tool name and do not persist across sessions.

Messaging gateways (Slack, Telegram) route external messages through the agent loop with no human in the loop. To prevent abuse:

  • Dangerous tools deniedGatewayApprovalHandler blocks write, edit, shell, and generate_tool in gateway mode. Only read-only tools (read, list, search) are available.
  • PII redaction on outbound — all responses are scanned and redacted before sending to the messaging platform
  • Policy still applies — the deny-by-default policy engine runs before every tool call, even in gateway mode

WASM plugins can make outbound HTTP requests via the az::http_request host import. Three barriers protect against data exfiltration:

  1. Capability check — policy engine must allow NetworkRequest
  2. URL allowlistSandboxNetworkPolicy must allow the specific URL (plugins declare allowed hosts in PLUGIN.toml)
  3. PII scan — request body is scanned for secrets; blocked if any are found

Plugins declare their network requirements in PLUGIN.toml:

[plugin.network]
policy = "allow_egress_filtered"
allowed_hosts = ["slack.com", "api.telegram.org"]

Plugins without a [plugin.network] section default to Deny — no outbound requests.

  • Raw secrets reaching model context
  • PII in remote model calls without redaction
  • Prompt injection from tool output
  • Ambient host access from skills/tools
  • WASM modules escaping sandbox boundaries
  • WASM modules with undeclared imports executing
  • Secret leakage in audit logs (tool output scanned before logging)
  • Unaudited tool or skill execution
  • Tool access to .agentzero/ configuration directory
  • TOCTOU path manipulation attacks
  • Arbitrary code execution via messaging gateways (dangerous tools denied when no human in the loop)
  • WASM plugin data exfiltration to unauthorized hosts (URL allowlist enforcement)
  • Secrets in outbound HTTP request bodies from WASM plugins (PII scan)