Skip to content

Architecture

┌──────────────────────────────────────────────────────────┐
│ AGENT SANDBOX (optional) │
│ Linux user/network/mount/PID/UTS/IPC/cgroup namespaces │
│ - Empty network stack │
│ - HTTPS proxy for LLM APIs (allowed hosts only) │
│ - Gate UDS for protected actions │
│ - Workspace mount (single RW dir) │
│ latchgate-sandbox crate · Linux ≥ 5.8 only │
└────────────────────────┬─────────────────────────────────┘
Agent Runtime / IDE / Orchestrator / MCP Host
│ northbound call
┌──────────────────────────────────────────────────────────┐
│ NORTHBOUND INTERFACES │
│ - MCP adapter (optional) │
│ - REST Action + Approval API │
│ - thin SDKs / operator CLI / TUI │
└─────────────────────────┬────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ LATCHGATE KERNEL │
│ │
│ Auth + Registry │
│ 1. Drain guard │
│ 2. Lease validation + DPoP sender binding + replay │
│ 3. Registry lookup (ActionSpec by action_id) │
│ 4. Trust / digest verification │
│ 5. Input schema validation │
│ 6. Canonicalization + request_hash (JCS RFC 8785) │
│ │
│ Domain + Policy + Approval │
│ 7. Domain pre-check (optimization — early reject) │
│ 8. Budget snapshot + OPA/Rego evaluation │
│ 9. Pending approval hold (if policy requires) │
│ │
│ Pre-dispatch │
│ 10. Atomic budget debit (Redis Lua) │
│ 11. ExecutionGrant construction + Ed25519 signing │
│ 12. Secret resolution + template expansion │
│ │
│ Shared execution tail (execute_authorized_plan) │
│ 13. Grant validity + signature verification │
│ 14. ExecutionIntent write (pre-dispatch evidence) │
│ 15. WASM provider dispatch (fresh instance per call) │
│ 16. Response schema validation │
│ 17. Effect verification │
│ 18. ExecutionReceipt hashing + Ed25519 signing │
│ 19. Evidence finalization (receipt + audit, single txn) │
└────────┬───────────────────────────────────────┬─────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────────────┐
│ WASM SANDBOX │ imports │ HOST I/O LAYER │
│ │────────>│ │
│ Provider .wasm │ │ Sink validation │
│ module executes │<────────│ Credential injection │
│ in wasmtime │ returns │ SSRF protection │
│ │ │ DNS pinning │
│ - no filesystem │ │ Timeout enforcement │
│ - no network │ │ │
│ - no syscalls │ │ Clients: │
│ - no secrets │ │ - HTTP (reqwest) │
│ - fuel metered │ │ - SMTP (lettre) │
│ - memory capped │ │ - SQL (sqlx) │
│ - epoch deadline │ │ - Queue (lapin) │
│ │ │ - Storage (object_store)│
└─────────────────────┘ └───────────┬──────────────┘
External systems / side effects

The execution tail — grant re-validation through evidence finalization — is shared: both the auto-allow path and the human-approved path converge into a single function (execute_authorized_plan). There is exactly one code path that dispatches a WASM provider. A bug that bypasses a check in one path cannot selectively affect either origin.

The agent sandbox (top of diagram) is an optional containment layer that wraps the agent process itself. When active, the agent runtime runs inside Linux namespaces with no host filesystem access, no host network, and no inherited credentials. The only paths out are the gate UDS and the HTTPS proxy. See Agent Sandbox.

CrateResponsibility
latchgate-coreShared types: ActionSpec, ExecutionGrant, ExecutionReceipt, canonical hashing, signing, approval plan, filesystem path evaluation, security constants
latchgate-cryptoCryptographic primitives: Ed25519 signing, SHA-256, JWK thumbprints, constant-time comparison
latchgate-configConfiguration loading, TOML parsing, env var overrides, production validation, path resolution
latchgate-authLease issuance, DPoP verification, identity providers (peercred / none), replay protection, operator auth
latchgate-registryAction registry, manifest loading, digest verification, schema validators
latchgate-policyOPA client, embedded Rego evaluator (regorus), policy input/output types
latchgate-stateApproval stores (in-memory, Redis, SQLite), budget tracking (Redis Lua), session state
latchgate-kernelExecution pipeline: orchestrates all steps from request to receipt; owns execute_authorized_plan
latchgate-providersWASM runtime (wasmtime), host I/O layer, sink validation, SSRF protection, secrets manager
latchgate-ledgerSQLite evidence ledger, receipt signing, integrity chain, JSONL export, intent tracking, learned domains, learned paths
latchgate-apiHTTP server (axum), client + admin routers, health/readiness probes, rate limiting
latchgate-webhooksOutbound webhook notifications: HMAC signing, SSRF protection, outbox delivery with retry
latchgate-mcpMCP adapter binary (latchgate-mcp) for exposing actions as MCP tools to IDE agents
latchgate-sandboxLinux namespace sandbox: user/network/mount/PID isolation, HTTPS CONNECT proxy, workspace mounts
latchgate-cliOperator CLI and TUI: approvals, audit, status, revoke, config, ledger, doctor, sandbox, presets, paths, domains, completions, uninstall
latchgate-clientRust client library for programmatic gate access
latchgate-embedCompile-time embedded assets and egress sync: manifests, policies, presets, providers
latchgate-binBinary entry point; dispatches to CLI commands
  • core has no provider or API dependencies
  • kernel depends on traits, not concrete transports
  • providers host I/O never calls policy directly
  • api does not contain business decisions
  • Provider .wasm modules never import kernel internals — only latchgate:io/*
  • Secrets never cross the WASM boundary
  • There is exactly one function that dispatches WASM providers (execute_authorized_plan)
  • sandbox has no dependency on the kernel — it is a launcher, not a pipeline participant
  • embed is a compile-time-only crate for embedded assets (manifests, policies, presets, providers)

These define the architecture. If any invariant is violated, the system is broken.

SI-1 Complete mediation. Every protected action passes through the kernel. No protected side effect bypasses the kernel.

SI-2 Fail closed. If identity, policy, registry, secret release, provider dispatch, or verification fails, the action is denied. No silent fallback to permissive behavior. 503 responses still mean DENY.

SI-3 Sender-bound identity. A stolen token alone is not enough. Every execution path is bound to a caller-controlled key via DPoP (RFC 9449).

SI-4 Body-bound integrity. The exact request body is canonically hashed (JCS RFC 8785) and bound into the authorization path.

SI-5 Immutable approval plan. Human approval binds the exact execution plan via plan_hash and approval_hash. The approval path executes the stored plan, never re-derives from the current manifest or registry state. Approval consumption is atomic and one-shot.

SI-6 Shared execution tail. The auto-allow path and the approved path converge into a single kernel function before any side effect. They cannot diverge at dispatch, verification, or evidence.

SI-7 Provider isolation. Providers execute in WASM sandbox with linear memory isolation. Each execution creates a fresh instance. Fuel, memory, I/O budget, and wall-clock deadline are enforced per execution.

SI-8 Host-mediated I/O. Providers communicate with external systems only through host-implemented import functions. The kernel validates sinks, injects credentials, and enforces egress policy at the host layer.

SI-9 Default-deny egress. Providers have no direct network access. All I/O goes through host imports which enforce allowlists from the grant.

SI-10 Least-privilege secret release. Secrets are injected by the host I/O layer at execution time. Secrets never enter the WASM sandbox. Only secrets declared in the action manifest AND approved by the policy decision are injected.

SI-11 Capability-gated imports. Only I/O imports declared in the action manifest are linked to the WASM instance. Runtime check (check_import_allowed) is a second layer of defense beyond linker-level gating.

SI-12 Verified outcomes. For high-risk effects, success is not declared from request acceptance alone. Verification or explicit unverifiable classification is required. Verified is never attached without an actual verification step.

SI-13 Pre-dispatch evidence. Every dispatch writes an ExecutionIntent to durable storage before the WASM provider runs. If the process crashes post-dispatch, operators can detect intents without matching receipts.

SI-14 Tamper-evident evidence. Receipts and events are append-only and chained (prev_hash) for integrity. Receipt signing key rotation preserves verifiability via a historical verifying key store.

SI-15 Grant integrity. Every grant is Ed25519-signed immediately after construction and verified before dispatch. Separate signing key from receipt signing (defense-in-depth). Any field mutation between construction and dispatch is detectable.

SI-16 Production fail-fast. The gate refuses to start in non-dev mode with insecure defaults: IdentityProvider::None, allow_unmapped = true, shared operator keys, ephemeral signing keys, response_schema_enforcement = warn, or missing JWKS path.

ComponentPurposeModeFailure mode
SQLiteEvidence ledger, learned domains, learned pathsAlwaysFail closed for protected actions; success gated on receipt write
SQLite (state)Budgets, approvals (embedded mode)Embedded (default)Fail closed (deny)
In-memory DashMapReplay cache (embedded mode, bounded 100k entries)Embedded (default)Fail closed (deny)
RedisReplay cache, budget atomics, approval state, revocation epoch--infra / customFail closed (deny)
Embedded regorusRego policy evaluation (in-process)Embedded (default)Fail closed (deny)
OPAPolicy evaluation (external HTTP)--infra / customFail closed (deny, with 503 to signal transient)
Squid (with proxy_allowlist actions)Defense-in-depth egress proxyOptionalFail closed (deny)
SOPS binarySecret decryptionWhen configuredRequired when sops_secrets_file is set; absence fails doctor

In embedded mode (the default for latchgate up), no external services are required. Redis and OPA are used when configured via --infra, --with-redis, --with-opa, or explicit TOML settings.

Redis should have persistence enabled when used in production (appendonly yes). Without it, replay cache and budget counters reset on restart — the replay window is short-lived (180s default) so this is low-risk, but budget accounting will be inaccurate.

For the full threat model and trust boundaries, see Security Model. For the execution pipeline and key artifacts, see Core Concepts.