Security Model
Applies to SDK 0.19+ · Last updated: 2026-07-06
AgentNode is local-first by design. All tools run on your machine. The registry never sees what you do with them.
AgentNode runs third-party tool code on your machine. This page explains exactly what is enforced, what is declared but not enforced, and what you can do to stay safe.
Enforcement is trust-tiered
What gets enforced depends on the package's trust level:
Trusted / curated packages
Run on the host with subprocess isolation, environment filtering, and timeouts under the default host-trust policy. Their network/filesystem declarations are policy-checked, not OS-enforced — that's the trade these tiers earn through review. You stay in control: the sandbox.host_trust_policy setting can sandbox trusted (curated_only) or everything (none), with a reinstall to build the sealed volume.
Verified / unverified community packages
Run inside a hardened container sandbox — or not at all. If no container runtime or pinned sandbox image is available, execution is blocked (fail-closed). There is no silent fallback to host execution.
Community agents
Community-agent sandboxing is gated behind an explicit opt-in flag (default OFF). When enabled, community agents run sandbox-or-fail-closed with a host-side LLM broker — provider API keys never enter the container. When disabled, community agents are refused entirely. Trusted and curated agents run on the host like other trusted/curated code, so not every agent is sandboxed.
What is enforced
Community-tier code (toolpack builds, toolpack runs, MCP servers, opt-in community agents) executes in a hardened container: read-only filesystem, non-root user, all capabilities dropped, no host mounts, no secrets. Networking is off by default across the board (unknown = deny); a community MCP must be pinned and preinstalled and gets network access only through a sealed egress allowlist it declares, while non-preinstalled MCP servers are refused. If the sandbox is unavailable, execution is denied — never downgraded to the host.
Community toolpack and agent-sandbox containers get a network only when the package declares a recognized network level; unknown, missing, or 'none' values mean the container runs with networking fully disabled (--network none, unknown = deny). Community MCP servers follow the same default-deny rule: they run with no network unless they declare a sealed egress allowlist (mcp_allowed_domains), and non-preinstalled MCP servers are refused.
The sandbox image is referenced by immutable digest, never by tag, and is never pulled automatically. You fetch it explicitly with 'agentnode sandbox pull'; 'agentnode sandbox doctor' explains the current state.
Packages are signed with publisher Ed25519 keys. An invalid signature blocks install — no override, no force flag. Missing signatures warn (publisher adoption is gradual) but are never silent.
Every lockfile entry carries a SHA-256 integrity hash over its security-critical fields ('agentnode lock seal' / 'lock verify'). Tampered entries are warned on by default and denied before execution in strict mode.
Sandboxed agents request completions through a host-side broker. Provider API keys never enter the sandbox container, audit records, manifests, or lockfiles.
'agentnode auth set' stores keys in the OS keychain (Windows Credential Manager, macOS Keychain, Linux Secret Service). Where no keychain is available (e.g. headless Linux), storage honestly falls back to a plaintext file with 0600 permissions — and tells you so.
Every run_tool() call passes through check_run() which evaluates trust level, permissions, and environment context. Returns allow, deny, or prompt. Fail-closed when config is missing.
Host subprocess mode (trusted/curated tiers) strips API keys (AWS_*, OPENAI_*, STRIPE_*, etc.) from the child process environment. Only PATH, HOME, PYTHON*, and TEMP are passed through.
Tools running in subprocess mode are killed after a configurable timeout (default 30 seconds).
Your local config sets a minimum trust level (default: verified). Packages below this threshold are denied before execution.
In CI environments or when AGENTNODE_NON_INTERACTIVE is set, any 'prompt' decision escalates to 'deny'. No silent approvals in automation.
All policy decisions are logged to ~/.agentnode/audit.jsonl. Append-only, rotated, local-only. Never contains secrets or tool inputs/outputs. Sandboxed agent runs write one aggregated, sanitized record per run.
CredentialHandle validates the target domain against allowed_domains before attaching credentials, and refuses non-HTTPS targets. Secrets are never exposed via properties.
Agent packages can only invoke tools explicitly listed in their manifest. Attempts to call unlisted tools are blocked — on the host and across the sandbox RPC boundary.
Honest limits — trusted/curated host execution
These limits apply to packages that run on the host because they earned trusted/curated status. Community-tier code does not have these gaps — it runs in the container sandbox or not at all. And you can remove the gaps yourself: set sandbox.host_trust_policy to curated_only or none to sandbox the trusted/curated tiers too (fail-closed; may require a reinstall).
For trusted/curated host execution, 'network: none' declarations are policy-checked but not OS-enforced — a trusted tool could still make HTTP requests. For community toolpacks, MCP servers, and agent sandboxes this IS enforced: the container runs with networking disabled unless a sealed egress allowlist is declared.
Same scope: trusted/curated host tools are policy-checked, not OS-restricted. Community packages run on a read-only container filesystem with no host mounts.
mode='direct' runs tool code in your process with full environment access. This is opt-in only — mode='auto' (the default) always uses subprocess isolation.
The input guard inspects tool arguments. Path-traversal and URL-anomaly findings require interactive confirmation — and are denied outright in non-interactive/CI contexts. Lower-severity findings (oversized inputs) remain non-blocking warnings.
Privacy
All execution is local. Tool inputs, outputs, and logs never leave your machine.
What the registry sees: Install events, search queries, and periodic trust-level refresh requests.
Audit logs: Stored at ~/.agentnode/audit.jsonl. Never transmitted. Contains only policy decisions (action, source, reason, trust level).
Recommendations
- Set up the sandbox so community packages can run isolated:
agentnode sandbox pullonce,agentnode sandbox doctorwhenever something is blocked — it explains exactly what is missing. - Store provider keys with
agentnode auth set <provider>so they live in the OS keychain instead of environment files. - Use
agentnode inspect <slug>to review permissions, enforcement status, and policy preview before running a package. - Run
agentnode lock verifyin CI to detect lockfile tampering or drift before it reaches execution. - Keep the default
mode="auto"which always uses subprocess isolation with env filtering. - To sandbox trusted/curated code you don't want on your host, set
agentnode config set sandbox.host_trust_policy curated_only(ornone) — it runs those tiers in the same hardened container, fail-closed, andagentnode sandbox doctorshows what to reinstall. - Review
agentnode auditperiodically to see policy decisions for installed packages. - Set a higher minimum trust level in your config if you want stricter package requirements.
Questions or concerns? See our FAQ or reach out on GitHub.