Agentic Covenants

Recover (RC) · Supply chain

Supply chain at the client side layer

deterministic · Outside the model's reasoning

How do I get back to a known-good state and not repeat this?

What this cell does

Reinstall agent runtime with signature verification, re-pin MCP hashes from clean source, regenerate lockfiles from declared deps.

Artifacts (1)

agent-restore-supply-chain-localview on GitHub
#!/usr/bin/env bash
# ABOUTME: Local supply-chain rebuild. Reinstall runtime with sig verification, restore MCP allowlist from clean source, regen lockfiles.
# ABOUTME: Caller must pass a verified-clean clone path; local files in /etc/agents/ are treated as possibly-tainted.

set -euo pipefail

if [[ $# -lt 3 ]]; then
  echo "Usage: agent-restore-supply-chain-local <AGENT_NAME> <INCIDENT_ID> <CLEAN_REPO_PATH>" >&2
  echo "  CLEAN_REPO_PATH must be a freshly cloned repo on a known-clean machine." >&2
  exit 64
fi

AGENT_NAME="$1"
INCIDENT_ID="$2"
CLEAN_REPO="$3"

if [[ ! -d "$CLEAN_REPO/controls/supply-chain/client-side" ]]; then
  echo "REFUSING: $CLEAN_REPO does not contain controls/supply-chain/client-side/" >&2
  exit 1
fi

SOURCE_DIR="$CLEAN_REPO/controls/supply-chain/client-side"

# 1. Restore MCP allowlist from clean source. Replace, do not merge — a
# merge could keep tainted entries from the local copy.
install -m 0644 "$SOURCE_DIR/mcp-allowlist.json" /etc/agents/mcp-allowlist.json

# 2. Restore mcp-launch and mcp-verify-tools from clean source.
install -m 0755 "$SOURCE_DIR/mcp-launch" /usr/local/bin/mcp-launch
install -m 0755 "$SOURCE_DIR/mcp-verify-tools.py" /usr/local/bin/mcp-verify-tools.py

# 3. Clear chattr +i on lockfiles so the operator can regenerate them.
for lockfile in \
    "/etc/agents/$AGENT_NAME/package-lock.json" \
    "/etc/agents/$AGENT_NAME/requirements.txt" \
    "/etc/agents/$AGENT_NAME/Pipfile.lock" \
    "/etc/agents/$AGENT_NAME/poetry.lock" \
    "/etc/agents/$AGENT_NAME/go.sum" \
    "/etc/agents/$AGENT_NAME/Cargo.lock"; do
  [[ -f "$lockfile" ]] && chattr -i "$lockfile" 2>/dev/null || true
done

# 4. Run vulnerability scans on the rebuilt environment.
if [[ -f "/etc/agents/$AGENT_NAME/requirements.txt" ]] && command -v pip-audit >/dev/null 2>&1; then
  pip-audit --requirement "/etc/agents/$AGENT_NAME/requirements.txt" --strict || \
    echo "WARN: pip-audit reported findings — review before restoring agent traffic" >&2
fi

if [[ -f "/etc/agents/$AGENT_NAME/package.json" ]] && command -v npm >/dev/null 2>&1; then
  ( cd "/etc/agents/$AGENT_NAME" && npm audit --audit-level=high ) || \
    echo "WARN: npm audit reported findings — review before restoring agent traffic" >&2
fi

logger -t agent-recovery -p user.notice \
  "$(jq -n \
      --arg event "supply_chain_restored_local" \
      --arg agent "$AGENT_NAME" \
      --arg incident "$INCIDENT_ID" \
      --arg actor "$(whoami)" \
      --arg ts "$(date -Iseconds)" \
      '{event:$event, agent:$agent, incident:$incident, actor:$actor, ts:$ts}')"

echo "Local supply-chain restore complete for $AGENT_NAME"
echo "Verify pip-audit / npm audit output before restoring agent traffic."

Cell notes

Restorations, Supply chain / Client-side

Precondition. Interventions L2-C5 has fired (suspect MCP removed from allowlist, packages quarantined, lockfiles locked). Restorations identity, authorization, blast-radius, and approval-gating rows complete. A clean MCP allowlist source has been verified (signed commits, off-cluster mirror, not the possibly-tainted local copy).

Authority. On-call.

Tooling

  • - cosign for signature verification on the agent runtime install.
  • - pip-audit, npm audit, trivy, cargo audit, go vuln, whichever apply.
  • - A repo with the canonical mcp-allowlist.json under signed-commit branch protection.

Files in this directory

  • - agent-restore-supply-chain-local, runbook script. Reinstalls agent runtime with cosign verification, copies a fresh mcp-allowlist.json from clean source (overwriting the post-incident local copy), removes chattr +i from lockfiles, regenerates lockfiles from manifest, runs vulnerability scan.

Verification


# 1. Agent runtime signature verifies
cosign verify-blob --signature /usr/local/bin/claude.sig /usr/local/bin/claude

# 2. MCP allowlist matches clean source
md5sum /etc/agents/mcp-allowlist.json controls/supply-chain/client-side/mcp-allowlist.json

# 3. Lockfiles editable (chattr +i removed)
lsattr /etc/agents/claude-code-prod/package-lock.json
# expected: 'i' attribute absent

# 4. Vulnerability scan clean
pip-audit --requirement requirements.txt --strict
npm audit --audit-level=high

Common failure modes

  • - Re-pin to "current" pins to a poisoned current. Pin to a hash from before the earliest indicator of compromise, even if a newer version exists.
  • - Lockfile regenerated against a still-tainted manifest. Verify manifest before regen.
  • - Signature verification accepts the same compromised key, if there's any chance the signing identity itself was exposed, the server-side row's key-rotation step must run first.

Citation

NIST CSF 2.0 RC.RP-01. NIST AI RMF MANAGE 3.1. OWASP ASI04, ASI06. OWASP MCP04, MCP09.

Primary failure modes

Documented, not hypothetical. A control whose bypass is undocumented is worse than no control, because somebody trusted it.

  • re-pin to "current" pins to a poisoned current
  • lockfile regenerated against possibly-tainted manifest

Crosswalk

NIST CSF 2 0RC.RP-01
NIST AI RMFMANAGE 3.1
OWASP AGENTICASI04, ASI06
OWASP MCPMCP04, MCP09