Skip to content

Security Model

AgentCTX implements an 8-layer defense-in-depth security architecture. Each layer addresses a specific threat vector, and they compose together to protect the entire agent interaction lifecycle.

The CTX parser is the first line of defense. It rejects malformed input at parse time with typed error codes:

  • NFC normalization — prevents Unicode canonicalization attacks
  • Size limits — MAX_INPUT_BYTES (65KB) prevents DoS via oversized payloads
  • Depth limits — MAX_DEPTH (16) prevents recursive nesting attacks
  • Banned keys__proto__, constructor, prototype rejected (prevents prototype pollution)
  • Mixed script detection — flags homograph attacks (Latin + Cyrillic mixing in tags)
  • Op×plane validation — invalid combinations rejected before reaching any handler

JWT-based authentication with role-based access control:

  • JWT validation — Ed25519 (EdDSA) or RS256 signature verification on every request, using pure node:crypto with zero external dependencies
  • Namespace isolation — agents can only access their namespace (tenant isolation via tenant_id claim)
  • Default roles — three built-in policies with first-match-wins evaluation:
RolePlanesOperatorsDescription
admink, t, s, mAllFull access to all planes and operations
readerk, t, s, m?, !Read-only — search and lookup only
writerk, t, s, m?, !, +, ~, -CRUD but no tool execution (>)
  • Custom policies — override defaults with higher priority (custom policies are evaluated before built-in ones)
  • Role scoping — backends expose tools only to agents with matching roles
backends:
- id: admin-tools
roles: [admin] # Only admin-role agents see these tools
- id: dev-tools
roles: [code, issues] # Available to code and issues roles

Content is encrypted using AES-256-GCM with keys derived from the content itself:

  • Content-addressed — identical plaintext produces identical ciphertext
  • Deduplication — encrypted content can be deduplicated without decrypting
  • Project-scoped — encryption salts are per-project (from project.salt)

Every CTX-to-human translation is Ed25519 signed:

Agent action: +m "decision" #arch "JWT for API"
Sidecar: Deterministic translation (no LLM)
Signature: Ed25519(ctx_raw + human_output) → verifiable proof
Verify: actx verify → ✅ signatures valid

This ensures humans can always verify what an agent actually did.

Timing-attack resistant operations throughout the crypto layer:

  • Signature verification — constant-time comparison prevents timing side-channels
  • Index padding — obfuscated memory indices prevent access pattern leakage
  • Wrapped in withConstantTiming() — critical paths are timing-normalized

All database operations use parameterized queries via SurrealQL emitters:

// ❌ Never: string interpolation
`SELECT * FROM memory WHERE key = '${userInput}'`
// ✅ Always: parameterized via emitter
surrealqlEmitter.emit(ast) // → parameterized SurrealQL

Zero SQL injection surface — the CTX parser constrains valid inputs, and the emitter produces safe queries.

Encrypted search indices prevent metadata leakage:

  • Obfuscated memory indices — access patterns are hidden even if the database is compromised
  • Constant-time padding — index sizes are normalized to prevent size-based information leakage
  • Module: obfuscation/ — implements constant-time index generation and padding

Advanced crypto primitives for multi-agent trust:

PrimitivePurpose
k-of-n signingRequire multiple agents to authorize an action
OPRFOblivious Pseudo-Random Function for blind key derivation
TEE integrationTrusted Execution Environment for sensitive operations

These are currently at the scaffolding tier (TypeScript prototypes, targeting Rust migration for production).

Every agent has an Ed25519 keypair generated during actx init:

.context/.keys/
├── ed25519.key # Private key (never leaves the machine)
├── ed25519.pub # Public key (shared for verification)
└── project.salt # Convergent encryption salt

The identity system supports:

  • Trust hierarchies — chain-of-trust from root to leaf agents
  • Role shifting — agents can change roles within their trust boundary
  • Federation — cross-organization identity verification via mTLS
  • Sybil resistance — trust weighting prevents identity spoofing
ThreatMitigation
Malformed inputLayer 1: Parser rejects at parse time
Unauthorized accessLayer 2: JWT + RBAC
Data at restLayer 3: AES-256-GCM convergent encryption
Translation tamperingLayer 4: Ed25519 signed translations
Timing attacksLayer 5: Constant-time operations
SQL injectionLayer 6: Parameterized queries only
Metadata leakageLayer 7: Index obfuscation
Single-agent compromiseLayer 8: k-of-n threshold crypto