Skip to content
Flows
Agent QA & Security Advanced · 120-180 minutes

Build a Command Security Pipeline for Your Agent

Replace scattered if-else safety checks with a layered validator pipeline: single-purpose checks, an allow/ask/deny/passthrough contract, and severity-aware ordering.

Start Route · 4 steps

The route

4 steps to Done

  1. 01

    Define the contract and pipeline skeleton

    A uniform result type is what makes 20 checks composable.

    Preview prompt + verify gate ▾

    Define the validator contract: each validator is a pure function taking the parsed command context and returning a result of allow (confident-safe: short-circuit the pipeline), ask (needs user confirmation, with reason), deny (block, with reason), or passthrough (no opinion: next validator). Add a severity flag distinguishing parser-mismatch findings (the command will execute differently than it parses - must interrupt) from informational ones (redirections, newlines - confirm but do not panic). Build the pipeline runner: run early validators first (allow can short-circuit), then the main chain collecting results, then apply selection - any deny wins, else the highest-severity ask, else allow. Wire ALL execution paths through it, including sub-agents and background tasks.

    • Contract covers allow/ask/deny/passthrough plus severity
    • Early-allow short-circuit implemented
    • No execution path bypasses the pipeline
  2. 02

    Implement early validators and input hygiene

    Cheap checks first: catch garbage and fast-path the common safe cases.

    Preview prompt + verify gate ▾

    Implement the front of the pipeline. Input hygiene (block outright): control characters and null bytes in commands, and known parser bugs in your shell-parsing library (test its edge cases - a quoting bug in the parser is a security hole in you). Preprocessing: strip heredoc bodies safely so later checks see structure rather than payload text; extract quote variants of the command for later multi-view checks. Early allows: empty commands, and your environment's most common verified-safe patterns (a well-formed commit with heredoc message, a plain build command) - these short-circuit to allow so the main chain's cost stays bounded. Early asks: malformed or incomplete commands (leading dash or tab) that suggest a truncated generation.

    • Control characters and parser edge cases blocked with tests
    • Heredoc stripping and quote extraction implemented
    • Common safe patterns short-circuit measured by pipeline timing
  3. 03

    Build the main validator chain and hard path constraints

    One attack class per validator, plus constraints nothing can override.

    Preview prompt + verify gate ▾

    Implement single-purpose main-chain validators, each with its own tests: shell metacharacters that split commands (';', '|', '&' outside quotes), IFS-injection, redirection detection (informational severity), sub-command extraction for compound commands so each piece is checked (a benign-looking second command reading credentials is the classic leak). Then implement the hard constraints layer: a protected-path denylist (system roots, credential directories) that blocks removal operations regardless of any permission rule, correct handling of the '--' separator so flags cannot smuggle paths past extraction, and for your riskiest allowed tool (e.g. sed-like editors), a whitelist of safe forms plus a denylist of dangerous sub-features (write-file and execute commands, non-ASCII lookalikes, multiline programs). Keep validators stateless and independent.

    • Each validator targets exactly one attack class
    • Compound commands are split and each part validated
    • Protected paths block removal even with explicit permission
  4. 04

    Order by severity and regression-test with an attack corpus

    The most severe finding must win, and stay winning.

    Preview prompt + verify gate ▾

    Implement result selection precisely: deny beats everything; among asks, parser-mismatch severity beats informational (a command flagged for both redirection and an escaped-operator trick must report the trick - the finding that means 'this will not execute the way it parses'); informational asks are deferred and only surface if nothing worse fired. Build the attack corpus: every attack class from your validators plus real transcripts, each labeled with expected outcome and expected reporting validator. Add benign-command cases asserting allow/passthrough to keep false positives visible. Run the corpus in CI; any change to a validator must keep the whole corpus green. Document the known-false-positive policy (e.g. find -exec's escaped semicolon asks once) - deliberate asks are fine, undocumented ones erode trust.

    • Deny > misparse-ask > informational-ask ordering tested
    • Corpus covers every validator's attack class plus benign cases
    • CI blocks on any corpus regression

Research-backed

Sources behind this flow