Security Model
Security Model
Section titled “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 8 Layers
Section titled “The 8 Layers”Layer 1: Input Validation
Section titled “Layer 1: Input Validation”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,prototyperejected (prevents prototype pollution) - Mixed script detection — flags homograph attacks (Latin + Cyrillic mixing in tags)
- Op×plane validation — invalid combinations rejected before reaching any handler
Layer 2: Auth + RBAC
Section titled “Layer 2: Auth + RBAC”JWT-based authentication with role-based access control:
- JWT validation — Ed25519 (EdDSA) or RS256 signature verification on every request, using pure
node:cryptowith zero external dependencies - Namespace isolation — agents can only access their namespace (tenant isolation via
tenant_idclaim) - Default roles — three built-in policies with first-match-wins evaluation:
| Role | Planes | Operators | Description |
|---|---|---|---|
admin | k, t, s, m | All | Full access to all planes and operations |
reader | k, t, s, m | ?, ! | Read-only — search and lookup only |
writer | k, 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 rolesLayer 3: Convergent Encryption
Section titled “Layer 3: Convergent Encryption”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)
Layer 4: Signed Translations
Section titled “Layer 4: Signed Translations”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 validThis ensures humans can always verify what an agent actually did.
Layer 5: Constant-Time Operations
Section titled “Layer 5: Constant-Time Operations”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
Layer 6: Parameterized Queries
Section titled “Layer 6: Parameterized Queries”All database operations use parameterized queries via SurrealQL emitters:
// ❌ Never: string interpolation`SELECT * FROM memory WHERE key = '${userInput}'`
// ✅ Always: parameterized via emittersurrealqlEmitter.emit(ast) // → parameterized SurrealQLZero SQL injection surface — the CTX parser constrains valid inputs, and the emitter produces safe queries.
Layer 7: Index Obfuscation
Section titled “Layer 7: Index Obfuscation”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
Layer 8: Threshold Cryptography
Section titled “Layer 8: Threshold Cryptography”Advanced crypto primitives for multi-agent trust:
| Primitive | Purpose |
|---|---|
| k-of-n signing | Require multiple agents to authorize an action |
| OPRF | Oblivious Pseudo-Random Function for blind key derivation |
| TEE integration | Trusted Execution Environment for sensitive operations |
These are currently at the scaffolding tier (TypeScript prototypes, targeting Rust migration for production).
Agent Identity
Section titled “Agent Identity”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 saltThe 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
Threat Model Summary
Section titled “Threat Model Summary”| Threat | Mitigation |
|---|---|
| Malformed input | Layer 1: Parser rejects at parse time |
| Unauthorized access | Layer 2: JWT + RBAC |
| Data at rest | Layer 3: AES-256-GCM convergent encryption |
| Translation tampering | Layer 4: Ed25519 signed translations |
| Timing attacks | Layer 5: Constant-time operations |
| SQL injection | Layer 6: Parameterized queries only |
| Metadata leakage | Layer 7: Index obfuscation |
| Single-agent compromise | Layer 8: k-of-n threshold crypto |
- Sentinel Monitoring → — runtime alignment enforcement
- Sidecar → — the trust boundary compiler