Skip to content

feat(security): Airlock service for tainted I/O mediation #230

Description

@rdwj

Problem

Agents currently receive untrusted external input directly — file uploads, webhook payloads, external API responses, user-provided URLs, Telegram messages, etc. There is no centralized security boundary that sanitizes and validates this tainted I/O before it reaches the agent's reasoning loop. A prompt injection buried in a PDF attachment or a crafted webhook payload can influence agent behavior without any mediation layer.

Context: The WYSIWYE Safety Model

This is one half of a broader safety architecture — What You See Is What You Execute (WYSIWYE):

  • Airlock (this issue): handles the input side. All tainted/untrusted data passes through the Airlock before the agent sees it. The Airlock sanitizes, validates, and presents input in a safe, normalized format.
  • Broker (future): handles the output/action side. The agent proposes actions → rules and/or human approve → the Broker executes. The agent never acts directly on the external world.

Together, the Airlock and Broker form a complete mediation layer: nothing tainted gets in without sanitization, and nothing consequential goes out without approval.

Proposed Solution

An Airlock service that mediates ALL tainted communication entering the agent:

What it mediates

  • File uploads (PDFs, images, office documents, archives)
  • Messages from external channels (Telegram, Slack, email)
  • External API responses (third-party services, webhooks)
  • User-provided URLs (fetched content)
  • Webhook payloads (inbound events from external systems)
  • Any other input not originating from the agent's own trusted tool plane

What it does

  • Sanitizes: strips or neutralizes content that could influence agent behavior (prompt injection patterns, embedded instructions, control characters)
  • Validates: enforces schema/format expectations, rejects malformed input
  • Normalizes: presents input to the agent in a consistent, safe format regardless of source
  • Audits: logs all input with provenance metadata (source, timestamp, sanitization actions taken)
  • Rate-limits: prevents flooding from any single external source

Integration with BaseAgent

The agent loop should never receive raw untrusted input. The Airlock sits between external sources and the agent's message queue / tool arguments:

External World → [Airlock] → Agent reasoning loop → [Broker (future)] → External World

Design Questions (need design session)

These are open questions that should be resolved before implementation:

  • Where does the Airlock live? Options: sidecar container, gateway extension (relates to gateway-template), standalone service, or library integrated into BaseAgent. Each has different trade-offs for latency, deployment complexity, and failure modes.
  • Sanitization strategy: What specific sanitization techniques? Regex pattern matching, LLM-based content classification, allowlist-based filtering, or a pipeline of multiple approaches? How do we handle false positives without silently dropping legitimate input?
  • BaseAgent integration surface: Does BaseAgent get an AirlockClient that replaces direct I/O, or does the Airlock intercept at the transport layer (before messages reach BaseAgent at all)?
  • Relationship with ToolInspector: The existing ToolInspector scans tool call arguments for dangerous patterns. Should the Airlock subsume this responsibility for inbound data, or are they complementary (Airlock for external input, ToolInspector for tool argument validation)?
  • Integration with future Broker: How do the Airlock and Broker coordinate? Shared audit log? Common policy engine? Same service with two modes?
  • Failure mode: If the Airlock is down or unreachable, does the agent fail closed (refuse all external input) or degrade gracefully?

Related Issues

Non-Goals

  • This is NOT the Broker / action-approval component (that's the output side of WYSIWYE, separate issue)
  • This is NOT a replacement for container-level isolation (feat: Code execution sandbox hardening with OpenShell + DefenseClaw (v2) #26) — defense in depth, not either/or
  • This is NOT about sanitizing the agent's own tool definitions or system prompts (those are trusted by definition)

Acceptance Criteria

  • Design decision on where the Airlock lives (sidecar vs. gateway extension vs. standalone vs. library)
  • Sanitization pipeline defined with specific techniques for each input type
  • BaseAgent integration design documented
  • Prototype implementation handling at least one input type (e.g., file uploads or webhook payloads)
  • Audit logging for all mediated input with provenance metadata
  • Documentation in docs/architecture.md covering the Airlock's role in the WYSIWYE safety model
  • Integration test demonstrating that a known prompt injection pattern is neutralized before reaching the agent

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions