The proxy used to inspect tools/call and treat tools/list as trusted context. It no longer does. On first contact the (name, description, inputSchema) of every tool is hashed and pinned (trust on first use). Every later tools/list is compared to the pin — a changed hash is a rug-pull, and the pin stays authoritative until an admin re-pins.
Pins persist in Redis (mcp:pins:<server_id>) with an in-memory fallback so a single-node box still gets rug-pull protection within a process lifetime. Enforcement is controlled by MCP_SUPPLY_CHAIN (quarantine default — drop the offending tool from the returned list; warn; off).
GET /api/mcp/pins/{server_id} reports pin statePOST /api/mcp/pins/{server_id}/repin clears pins after a reviewed changeA malicious or compromised MCP server can no longer silently change an approved tool's behavior or schema after the fact. The same rule bundle runs on the Shield laptop client and the cluster, so a description hashed on a developer's Mac and on the cluster produce the same pin.
quarantine, the tool is dropped from the list before an agent ever sees it.
secret → egressNEWAllow-listing tools one at a time misses the exfil that lives in the sequence: read_file (touches a secret) then http_post (egress) in the same turn — each call looks fine on its own. A short, turn-scoped ledger classifies each tool and tracks tainted values by hash only, never the raw secret.
off.Enforcement via MCP_CHAIN_POLICY: enforce (deny, sealed into the chain), warn (default — stamp + log), off. Sequences are authored in the shared bundle; MCP_CHAIN_SEQUENCES overrides.
The classic two-step agent exfil — read a secret with one tool, send it with the next — is caught at the gateway, correlated by hash so the secret value itself never enters the audit trail.
On the regulated profile an agent can only act for a human proofed at IAL ≥ REGULATED_MIN_IAL (default 2 — the ID.me IAL2 tier) no older than REGULATED_MAX_AGE_SECONDS (default 900) before A2A or MCP egress. Missing, forged, expired, stale, or below-floor is a hard deny, sealed into the audit chain. Activate with SMARTFLOW_PROFILE=regulated.
The claims travel in the agent credential's metadata (principal_ial, principal_proofed_at), so no schema migration is required, and the AgentCard gains an optional principal binding.
Delegation + freshness + evidence in one check — "was a real, recently-verified human behind this agent action?" — which a path-based access list structurally cannot express.
config/shieldset.yaml Shield already loads, under shieldset.supply_chain and shieldset.chain_policy. A shared loader compiles them once. Edit one file and the Shield laptop client and the cluster gateway move together; a rules-only bundle falls back to compiled defaults so nothing regresses.
Supply-chain and chain-policy findings, plus regulated-profile denies, are stamped onto the VAS log and sealed into the same tamper-evident HMAC chain as LLM and A2A events. A shared correlation id (x-correlation-id / x-conversation-id / x-trace-id) stitches one agent turn together across all three surfaces.
POST /api/examination/pack exports LLM + MCP + A2A events for a period into a JSONL bundle with the chain head (seq, HMAC, key id) and an independent verifier path, so an examiner re-verifies the chain without trusting the console.
An auditor gets one file that covers every surface an agent touched, and can recompute each entry's HMAC and walk the prev-hash links themselves — evidence, not a screenshot.
| Env | Default | Effect |
|---|---|---|
MCP_SUPPLY_CHAIN | quarantine | Pin + poison enforcement on tools/list |
MCP_CHAIN_POLICY | warn | Cross-tool chain / taint on tools/call |
MCP_CHAIN_SEQUENCES | (bundle) | JSON override of ordered class sequences |
SMARTFLOW_PROFILE | (unset) | regulated turns on the IAL2-fresh gate |
REGULATED_MIN_IAL | 2 | Identity-assurance floor for the principal |
REGULATED_MAX_AGE_SECONDS | 900 | Proofing freshness window |
SHIELD_RULESET_PATH | embedded | Shared bundle (rules + supply_chain + chain_policy) |
| # | Feature | Area |
|---|---|---|
| 1 | TOFU catalog pinning + rug-pull detection on tools/list — Redis-backed pins, admin pin/repin, dashboard Integrity tab | MCP |
| 2 | Tool-description poison scan (hidden-instruction / exfil / tool-shadow / role-injection / invisible unicode) | MCP |
| 3 | Cross-tool chain + secret → egress taint deny on tools/call, hash-only correlation | MCP |
| 4 | Regulated profile — agent bound to an IAL2-fresh human for A2A + MCP egress, denies sealed | Identity |
| 5 | One bundle drives both seams — poison rules + chain sequences in shieldset.yaml | Policy |
| 6 | Examiner pack export — POST /api/examination/pack, one sealed chain, independent verifier path | Audit |