pipelock explain

July 13, 2026 · View on GitHub

pipelock explain <url> runs a URL through the scanner pipeline using the loaded config and explains the verdict so that a block is remediable. For a blocked URL it prints the scanner/layer that produced the verdict, the matching pattern (for DLP and blocklist), which part of the URL was inspected, the destination host, the effective config path, and — most importantly — the exact remediation knob that scanner consults, plus any broader option and its tradeoff.

pipelock explain https://example.com/path
pipelock explain --config /etc/pipelock/pipelock.yaml "https://example.com/download?id=42"
pipelock explain --json https://10.0.0.1/internal

The remediation guidance is the point of the command: a hint must name a knob the blocking scanner actually consults. Pointing an operator at a knob the scanner ignores (for example, suggesting top-level suppress: for a URL-DLP block, which URL DLP never reads) trains them to believe they changed policy when they changed nothing. explain is built so every block names the correct, narrowest knob.

No network access

explain does not resolve DNS or fetch anything. It runs the layers that fire before DNS resolution: scheme, CRLF injection, path traversal, allowlist, blocklist, the immutable core SSRF literal check, core and URL DLP, and path/subdomain entropy. The hostname-based SSRF layer (layer 8) resolves DNS at runtime, so explain reports when a verdict would additionally depend on resolution rather than reaching out itself. IP literals that fall in private/loopback/link-local ranges are still caught here by the immutable core SSRF literal check, which needs no resolution.

Per-scanner remediation mapping

Scanner / layerWhy it blockedCorrect (narrowest) knobBroader option + tradeoff
dlp (URL DLP)A configurable DLP pattern matched the URLdlp.patterns[].exempt_domains for that pattern. The top-level suppress: list does NOT apply to URL DLP — it is body-DLP and response-scanning only. If a long token in the query also trips entropy, you may additionally need fetch_proxy.monitoring.query_entropy_param_exclusions for an exact endpoint+parameter, or fetch_proxy.monitoring.query_entropy_exclusions as the broader host-wide fallback (a separate gate).tls_interception.passthrough_domains exempts the host in one line but blinds Pipelock to all inner TLS (method, path, body, response). Only for can't-scan-by-construction hosts.
core_dlpAn immutable critical-credential pattern matchedNone — core DLP is a safety floor and cannot be exempted by config. A genuine false positive must be fixed by tightening the pattern in a release.
entropy (query entropy)A high-entropy query key/value crossed the thresholdfetch_proxy.monitoring.query_entropy_param_exclusions for an exact HTTPS endpoint+parameter when host, path, and param are known; otherwise fetch_proxy.monitoring.query_entropy_exclusions is the broader host-wide fallback. Separate gate from DLP — exempting a DLP pattern does not lift an entropy block.Raising fetch_proxy.monitoring.entropy_threshold lowers sensitivity for every destination.
entropy (path entropy)A high-entropy path segment crossed the thresholdfetch_proxy.monitoring.subdomain_entropy_exclusions for host-wide path entropy false positives, or an enforced request_policy route for an exact host+path exemption. query_entropy_exclusions does not lift path entropy blocks.Raising fetch_proxy.monitoring.entropy_threshold lowers sensitivity for every destination.
subdomain_entropyA high-entropy DNS label was detectedfetch_proxy.monitoring.subdomain_entropy_exclusions.Raising fetch_proxy.monitoring.subdomain_entropy_threshold globally.
blocklistThe host is on the domain blocklistRemove or narrow the entry in fetch_proxy.monitoring.blocklist.
allowlistStrict mode and the host is not allowlistedAdd the host to api_allowlist.Switching mode from strict to balanced permits monitored browsing for all destinations.
ssrf / ssrf_metadataThe host resolves (at runtime) to a private/metadata IPTop-level trusted_domains (hostname) or ssrf.ip_allowlist (IP range). This verdict depends on DNS resolution.Disabling SSRF (internal: []) removes private-range protection for all destinations.
core_ssrfA private/loopback/link-local IP literalssrf.ip_allowlist is the only override (honored even by the core check). The floor cannot be disabled wholesale.
ratelimitPer-domain request ceiling reachedfetch_proxy.monitoring.max_requests_per_minute, or retry after the window.
lengthURL exceeds the max lengthfetch_proxy.monitoring.max_url_length, or inspect for query-param data stuffing.
databudgetPer-domain data ceiling reachedAdjust the session data-budget configuration.
crlf_injection / path_traversalA header-injection or directory-escape sequenceNone — never legitimate in a normal URL. Correct the URL at its source.
schemeA non-http/https schemeNone — use an http/https URL.

Flags

FlagDefaultPurpose
--config, -cbuilt-in defaultsConfig file to load. Without it, the built-in default config is used.
--jsonfalseEmit a structured report instead of human-readable text.

pipelock explain event

pipelock explain event <id> looks up a past decision in a Pipelock JSONL audit log and explains the operator-facing reason. It matches request_id first, then event_id and id, and it uses the configured DLP rules when redacting untrusted log content before printing it.

pipelock explain event req-abc-123 \
  --config /etc/pipelock/pipelock.yaml \
  --log /var/log/pipelock/audit.jsonl

pipelock explain event req-abc-123 \
  --config /etc/pipelock/pipelock.yaml \
  --log /var/log/pipelock/audit.jsonl \
  --json

When --log is omitted, the command uses logging.file from the config when that config writes JSONL audit events to a file. The command is read-only: it does not contact the proxy and does not mutate the log.

URL explanation exit codes

These exit codes apply to pipelock explain <url>. pipelock explain event uses normal command success/failure semantics for log lookup and rendering.

Exit codeMeaning
0The URL is allowed under the loaded config.
2Config load failed, or the URL was empty/unparseable.
3The URL is blocked. The report names the scanner and the remediation.

The non-zero exit on a block lets scripts branch on the verdict without parsing output.

JSON report fields

--json emits a stable report shape: url, config_file, mode, version, allowed, scanner, layer, target_view (url_query / host / path / scheme / url), host, pattern_name (for DLP/blocklist), reason, score, dns_dependent, notes, warn_matches, and a remediation object with knob, broader, and immutable.

See also

  • pipelock doctor — audits whether configured protections are actually enforceable.
  • pipelock check — validate a config and scan a single URL for an allow/block verdict.
  • False-positive tuning — the knob-selection guide this command's remediation mapping is built from.