IronCurtain Documentation

repository·master·Indexed 20 days ago

https://github.com/provos/ironcurtain

A secure runtime for autonomous AI agents that uses a human-readable constitution to derive deterministic security policies. It prevents ambient authority by intercepting agent actions (filesystem, git, network) through a policy engine and MCP servers. Features include a vuln-discovery workflow for vulnerability research, a Web UI for control, and support for Anthropic and OpenAI-compatible models via LiteLLM.

Tokens
393.7K
Snippets
810
Records
1.4K
Agent score
69%

What's inside IronCurtain

  1. Overview of Memory MCP Server

    master
    The Memory MCP Server is a persistent memory solution for LLM agents built on the Model Context Protocol (MCP). It provides semantic search, LLM-powered summarization, and automatic memory maintenance using a single SQLite file. Unlike many other memory servers, it requires zero external dependencies (no Docker, PostgreSQL, or Neo4j) because it handles vector search and keyword search in-process using SQLite extensions.
  2. Overview of the LongMemEval Benchmark Harness

    master

    The LongMemEval Benchmark Harness is a Python-based evaluation tool designed to test the memory-mcp-server against the LongMemEval benchmark (comprising 500 questions across 6 question types).

    The evaluation workflow follows these steps:

    1. Reset: For every question, the harness resets the memory database to ensure isolation.
    2. Ingest: It ingests haystack sessions into the memory server using memory_store calls.
    3. Retrieve: It uses memory_recall (or memory_context) to fetch relevant context based on the question.
    4. Generate: A reader LLM (e.g., Gemma3:27b via Ollama) generates a hypothesis answer based on the retrieved context.
    5. Evaluate: A judge LLM scores the hypothesis for correctness, producing accuracy metrics compatible with the official LongMemEval format.

    This harness allows developers to verify how well the memory server handles temporal reasoning, knowledge updates, and multi-session retrieval.

  3. Overview of the LoCoMo Benchmark Harness

    master

    The LoCoMo (Long-Context Conversations for Memory-based Open-domain Dialogue) benchmark harness evaluates a memory MCP server's ability to handle long, multi-session conversations. It tests five specific reasoning skills:

    1. Single-hop retrieval: Finding information in a single session.
    2. Multi-hop synthesis: Combining information across multiple sessions.
    3. Temporal reasoning: Reasoning about dates and the order of events.
    4. Open-domain knowledge integration: Using external knowledge alongside conversation context.
    5. Adversarial detection: Identifying unanswerable questions.

    The harness uses token-level F1 scoring (normalized) as its primary metric and evaluates retrieval accuracy using dia_id tags.

  4. Comparison: Knostic OpenAnt vs IronCurtain vuln-discovery

    master

    This research document compares the capabilities of Knostic OpenAnt against IronCurtain's vuln-discovery workflow. It highlights specific technical advantages found in OpenAnt that IronCurtain currently lacks or handles differently, specifically regarding cost-efficiency, automated filtering, and structured reporting.

    Key areas of divergence include:

    • Reachability Filtering: OpenAnt uses code-based call graph traversal to reduce LLM analysis costs, whereas IronCurtain relies on the LLM to manually trace call graphs via prompts.
    • Static Analysis Seeding: OpenAnt uses CodeQL to exclude units already flagged by traditional SAST, while IronCurtain does not use static-analysis seeding.
    • Prompt Customization: OpenAnt adjusts threat models based on application type (e.g., cli_tool vs web_app), whereas IronCurtain relies on human-provided task descriptions.
    • Structured Output: OpenAnt enforces a strict schema for exploit paths in its verifier tools, while IronCurtain produces free-form markdown triage documents.
    • Reporting & Deduplication: OpenAnt includes explicit modules for deduplication, evidence-tier rollup, and CWE tagging, and performs post-hoc deduplication of findings via call graphs.
  5. Explore the IronCurtain project structure

    master

    The project is organized into the following core directories:

    • src/index.ts: Entry point.
    • src/cli.ts: CLI command dispatcher.
    • src/config/: Configuration, constitution, and MCP server definitions.
    • src/session/: Session management, budgets, and loop detection.
    • src/sandbox/: V8 isolated execution environment.
    • src/trusted-process/: Policy engine, MCP proxy, audit log, and escalation handler.
    • src/pipeline/: Constitution to policy compilation pipeline.
    • src/escalation/: Escalation listener, TUI dashboard, and state.
    • src/mux/: Terminal multiplexer (PTY bridge, renderer).
    • src/persona/: Persona management.
    • src/memory/: Memory server integration.
    • src/signal/: Signal messaging transport.
    • src/daemon/: Unified daemon (Signal + cron scheduler).
    • src/cron/: Cron job management.
    • src/docker/: Docker agent mode and proxies.
    • src/workflow/: Multi-agent workflow engine.
    • src/web-ui/: Web UI backend.
    • src/servers/: Built-in MCP servers.
    • src/types/: Shared type definitions.
    • packages/memory-mcp-server/: Standalone memory MCP server.
  6. Overview of MITM Token Trajectory Capture

    master

    The MITM Token Trajectory Capture system is designed to capture verbatim HTTP exchanges between Docker-mode agents (such as Claude Code or Goose) and upstream LLM providers (Anthropic, OpenAI, Google).

    Key Characteristics:

    • Output Format: Append-only JSONL, where each line represents one HTTP exchange.
    • Fidelity: Captures byte-exact request bodies and reassembled response bodies (handling streaming SSE) suitable for SFT/RL training pipelines.
    • Security: Designed to never leak real provider credentials; captured headers use the sentinel fakeKey instead of the real swapped keys.
    • Reliability: Uses a 'poisoning' model—if a capture is incomplete due to memory pressure, write errors, or unsupported encodings (like zstd), the entire session is flagged as poisoned rather than emitting partial, useless data.
    • Performance: The capture process is a 'tee' that runs in parallel to the forwarding path, ensuring it never blocks, slows, or interrupts the agent's connection.
  7. Understand ToolCallCoordinator concurrency and safety

    master

    The ToolCallCoordinator is a central component that manages PolicyEngine, AuditLog, CallCircuitBreaker, ApprovalWhitelist, AutoApprover, and ServerContextMap. It is designed to handle $N$ concurrent agent tool-call streams (e.g., multiple researcher or analyzer lanes).

    Thread Safety Mechanism

    The coordinator uses a FIFO call mutex (AsyncMutex) to ensure that in-memory caches and audit logs are protected from race conditions. The following operations are serialized via this.callMutex.withLock(...):

    • handleToolCall (includes buildCallToolDeps() and handleCallTool())
    • handleStructuredToolCall
    • loadPolicy (acquires call-mutex then policy-mutex in a fixed order to prevent deadlocks)
    • close()

    Critical Risk: Mutex Stalling during Escalation

    A known risk is that an agent-path policy escalation (where a human must approve a tool call) can hold the callMutex for the entire duration of the human response latency. This causes all other concurrent lanes to queue and freeze.

    Mitigation Strategy: The design requires that the callMutex be released during the escalation wait (awaiting autoApprove, onEscalation, or waitForEscalationDecision) and re-acquired only to finish the call (writing the audit log, updating the circuit breaker, and handling transport).

  8. Handle context window exhaustion errors

    master

    IronCurtain does not perform automatic pruning or summarization of message history. If the message history exceeds the model's context window, generateText() will throw an error.

    When this happens, the transport will surface an error message similar to: Context window exceeded. Please start a new session.

    To avoid this, you should manage context manually or start a new session when approaching model limits.

  9. Verify Logger interception and formatting

    master

    The IronCurtain logger intercepts standard console methods and redirects them to the configured log file. When testing or using the logger, note the following formatting rules:

    1. Console Interception: console.log and console.error calls are prefixed with [console.log] or [console.error] respectively in the log file.
    2. Argument Formatting: Non-string arguments passed to console.log are formatted as JSON strings.
    3. Log Levels: The logger supports debug, info, warn, and error. Each entry in the log file includes an ISO timestamp and the level (e.g., INFO , ERROR ).
    4. No-op Behavior: If logger.setup() has not been called, calls to logger.info() or logger.error() are no-ops and do not write anywhere.
    // Example of how console calls are transformed in the log file:
    logger.setup({ logFilePath: logFile });
    
    console.log('count:', 42, { key: 'value' });
    // Log file content: [timestamp] [console.log] count: 42 {"key":"value"}
    
    console.error('some error');
    // Log file content: [timestamp] [console.error] some error
  10. Configure OpenRouter via Provider Profiles

    master

    IronCurtain supports OpenRouter through named provider profiles. Instead of using a global setting, you define profiles in your configuration, allowing different sessions to use different providers (e.g., native for Anthropic/OpenAI and openrouter for OpenRouter-based models).

    To use a specific profile, you must specify it during session startup. If no profile is specified, IronCurtain falls back to the modelProviders.default profile defined in your configuration.

    # Start a session using a specific OpenRouter profile
    ironcurtain start --provider-profile my-openrouter-profile
  11. Configure deterministic execution with containers

    master

    You can configure deterministic states to run inside a Docker container by setting the container field to true in your workflow configuration. This allows for isolated execution environments.

    Key configuration options for deterministic states include:

    • container: Boolean. If true, the state executes within a Docker container.
    • containerScope: String. Defines the scope for the container. If not provided, it defaults to DEFAULT_CONTAINER_SCOPE.
    • timeoutMs: Number. The maximum execution time for the commands. If omitted, the system defaults to a 10-minute timeout via the DockerManager.

    When running in a container, commands are executed in the CONTAINER_WORKSPACE_DIR using the codespace user. The system uses a 'mint-on-demand' strategy: if a container for the specified scope does not exist, one is created (minted), re-attaching the persisted /workspace directory to ensure continuity from previous states.

    # Example YAML configuration for a deterministic state
    state_id: "my-test-state"
    run:
      - "npm test"
      - "npm run lint"
    container: true
    containerScope: "test-env-1"
    timeoutMs: 300000