BleedWatch
00 // MCP ARCHITECTURE

Every security-tool invocation passes through one auditable boundary.

SaintScan is BleedWatch's MCP gateway for sandboxed active validation. It routes CLI tools through allowlists, tenant scope checks, argv sanitization, digest-pinned images, policy decisions, circuit breakers, and immutable audit records before any process can run.

01 // WHY IT MATTERS

Three properties CISOs ask about.

Agent-driven pentest and validation platforms introduce new failure modes. The gateway makes the execution path reviewable, bounded, and reconstructable.

Single chokepoint for tool execution

Every invocation of nuclei, sqlmap, naabu, httpx, katana, and future active-validation tools routes through one auditable boundary. There are no ad-hoc execFile calls and no shadow tool paths.

SOC 2-grade cryptographic audit trail

Every execution produces an append-plus-one-finalize row in saintscan_mcp_audit. Immutability is enforced at the PostgreSQL level with REVOKE plus trigger protections.

PostgreSQL-level tenant isolation

Audit and kill-switch tables run under row-level security. Gateway-side tenant-tier allowlisting and per-(scanId, tool) circuit breakers isolate tenant risk from the shared execution fleet.

02 // ARCHITECTURE

One gateway, seven enforced layers.

An agent request reaches a tool binary only after every layer approves the same tenant, target, image, policy, and audit context. If any layer rejects the request, no container is spawned.

BleedWatch MCP gateway execution flowAn agent request enters the MCP gateway, passes through allowlist, scope validation, argv sanitizer, digest-pinned image resolver, policy gate, circuit breaker, and audit insert before reaching the docker socket proxy.Agentscan requestMCP GATEWAYAllowlisttool + tenant tierScope validatorauthorized targetArgv sanitizerno shell expansionDigest resolverpinned imagePolicy gateactive opt-inCircuit breakerper scan + toolaudit insert before execdocker-socketproxyTool containerdigest-pinned, non-root

Agent requests traverse allowlist, scope validator, argv sanitizer, digest resolver, policy gate, circuit breaker, and pre-exec audit insert before the docker-socket-proxy launches a digest-pinned non-root container.

03 // GATEWAY PIPELINE

Fail closed before execution.

The pipeline is deliberately redundant. Tool, target, argument, image, policy, rate, and audit checks each catch different classes of agent and tool-execution failure.

fn-138 closure

1. Tool allowlist

The requested binary must exist in the compiled SaintScan allowlist. Unknown tools, shell paths, absolute paths, aliases, and runtime-provided executables are rejected before argument parsing.

2. Scope validator

The target is matched against the tenant's approved scan scope: domain, host, repository, package, registry artifact, or explicitly authorized validation target.

3. Argv sanitizer

Arguments are represented as arrays, not shell strings. Dangerous flags, output redirects, file-system writes, shell expansion, nested commands, and unbounded concurrency are blocked.

4. Digest-pinned image resolver

Tool containers are resolved to immutable SHA-256 image digests. Tags alone are not accepted, and the digest must match the approved registry manifest before execution.

5. Policy gate

Tenant tier, authorization mode, tool risk level, expected duration, target class, and active-validation opt-in are evaluated before a process can be created.

6. Circuit breaker

Per-(scanId, tool) counters enforce max attempts, backoff, timeout, and kill-switch state so a single scan cannot create a runaway validation loop.

7. Audit insert

The gateway synchronously inserts an audit row before execution. If the insert fails, the tool does not run. Finalization may update only the allowed outcome fields.

04 // ADMISSION PSEUDOCODE

The request is admitted before the proxy sees it.

const admission = await gateway.admit({
  tenantId,
  scanId,
  tool,
  target,
  argv,
});

// Pipeline:
// allowlist -> scope validator -> argv sanitizer -> digest resolver
// -> policy -> circuit breaker -> audit insert -> docker-socket-proxy

if (!admission.allowed) {
  return deny(admission.reason);
}

return dockerProxy.run({
  image: admission.imageDigest,
  user: 'nonroot',
  network: admission.networkPolicy,
  argv: admission.sanitizedArgv,
  timeoutMs: admission.timeoutMs,
});
05 // SECURITY GUARANTEES

What the gateway is designed to prevent.

No shell expansion

SaintScan never constructs a shell command from user input. Commands are spawned as binary plus argv array after allowlist and sanitizer checks.

No mutable tool tags

Tool containers must be digest-pinned. Mutable tags such as latest are rejected in production policy.

No unscoped validation

Active validation requires approved tenant scope and explicit opt-in. OSINT-only scans cannot silently promote themselves to probing.

No silent audit gaps

Execution depends on a pre-exec audit insert. Missing audit storage fails closed instead of allowing unaudited tool execution.

No cross-tenant audit reads

RLS policies filter audit rows by tenant. Support review uses controlled break-glass paths, not broad application queries.

No app-layer-only immutability

The database rejects mutation of immutable fields even if an application credential is compromised.

06 // THREAT MODEL

Risks and controls.

The gateway assumes agent output may be adversarial, scanner targets may be hostile, tool containers may need rapid revocation, and application credentials may be less trusted than database policy.

ThreatControl
Prompt injection asks an agent to run an unsafe toolThe tool name must clear the allowlist, tenant tier, scope validator, policy gate, and circuit breaker. Unknown binaries never reach spawn.
Argument injection turns a benign tool into an exploit pathArguments are parsed as structured arrays. Shell metacharacters, nested commands, output redirects, write paths, and dangerous flags are rejected.
A mutable container tag is replaced upstreamImages are resolved and executed by approved digest. Tag drift is visible before rollout and cannot silently change production tools.
One tenant creates a runaway validation loopPer-(scanId, tool) circuit breakers and kill switches isolate the scan. Shared workers do not keep retrying blindly.
Application credentials are compromisedPostgreSQL RLS and audit-table triggers enforce tenant filtering and immutable fields below the API layer.
Auditors cannot reconstruct what happenedThe audit row records tenant, scan, tool, image digest, argv hash, target hash, start time, final status, duration, and policy decision.
07 // AUDIT TABLE INVARIANTS

Append plus one finalize.

The audit table records a pre-execution row, then permits a single finalization update for outcome fields. Immutable fields such as tenant, scan, tool, target hash, argv hash, image digest, and policy version cannot change after insert.

tenant_idscan_idtooltarget_hashargv_hashimage_digestpolicy_versiondecisionstarted_atfinalized_atduration_msexit_codestdout_refstderr_referror_class
create table saintscan_mcp_audit (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null,
  scan_id uuid not null,
  tool text not null,
  target_hash text not null,
  argv_hash text not null,
  image_digest text not null,
  policy_version text not null,
  decision text not null check (decision in ('allow', 'deny')),
  started_at timestamptz not null default now(),
  finalized_at timestamptz,
  duration_ms integer,
  exit_code integer,
  stdout_ref text,
  stderr_ref text,
  error_class text,
  created_by text not null default 'saintscan-mcp-gateway'
);

alter table saintscan_mcp_audit enable row level security;

create policy saintscan_mcp_audit_tenant_isolation
  on saintscan_mcp_audit
  using (tenant_id = current_setting('app.tenant_id')::uuid);

revoke update on saintscan_mcp_audit from app_runtime;

create trigger saintscan_mcp_audit_immutable
  before update on saintscan_mcp_audit
  for each row execute function enforce_mcp_audit_finalize_only();
08 // COMPLIANCE MAPPING

How the gateway maps to your controls.

Each mapping references the gateway control that can be reviewed in auditor language. Full clause-to-evidence crosswalks are available in the enterprise security review package.

NIS2Article 21(d)

Cybersecurity supply-chain management

Digest-pinned tool container images, gateway-side binary allowlist, and full audit trail of third-party tool invocations address supply-chain management obligations for external tooling.

ISO 27001Annex A 8.25

Secure development lifecycle

Tool-execution code paths are centralized, reviewed, policy-gated, and validated before any binary is spawned.

PCI-DSSRequirement 6.3

Maintain secure systems and software

Tool binaries are pinned, vulnerability-reviewed before rollout, invoked through one controlled entry point, and insulated from shell expansion.

SOC 2CC7.1

System operations and monitoring

mcp_client_* and mcp_exec_* metrics, synchronous audit insert, append-plus-one finalize semantics, and kill-switch logs support operational monitoring evidence.

DORAICT risk management

Operational resilience

Circuit breakers, kill switches, incident runbooks, and deterministic execution logs help reconstruct and contain validation incidents.

GDPRArticle 32

Security of processing

Tenant-scoped execution logs, data minimization, RLS, immutable audit rows, and active-validation opt-in support appropriate technical controls.

09 // INCIDENT RESPONSE RUNBOOK

Contain by tenant, tool, or scan.

The incident runbook is shaped around the gateway boundary. Operators can revoke a tool, pause a tenant, stop a scan, or block a digest without disabling the whole platform.

On-call

Detect

Alert triggers on mcp_exec_failures_total, circuit-breaker open events, unexpected tool decision rates, image digest mismatch, or audit insert failures.

Security engineer

Contain

Open the per-tool or per-tenant kill switch. Existing containers are stopped through the proxy path and new admissions fail closed.

Incident commander

Preserve

Export audit rows, policy versions, digest manifests, metrics, and gateway logs. Do not mutate audit records.

Platform owner

Eradicate

Patch policy, sanitizer, image digest, or scope logic. Add regression coverage for the exact admission path.

Operations

Recover

Re-enable the specific tool or tenant only after replaying a dry-run decision, verifying audit inserts, and confirming breaker counters.

DPO / customer owner

Notify

If customer data or availability was affected, notify through email, status page, and in-app banner according to the incident policy.

SECURITY REVIEW

Evaluating BleedWatch for regulated workloads?

Prospects in banking, healthcare, public sector, and critical infrastructure can request the full security review package, including the MCP audit schema, rollback runbook, and control evidence crosswalk for NIS2, ISO 27001, PCI-DSS, DORA, GDPR, and SOC 2.

PACKAGE CONTENTS

  • MCP gateway architecture brief
  • Audit table schema and invariants
  • Kill-switch and revocation runbook
  • Digest-pinning and image review policy
  • Clause-to-evidence control mapping
Request package