← Back to Home

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.

Linux Bubblewrap (bwrap)
  • 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)
macOS sandbox-exec (SBPL)
  • 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.

5 Perimeter

Block threats before they reach the LLM

3 Secrets

Encrypt, scope, and redact credentials at every layer

1 Network

Prevent outbound requests to private networks

1 Process Isolation

Kernel-enforced filesystem sandbox for shell commands

2 Access Control

Limit what each agent can do and require approval

3 Memory

Partition trust levels to prevent memory poisoning

1 Detection

Detect when the LLM leaks system instructions

3 Transport

Authenticate and verify every connection

3 Runtime

Prevent runaway costs and sanitize tool output

Every layer explained

What each layer protects against - and how.

1

Input Guard

Perimeter

Protects 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.

2

Output Guard

Perimeter

Protects 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.

3

External Content Wrapping

Perimeter

Protects 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.

4

Zero-Width Character Stripping

Perimeter

Protects 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.

5

Injection Rate Limiter

Perimeter

Protects 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.

6

Secret Manager

Secrets

Protects 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.

7

Scoped Secret Manager

Secrets

Protects 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.

8

Log Sanitizer

Secrets

Protects 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.

9

SSRF Guard

Network

Protects 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.

10

OS-Level Exec Sandbox

Process Isolation

Protects 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.

11

Tool Policy Engine

Access Control

Protects 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.

12

Approval Gates

Access Control

Protects 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.

13

Memory Trust Partitioning

Memory

Protects 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.

14

Pre-Write Security Scan

Memory

Protects 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.

15

RAG Trust Filtering

Memory

Protects 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.

16

Canary Tokens

Detection

Protects 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.

17

Bearer Token Authentication

Transport

Protects 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.

18

mTLS Authentication

Transport

Protects 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.

19

Webhook Verification

Transport

Protects 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.

20

Budget Guard

Runtime

Protects 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.

21

Circuit Breaker

Runtime

Protects 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.

22

Tool Output Sanitizer

Runtime

Protects 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.