Security engineered in. Not bolted on.
Comis wasn't patched for security after launch. Every component was built from scratch with the question: what happens when an AI agent has real power and someone tries to abuse it?
22
Security layers
40+
Injection patterns
18
Log redaction rules
0
Secrets in plaintext
Flagship feature
Kernel-enforced process isolation.
Every shell command your agent runs is sandboxed at the OS level. The agent sees its workspace. Nothing else. No tricks, no escapes - the kernel enforces it.
- • Full namespace unsharing - mount, PID, user, cgroup, IPC all isolated
- • Private /tmp and /dev - tmpfs mounts, no host filesystem leakage
- • Read-only system paths - /usr, /bin, /lib, /etc (subset) mounted read-only
- • --die-with-parent - sandbox process dies if daemon dies, no orphans
- • Network preserved - network isolation is a separate concern (SSRF guard)
- • Default-deny profile - starts from (deny default), explicitly allows each capability
- • Dynamic SBPL generation - per-invocation profile based on agent workspace
- • Symlink resolution - resolves /tmp → /private/tmp for kernel path matching
- • Startup smoke test - verifies sandbox-exec works on current macOS version
- • Graceful degradation - falls back to command denylist if unavailable
6 layers of exec defense, inside out:
Layer 1
Tool policy can remove exec entirely
Layer 2
Command denylist blocks rm -rf, mkfs, etc.
Layer 3
Env denylist blocks LD_PRELOAD, DYLD_*
Layer 4
CWD validation via safePath()
Layer 5
OS kernel sandbox (bwrap / sandbox-exec)
Layer 6
Subprocess env filtering strips API keys
Defense in depth
9 defense categories. 22 independent layers.
Each layer protects against a specific attack vector. No single layer failing compromises the system.
Block threats before they reach the LLM
Encrypt, scope, and redact credentials at every layer
Prevent outbound requests to private networks
Kernel-enforced filesystem sandbox for shell commands
Limit what each agent can do and require approval
Partition trust levels to prevent memory poisoning
Detect when the LLM leaks system instructions
Authenticate and verify every connection
Prevent runaway costs and sanitize tool output
Every layer explained
What each layer protects against - and how.
Input Guard
PerimeterProtects against: Prompt injection & jailbreaks
Semantic scoring engine with 13 weighted pattern categories, typoglycemia detection for scrambled-letter evasion, and code-block exclusion to avoid false positives. Three risk levels (low/medium/high) with configurable actions: pass, warn, reinforce, or block.
Output Guard
PerimeterProtects against: Secret leakage & data exfiltration
Scans every LLM response for 15 secret patterns (AWS keys, bearer tokens, JWTs, database connection strings), canary token leakage, and system prompt extraction attempts. Critical findings are redacted as [REDACTED] before delivery.
External Content Wrapping
PerimeterProtects against: Indirect prompt injection
All external content (web fetches, API responses, emails, webhooks) is wrapped in randomized 24-hex-char security delimiters with an explicit warning header. The LLM sees clear boundaries between trusted instructions and untrusted content.
Zero-Width Character Stripping
PerimeterProtects against: Invisible character injection
Strips 15+ categories of invisible Unicode characters (U+200B-200F, U+2060, FEFF, U+00AD, tag block U+E0000-E007F) while preserving legitimate flag emoji. Prevents hidden instruction embedding.
Injection Rate Limiter
PerimeterProtects against: Repeated injection attempts
Per-user sliding 5-minute window with progressive thresholds: warn at 3 detections, audit at 5. TTL-based eviction with 10K entry cap to prevent memory exhaustion.
Secret Manager
SecretsProtects against: Credential exposure
AES-256-GCM encryption at rest with HKDF-SHA256 key derivation and per-encryption random salts. Defensive snapshot of environment at creation - no mutation tracking. No enumeration API. Diagnostic errors include the missing key name but never the value.
Scoped Secret Manager
SecretsProtects against: Cross-agent credential access
Per-agent glob-pattern filtering (e.g., OPENAI_*, ANTHROPIC_*). Decorator pattern: indistinguishable from plain SecretManager. Audit events (secret:accessed) log every access attempt with success/denied/not_found outcomes.
Log Sanitizer
SecretsProtects against: Secrets in logs
Three layers deep: Pino fast-redact for structured fields, regex-based sanitizer with 18 patterns for free-text credential detection, and ReDoS mitigation with 1MB input cap. Defense-in-depth - any single layer failing doesn't expose secrets.
SSRF Guard
NetworkProtects against: Server-side request forgery
DNS-pinned URL validation before every outbound fetch. Blocks private RFC 1918 ranges, loopback, link-local, and explicitly blocks cloud metadata IPs (169.254.169.254 for AWS/GCP/Azure, 100.100.100.200 for Alibaba). HTTP/HTTPS only.
OS-Level Exec Sandbox
Process IsolationProtects against: Filesystem escape & host compromise
Kernel-enforced filesystem isolation for every shell command. Linux uses bubblewrap (bwrap) with full namespace unsharing (mount, PID, user, cgroup, IPC). macOS uses sandbox-exec with SBPL deny-default profiles. Agents can only see their own workspace - the host filesystem is invisible. Package manager caches are redirected into the workspace. Process tree kill cascades via --die-with-parent.
Tool Policy Engine
Access ControlProtects against: Unauthorized tool access
Named profiles (minimal, coding, messaging, supervisor, full) with group-based expansion. Per-agent allow/deny lists. The minimal profile exposes only exec, read, write - no memory, no web, no messaging.
Approval Gates
Access ControlProtects against: Unsupervised destructive actions
In-memory request queue with configurable timeouts. Dual caching: approval cache (30s) and denial cache (60s) with mutual invalidation. Batch parallel requests join existing pending entries. Graceful shutdown denies all pending.
Memory Trust Partitioning
MemoryProtects against: Memory poisoning via indirect injection
Three trust levels: system (platform-injected, highest), learned (from conversation), external (from tools/APIs/web, lowest). Low-trust sources can't overwrite high-trust memories. Provenance tracking records who stored each entry, from which channel, at which trust level.
Pre-Write Security Scan
MemoryProtects against: Dangerous patterns persisted in memory
Every memory entry passes through a security scan before storage. Blocks injection patterns, encoded payloads, and instruction-like content from being persisted where it could later surface via RAG retrieval and influence agent behavior.
RAG Trust Filtering
MemoryProtects against: Poisoned memories surfacing in retrieval
RAG retrieval excludes external-trust memories by default. Only system and learned memories are returned unless explicitly requested. Prevents low-trust content from web scrapes, API responses, or tool outputs from influencing agent reasoning through semantic search.
Canary Tokens
DetectionProtects against: System prompt extraction
Deterministic per-session HMAC-SHA256 tokens (CTKN_{16 hex chars}) injected into the system prompt. If the token appears in a response, the OutputGuard detects leakage and redacts it. Proves the LLM was tricked into revealing system instructions.
Bearer Token Authentication
TransportProtects against: Unauthorized API access via token guessing
Timing-safe bearer token comparison using crypto.timingSafeEqual. Eliminates timing side channels that could leak token bytes through response latency differences. All API endpoints require authentication by default.
mTLS Authentication
TransportProtects against: Unauthorized client connections
Mutual TLS certificate validation with Common Name (CN) extraction for client identity. Establishes cryptographic client identity at the transport layer before any application logic executes.
Webhook Verification
TransportProtects against: Forged webhook deliveries
HMAC-SHA256/384/512 signature verification on all incoming webhooks. Timestamp freshness checks with a 5-minute replay window prevent captured webhook payloads from being replayed later.
Budget Guard
RuntimeProtects against: Runaway LLM costs
Three-tier token budgets (per-execution, per-hour, per-day) checked before the LLM call, not after. A prompt injection that tries to exhaust your API budget is stopped before it costs anything. Context window guard blocks at 95% utilization.
Circuit Breaker
RuntimeProtects against: Cascading provider failures
Three-state machine (closed/open/halfOpen) per model and provider. Tracks consecutive failures and latency. When open, returns a fallback response immediately instead of propagating the failure. Automatic recovery via half-open probes.
Tool Output Sanitizer
RuntimeProtects against: Indirect injection via tool results
Normalizes NFKC Unicode, strips invisible characters, detects instruction-like patterns in tool output, and truncates oversized results at newline boundaries (50K char default). Catches injection attempts that arrive through tool results rather than user input.
Design principles
Why "security-first" isn't a marketing claim.
Single source of truth for all patterns
Every injection pattern, secret format, and dangerous command is defined once in injection-patterns.ts and shared across InputGuard, OutputGuard, Tool Sanitizer, and Memory Validator. No drift between components.
Constant-time comparisons everywhere
Bearer token verification, HMAC webhook validation, and secret comparison all use crypto.timingSafeEqual. No timing side channels.
Result type - no thrown exceptions
Every security operation returns Result<T, E>. Error handling is explicit and type-checked. No catch blocks hiding security failures.
Audit events on every decision
TypedEventBus emits security:warn, secret:accessed, approval:requested/resolved, and tool:executed events. Full audit trail without touching application logic.
Trust boundaries on memory
Memory entries carry provenance (who stored it, from which channel, trust level). External content from web/APIs cannot overwrite system or learned memories. RAG excludes external by default.
Pre-commit budget checks
Token budgets are checked before the LLM call, not after. A prompt injection that tries to exhaust your API budget is stopped before it costs you anything.
Audit every line. Run it on your infrastructure.
Comis is Apache-2.0-licensed, fully open source, and self-hosted. No telemetry, no cloud lock-in, no trust required.