Recover (RC) · Supply chain
Supply chain at the server side layer
external · Outside the agent entirely
How do I get back to a known-good state and not repeat this?
What this cell does
Rebuild and re-sign images, regenerate SBOMs, rotate signing key if exposed, force redeploy with new SHA pins.
Artifacts (1)
agent-restore-supply-chain-serverview on GitHub#!/usr/bin/env bash
# ABOUTME: Server-side supply-chain rebuild. Removes emergency denies, optionally rotates signing key, rebuilds + re-signs images, regen SBOMs, force-roll.
# ABOUTME: --rotate-signing-key triggers cosign key rotation; required when the original signing key may have been exposed.
set -euo pipefail
ROTATE_KEY="0"
ARGS=()
for arg in "$@"; do
case "$arg" in
--rotate-signing-key) ROTATE_KEY="1" ;;
*) ARGS+=("$arg") ;;
esac
done
set -- "${ARGS[@]}"
if [[ $# -lt 2 ]]; then
echo "Usage: agent-restore-supply-chain-server <AGENT_NAME> <INCIDENT_ID> [--rotate-signing-key]" >&2
exit 64
fi
AGENT_NAME="$1"
INCIDENT_ID="$2"
NAMESPACE="agent-${AGENT_NAME}"
# 1. Remove emergency Kyverno deny ClusterPolicies (image-deny variants and
# emergency-deny-all-agents from the auth row if it lingered).
mapfile -t EMERGENCY < <(
kubectl get clusterpolicies -o name 2>/dev/null \
| grep -E "emergency-deny-(image-|all-agents)"
)
for cp in "${EMERGENCY[@]}"; do
kubectl delete "$cp" 2>/dev/null || true
done
# 2. Remove the emergency Cilium FQDN deny CNP.
kubectl delete cnp -n kube-system emergency-deny-suspect-fqdns 2>/dev/null || true
# 3. Optionally rotate the cosign signing key. Required if the key was on a
# host that may have been compromised. Implementation depends on key store.
if [[ "$ROTATE_KEY" == "1" ]]; then
if ! command -v cosign >/dev/null 2>&1; then
echo "REFUSING: cosign not installed; cannot rotate signing key" >&2
exit 1
fi
echo "Rotating cosign signing key. Old signatures must be marked untrusted in Kyverno verifyImages policies."
# The actual key generation depends on whether you use KMS, file-based, or HSM-backed cosign.
# cosign generate-key-pair k8s://cosign-system/cosign-key (Kubernetes)
# cosign generate-key-pair awskms:///alias/cosign-signer (AWS KMS)
# cosign generate-key-pair (file-based, NOT recommended)
echo "Run the appropriate cosign generate-key-pair command for your key store, then update Kyverno verifyImages policy with the new public key."
fi
# 4. Trigger CI rebuild + re-sign of agent images. Implementation
# environment-specific; this runbook expects a canonical "rebuild" workflow
# you can dispatch.
if command -v gh >/dev/null 2>&1; then
gh workflow run build-and-sign.yml -f agent="$AGENT_NAME" 2>/dev/null || \
echo "WARN: failed to dispatch build-and-sign workflow" >&2
fi
# 5. Force redeploy with new SHA pins. The deployment manifest in source
# controls the digest; reapplying picks up the new SHA after CI publishes.
if [[ -d ./manifests/agent ]]; then
kubectl apply -n "$NAMESPACE" -f "./manifests/agent/${AGENT_NAME}-deployment.yaml" 2>/dev/null || true
kubectl rollout restart deployment -n "$NAMESPACE" 2>/dev/null || true
fi
logger -t agent-recovery -p user.notice \
"$(jq -n \
--arg event "supply_chain_restored_server" \
--arg agent "$AGENT_NAME" \
--arg incident "$INCIDENT_ID" \
--arg rotate "$ROTATE_KEY" \
--arg actor "$(whoami)" \
--arg ts "$(date -Iseconds)" \
'{event:$event, agent:$agent, incident:$incident, rotate_signing_key:$rotate, actor:$actor, ts:$ts}')"
echo "Server-side supply-chain restore complete for $AGENT_NAME"
echo "Recovery is finished. Update Covenants per the lessons learned in this incident."
Cell notes
Restorations, Supply chain / Server-side
Precondition. Interventions L3-C5 has fired (poisoned image deleted from registry, Kyverno deny rule on suspect digest applied, FQDN deny in effect, workloads on last-known-good SHA). All four prior recovery rows complete.
Authority. On-call plus security review.
Tooling
- -
cosignfor image re-sign and key rotation. - -
syftfor SBOM regeneration. - -
cranefor registry operations. - - KMS or HSM for the new signing key (if rotating).
Files in this directory
- -
agent-restore-supply-chain-server, runbook script. Removes the emergency Kyverno deny ClusterPolicies, optionally rotates the cosign signing key (if--rotate-signing-keyis passed), rebuilds and re-signs every agent image, regenerates SBOMs, force-rolls workloads to the new images, removes the emergency Cilium FQDN deny.
Verification
# 1. Emergency Kyverno deny rules removed
kubectl get clusterpolicies | grep -E "emergency-deny-(image-)" || echo "OK: no emergency denies"
# 2. New signed image deploys
kubectl run test --image=ghcr.io/example-org/claude-agent@sha256:NEW_SIGNED_DIGEST -n agent-claude-code-prod
# expected: success
# 3. SBOM attestation present on new image
cosign tree ghcr.io/example-org/claude-agent@sha256:NEW_SIGNED_DIGEST
# 4. Egress to formerly-blocked MCP domain restored (if it was a false-positive)
kubectl exec -n agent-claude-code-prod $(kubectl get pods -n agent-claude-code-prod -o name | head -1) -- \
curl -sS --max-time 3 https://api.anthropic.com -o /dev/null -w "%{http_code}\n"
Common failure modes
- - Signing key rebuild without rotation when key was exposed. If there's any chance the signing key was on a compromised host, rotate it; rebuild alone keeps the same compromised identity signing.
- - SBOM diff not used; regeneration alone does not surface what changed. Always diff old vs new SBOM.
- - Registry-cached compromised images survive on nodes. Force-rollout (covered in the runbook) is mandatory.
Citation
NIST CSF 2.0 RC.RP-01, RC.IM-01; ID.RA-09 (recovery dimension); GV.SC-07 (recovery dimension). NIST SP 800-218 Rev. 1. NIST SP 800-218A. SLSA framework. NIST AI RMF MAP 4.1, MANAGE 3.1.
Primary failure modes
Documented, not hypothetical. A control whose bypass is undocumented is worse than no control, because somebody trusted it.
- signing key rebuild without rotation when key was exposed
- SBOM diff not used; regeneration alone does not surface what changed
- registry-cached compromised images survive
Crosswalk
| NIST CSF 2 0 | RC.RP-01, RC.IM-01, ID.RA-09, GV.SC-07 |
|---|---|
| NIST AI RMF | MAP 4.1, MANAGE 3.1 |
| OWASP AGENTIC | ASI04 |
| OTHER | NIST SP 800-218 Rev. 1, NIST SP 800-218A, SLSA framework |
Cite this cell:
https://agenticcovenants.com/recover/supply-chain/server-side/