The CLI is published on npm (npm i -g @aex-lang/cli). APIs are experimental and may change before v1.0. Roadmap →
Skip to content

Security Model ​

AEX contracts act as an enforceable layer between intent and tool execution. The runtime and adapters uphold the following guarantees:

  • Contracts are parsed and validated before execution.
  • Tool calls must appear in use, be absent from deny, and pass the runtime policy intersection.
  • When both a policy and task contract are active, effective permissions use the most restrictive combination: allow is intersected, deny is unioned, confirm is unioned, budget takes the minimum.
  • Confirmation gates pause execution until an approval handler allows the call.
  • Budgets stop execution when the permitted number of do/make steps is exhausted.
  • All tool calls, confirmations, checks, and return values are logged.
  • The MCP proxy (aex proxy) enforces the same rules on every tool call between your client and upstream servers.

Runtime Protections ​

Command Injection Prevention ​

Built-in tools like tests.run use execFile rather than shell-based exec. Commands are split into an executable and argument array, preventing injection via shell metacharacters like ;, &&, |, or backticks. The runtime rejects any command argument containing shell chaining operators.

Path Traversal Prevention ​

The built-in file.read and file.write tools enforce a working-directory boundary. Any path that resolves outside process.cwd() (e.g., ../../../etc/passwd or an absolute path like /etc/shadow) is rejected before the filesystem is touched.

Policy Path Qualifiers ​

Runtime policy entries support path-scoped rules like file.read:/workspace/**. The runtime parses both the tool name and the path pattern from policy entries, preserving the path qualifier for future enforcement instead of discarding it.

Wildcard Matching ​

Tool permission wildcards enforce a dot boundary: network.* matches network.fetch and network.post but does not match networkx.anything. A shared matching implementation is used consistently across the parser, validator, runtime, and MCP gateway.

Timing-Safe Signature Verification ​

The aex verify command uses crypto.timingSafeEqual to compare HMAC signatures, preventing timing side-channel attacks that could progressively leak the expected signature.

Threat Model ​

AEX is designed to mitigate:

  • prompt-injection attempts that ask an agent to read secrets or call undeclared tools
  • exfiltration via overbroad tool permissions (blocked by deny rules enforced before any tool executes)
  • silent edits that skip tests or checks
  • tool calls that should require human approval (e.g., file.write, ticket.create)
  • path traversal attacks through user-controlled file paths
  • command injection through crafted test commands
  • permission escalation when a task contract requests broader access than the ambient policy allows (merge semantics enforce the intersection)
  • generated contracts that bypass policy (aex draft validates against policy; aex review shows effective permissions before execution)

What AEX does not guarantee:

  • the correctness of a model-generated artifact (make steps still depend on the underlying model)
  • protection against compromised tool implementations
  • sandboxing of arbitrary shell commands (use specialized tools instead of shell.exec)

Signed Contracts & Provenance ​

Use the CLI to generate and verify cryptographic metadata:

bash
aex sign tasks/fix-test.aex --id release-bot --key-file ./keys/aex.hmac
aex verify tasks/fix-test.aex --signature tasks/fix-test.aex.signature.json --key-file ./keys/aex.hmac

Signature files capture the source path, SHA-256 hash, signer, timestamp, and HMAC digest. Store the signatures in your repository alongside contracts so platform teams can audit every change before allowing execution.

Threat-Model Demo ​

The Threat Monitor example demonstrates how to wire policies, confirmations, git tooling, and diff-aware checks together before mutating a repository. Pair it with signed contracts to guarantee the workflow hasn't changed since approval.

Compatibility Tests ​

The reference implementation includes tests that ensure the CLI, runtime, and LangGraph compiler agree on step ordering and semantics. When you run npm test, vitest executes:

  • Command injection prevention (shell metacharacters blocked).
  • Path traversal prevention (out-of-cwd paths rejected).
  • Runtime checks for unified diff validation and file-permission enforcement.
  • Git tool integrations (git.diff, git.apply) under a temporary repository.
  • Cross-runtime verification that taskToLangGraph produces the same step count as the validated task.
  • Timing-safe signature verification and tamper detection.

MCP Proxy Security ​

The aex proxy command enforces policy on MCP tool calls at the transport layer — between your client (Claude Code, Codex CLI) and upstream MCP servers. This provides defense-in-depth because:

  • Deny rules are enforced before the upstream server sees the request. A prompt injection that convinces the model to call a denied tool is blocked at the proxy, not at the model.
  • Budget enforcement stops execution after the configured number of calls, preventing runaway agents.
  • Audit logging records every decision (allowed, denied, confirmed) as structured JSON to stderr.
bash
aex proxy --policy .aex/policy.aex -- your-mcp-server

Resources ​

Prompts are not permissions. Plans are not contracts.