Back to KB
Difficulty
Intermediate
Read Time
9 min

What Pipelock Inspects, And What Tool Policy Inspects Instead

By Codcompass TeamΒ·Β·9 min read

Dual-Layer Agent Security: Architecting Inspection at the Wire and Action Boundaries

Current Situation Analysis

The rapid adoption of autonomous coding agents, customer-facing AI assistants, and internal workflow automations has exposed a critical gap in agent security architecture. Vendors frequently market their solutions as "comprehensive inspection engines" that scan every byte passing through the proxy. This claim creates a dangerous mental model for engineering teams: the assumption that network-level scanning inherently covers all data modalities, including images, audio, video, and complex document formats.

The reality is fundamentally different. Wire-level inspection operates on syntactic patterns. It excels at parsing HTTP headers, JSON-RPC frames, WebSocket payloads, and plain-text bodies. However, it cannot natively interpret opaque media without attaching heavy perception pipelines. Running optical character recognition (OCR) on every uploaded screenshot, automatic speech recognition (ASR) on voice memos, or deep PDF extraction on every document fetch introduces latency penalties of 200–800ms per request and multiplies CPU/GPU consumption by an order of magnitude. For real-time agent interactions, these budgets are unacceptable.

This architectural constraint is frequently overlooked during procurement. Engineering teams evaluate agent firewalls using rubrics that demand "image scanning" or "audio transcription" at the proxy layer, forcing vendors into two undesirable positions: either deploy perception models that degrade agent responsiveness, or make coverage claims that collapse under production load. The result is a security posture that appears robust on paper but leaves critical exfiltration vectors open. Agents can bypass wire scanners entirely by packaging sensitive data into screenshots, voice recordings, or embedded PDFs, then exfiltrating them through seemingly benign tool calls.

The industry pain point is not a lack of scanning capability; it is a misalignment between inspection abstraction levels and attack surfaces. Structured text and protocol headers belong at the wire. Semantic actions, tool invocations, and multi-step workflows belong at the action layer. Treating them as a single inspection domain guarantees coverage gaps or performance collapse.

WOW Moment: Key Findings

The architectural split between wire-level and tool-level inspection is not a compromise; it is a deterministic security pattern. When evaluated across production metrics, the dual-layer approach consistently outperforms single-layer designs in latency, coverage accuracy, and resource efficiency.

Inspection LayerLatency OverheadPrimary Coverage ScopeResource ProfileAttack Surface Match
Wire (Byte/Protocol)5–15ms per requestHTTP headers, JSON-RPC frames, text bodies, URLs, MCP stdio/SSECPU-bound, stateless, highly parallelizableCredential leaks in payloads, prompt injection in responses, SSRF attempts, DLP pattern matches
Tool (Semantic/Action)2–8ms per decisionTool names, argument structures, URL parameters inside args, call sequencesStateful, context-aware, policy-drivenOpaque media exfiltration, tool poisoning, multi-step workflow abuse, semantic jailbreaks

This comparison reveals why the dual-layer model matters. Wire inspection catches syntactic violations before data leaves the controlled environment. Tool inspection catches semantic violations before the agent executes a decision. Neither layer can replace the other. A wire-only design misses actions that produce opaque outputs. A tool-only design misses credential leaks embedded in JSON or headers. Together, they close the surface area that single-layer architectures leave exposed.

For engineering leaders, this means evaluation rubrics must shift from "does it scan everything?" to "which layer catches which attack class?" The correct metric is coverage alignment, not blanket inspection claims.

Core Solution

Implementing a dual-layer agent security posture requires separating syntactic inspection from semantic enforcement. The architecture consists of two independent pipelines that share a common enforcement boundary but operate on different data abstractions.

Step 1: Deploy a Protocol-Agnostic Interception Proxy

The proxy must normalize traffic across HTTP forward/reverse, MCP stdio, MCP HTTP/SSE, and WebSocket transports. Each transport is mapped to a unified inspection interface that extracts headers, bodies, URLs, and JSON-RPC frames without altering the original payload.

Step 2: Implement Wire-Level Scanners

Wire scanners operate synchronously on raw bytes and structured text. They run pattern matching, entropy analysis, and content classification before the request reaches the target service.

// Wire-level inspection pipeline
interface WireInspectionResult {
  allowed: boolean;
  redactedPayload?: string;
  flags: string[];
}

class WireInspectionPipeline {
  private dlpEngine: DlpPatternMatcher;
  private injectionDetector: ContentInjectionScanner;
  private ssrfGuard: UrlRiskAnalyzer;

  constructor(config: WireScanConfig) {
    this.dlpEngine = new DlpPatternMatcher(config.dlpRules);
    this.injectionDetector = new ContentInjectionScanner(config.injectionPatterns);
    this.ssrfGuard = new UrlRiskAnalyzer(config.privateRanges, config.metadataEndpoints);
  }

  async inspectRequest(request: ProxyRequest): Promise<WireInspectionResult> {
    const flags: string[] = [];
    let payload = request.body;

    // SSRF validation on all URL-bearing transports
    if (request.url && this.ssrfGuard.isRiskUrl(request.url)) {
      flags.push('SSRF_BLOCKED');
      return { allowed: false, flags };
    }

    // DLP scanning on bodies and headers
    const dlpMatches = this.dlpEngine.scan(payload, request.headers);
    if (dlpMatches.length > 0) {
      flags.push('DLP_MATCH');
      payload = this.dlpEngine.redact(payload, dlpMatches);
    }

    // Injection detection on response bodies and MCP tool definitions
    if (request.isResponse) {
      const injectionRisk = this.injectionDetector.analyze(payload);
      if (injectionRisk.severity === 'HIGH') {
        flags.push('INJECTION_DETECTED');
        return { allowed: false, flags };
      }
    }

    return { allowed: true, redactedPayload: payload, flags };
  }
}

Architecture Rationale: Wire scanners are stateless and optimized for throughput. They use compiled regex engines, entropy thresholds, and precomputed pattern sets to maintain sub-15ms latency. Redaction happens in-memory before forwarding. SSRF checks run first to fail fast on network-level threats.

Step 3: Implement Tool-Level Policy and Chain Detection

Tool inspection operates on JSON-RPC method

names, argument payloads, and call sequences. It does not inspect binary outputs; it inspects the intent behind the invocation.

// Tool-level policy and sequence enforcement
interface ToolPolicyDecision {
  action: 'ALLOW' | 'DENY' | 'REDIRECT';
  matchedRule: string;
  chainRisk?: 'LOW' | 'MEDIUM' | 'HIGH';
}

class ToolActionPolicyEngine {
  private ruleSet: ToolPolicyRule[];
  private sequenceTracker: CallSequenceAnalyzer;

  constructor(policyConfig: ToolPolicyConfig) {
    this.ruleSet = policyConfig.rules;
    this.sequenceTracker = new CallSequenceAnalyzer(policyConfig.chainWindows);
  }

  evaluateInvocation(invocation: ToolInvocation): ToolPolicyDecision {
    // Match tool name and argument patterns
    const matchedRule = this.ruleSet.find(rule => 
      rule.toolName === invocation.method && 
      this.matchesArgumentPattern(rule.argFilters, invocation.params)
    );

    if (matchedRule) {
      return { action: matchedRule.enforcement, matchedRule: matchedRule.id };
    }

    // Analyze call sequence for multi-step exfiltration
    const sequenceRisk = this.sequenceTracker.trackAndEvaluate(invocation);
    if (sequenceRisk.level === 'HIGH') {
      return { 
        action: 'DENY', 
        matchedRule: 'CHAIN_DETECTION', 
        chainRisk: 'HIGH' 
      };
    }

    return { action: 'ALLOW', matchedRule: 'DEFAULT_ALLOW' };
  }

  private matchesArgumentPattern(filters: ArgFilter[], params: Record<string, unknown>): boolean {
    return filters.every(filter => {
      const value = params[filter.key];
      if (typeof value === 'string') {
        return filter.pattern.test(value);
      }
      return false;
    });
  }
}

Architecture Rationale: Tool policies are stateful and context-aware. They intercept JSON-RPC frames before execution, evaluate argument structures, and maintain a sliding window of recent calls to detect suspicious sequences. This layer catches attacks that wire scanners miss: agents screenshotting sensitive UIs, uploading opaque media to external hosts, or chaining benign tools into exfiltration workflows.

Step 4: Orchestrate Enforcement Boundaries

Both pipelines feed into a unified enforcement gateway. Wire scanners block or redact payloads. Tool policies allow, deny, or redirect invocations. Enforcement must align with infrastructure containment strategies, such as the three-UID pattern for process isolation and Kubernetes per-pod network segmentation, to prevent lateral movement if a policy is bypassed.

Pitfall Guide

1. The "OCR at the Proxy" Trap

Explanation: Attempting to run OCR or ASR pipelines inside the interception proxy to "scan images" or "transcribe audio." This destroys latency budgets, requires GPU provisioning, and introduces failure modes when perception models misread context. Fix: Never attach perception models to the wire layer. Instead, enforce tool-level policies that block the invocation of screenshot, recording, or upload tools when targeting sensitive endpoints. Inspect the action, not the output.

2. Ignoring Multi-Step Exfiltration Chains

Explanation: Evaluating tool calls in isolation. An agent reading a database, taking a screenshot, and uploading to a third-party host may pass individual policy checks, but the sequence reveals exfiltration intent. Fix: Deploy sequence matchers with configurable time windows and state tracking. Flag patterns like READ_SENSITIVE_DATA β†’ CAPTURE_UI β†’ UPLOAD_EXTERNAL regardless of individual call legitimacy.

3. Over-Reliance on Static Allowlists

Explanation: Hardcoding allowed tools and arguments without dynamic evaluation. Agents evolve, and static lists create maintenance debt while missing novel attack paths. Fix: Use pattern-based argument filtering combined with behavioral baselines. Allow tools by default but restrict high-risk arguments (URLs, file paths, external endpoints) through dynamic policy evaluation.

4. Misaligning Policy Scope with Agent Workflows

Explanation: Applying blanket restrictions that break legitimate agent operations. For example, blocking all screenshot tools because of exfiltration risk, which disables debugging and UI validation workflows. Fix: Scope policies to specific tool-argument combinations. Allow screenshot tools only for approved domains, redirect uploads to internal review endpoints, and maintain audit trails for policy overrides.

5. Assuming PDF/Vector Text is Syntactic

Explanation: Treating PDFs as plain text for wire scanning. PDFs contain embedded fonts, vector shapes, and image-rendered text that naive extractors miss, creating false negatives in DLP and injection detection. Fix: Apply tool-level policies to PDF fetch tools. Restrict which domains can be fetched, validate URLs against allowlists, and scan the parsed text output only after the agent explicitly extracts it into tool arguments.

6. Bypassing Enforcement Boundaries

Explanation: Assuming proxy inspection covers all traffic. Agents running outside the proxy scope, or using direct socket connections, bypass both wire and tool layers entirely. Fix: Combine proxy inspection with infrastructure containment. Enforce three-UID isolation for agent processes, apply Kubernetes NetworkPolicies to restrict egress, and use service meshes to guarantee all traffic routes through the inspection boundary.

7. Policy Versioning Without Rollback Safety

Explanation: Deploying tool policy updates without version control or canary testing. A malformed regex or overly broad chain rule can block legitimate agent operations across production. Fix: Implement policy versioning with dry-run modes, shadow enforcement, and automatic rollback on anomaly detection. Test chain detection rules against historical call logs before enabling hard denies.

Production Bundle

Action Checklist

  • Map all agent tools to inspection layers: classify each as wire-scannable (text/JSON) or tool-policy-dependent (opaque media/sequence)
  • Configure wire scanners with latency budgets: enforce sub-15ms overhead by prioritizing SSRF and DLP, deferring heavy pattern matching
  • Deploy tool policy rules before execution: block screenshot, recording, and upload tools targeting sensitive domains at the argument level
  • Enable chain detection with sliding windows: track 3–5 step sequences and flag combinations like read β†’ capture β†’ exfiltrate
  • Align proxy enforcement with infrastructure containment: apply three-UID process isolation and Kubernetes per-pod network policies
  • Implement policy versioning and shadow mode: test rule updates in dry-run before enforcing hard denies
  • Audit opaque media workflows: ensure every image/audio/PDF-producing tool has a corresponding allow/deny/redirect policy

Decision Matrix

ScenarioRecommended ApproachWhyCost Impact
High-throughput API agentWire-layer DLP + SSRF + injection scanningHandles JSON/text payloads at scale with minimal latencyLow CPU, predictable network costs
Media-heavy debugging agentTool policy on screenshot/recording tools + chain detectionBlocks exfiltration without running OCR/ASR at proxyModerate policy evaluation overhead, zero perception model costs
Compliance-driven document processingTool policy on PDF fetch tools + post-extraction wire scanningPrevents blind fetching; scans only parsed text in argumentsHigher tool-layer state tracking, lower wire-layer false positives
Multi-agent orchestration platformChain detection + sequence baselining + K8s pod isolationDetects cross-agent exfiltration patterns and lateral movementIncreased memory for sequence tracking, offset by reduced breach risk

Configuration Template

# agent-security-policy.yaml
wire_inspection:
  dlp:
    enabled: true
    patterns:
      - type: api_key
        regex: '(?i)sk-[a-zA-Z0-9]{20,}'
        redact: true
      - type: credential_header
        scope: headers
        redact: true
  injection_detection:
    enabled: true
    severity_threshold: HIGH
    scan_targets:
      - response_body
      - mcp_tool_definitions
  ssrf_protection:
    enabled: true
    block_private_ranges: true
    metadata_endpoints:
      - "169.254.169.254"
      - "metadata.google.internal"

tool_policy:
  rules:
    - id: block_sensitive_screenshots
      tool_name: "browser_screenshot"
      arg_filters:
        - key: "url"
          pattern: "^https://(admin|internal|secure)\\."
      enforcement: DENY
    - id: redirect_uploads
      tool_name: "file_upload"
      arg_filters:
        - key: "destination"
          pattern: "^https://(third-party|external)\\."
      enforcement: REDIRECT
      redirect_target: "https://internal-review.internal/api/upload"
  chain_detection:
    enabled: true
    window_seconds: 300
    max_steps: 5
    flagged_sequences:
      - ["database_query", "browser_screenshot", "file_upload"]
      - ["record_audio", "transcribe", "external_send"]

Quick Start Guide

  1. Deploy the interception proxy in front of your agent runtime. Configure it to normalize HTTP, MCP stdio, MCP HTTP/SSE, and WebSocket traffic into a unified inspection interface.
  2. Load wire scanners with DLP patterns, injection detection rules, and SSRF blocklists. Validate latency overhead stays under 15ms per request using synthetic traffic.
  3. Define tool policies targeting high-risk invocations. Start with screenshot, recording, and upload tools. Apply allow/deny/redirect rules based on argument patterns and destination URLs.
  4. Enable chain detection with a 5-minute sliding window. Run in shadow mode for 24 hours to baseline normal agent behavior, then switch to hard enforcement.
  5. Integrate with infrastructure containment by applying three-UID process isolation and Kubernetes NetworkPolicies. Verify that all egress routes through the inspection boundary and that policy bypasses are structurally impossible.

This dual-layer architecture delivers deterministic security without sacrificing agent responsiveness. By aligning inspection abstraction levels with attack surfaces, engineering teams gain complete coverage, predictable performance, and a scalable foundation for autonomous agent operations.