| name | supply-chain-audit |
| description | Audit MCP Runtime supply chain — Go modules, container images, base images, SBOMs, signatures, and GitHub Actions workflows — for known vulnerabilities, unsigned artifacts, weak action pinning, license violations, and pwn-request exposure. Use when Codex bumps dependencies, changes Dockerfiles or workflows, prepares a release, or is asked to audit dependencies, images, SBOMs, signatures, or CI security. |
Supply Chain Audit
Overview
Use this skill to audit everything that crosses the trust boundary into the
build: Go modules, container base images, image signatures, SBOMs, and
GitHub Actions. Scope intentionally excludes runtime authn/z, RBAC, and
cluster posture — those live in security-audit-platform and
k8s-hardening-audit.
Findings use the shared template at
../_shared/FINDINGS-TEMPLATE.md.
Step 1 — Inventory the build inputs
State the inventory in the report so a future audit knows the surface.
Step 2 — Vulnerable Go dependencies
govulncheck reports CVEs the binary actually reaches, not just modules
in the graph. Run from every Go module root:
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
for d in services/*/; do
[ -f "$d/go.mod" ] && (cd "$d" && govulncheck ./...)
done
Report each Vulnerability block as a finding with severity drawn from the
upstream advisory and the CallStack field as exploitability evidence.
Step 3 — Container image scans
Mirror .github/workflows/security-trivy.yaml locally. Build every image
the repo produces and scan it as an image (filesystem scans miss base-image
CVEs). Pin the same Trivy action version (currently 0.36.0 →
aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25):
docker build --pull -f Dockerfile.operator -t mcp-runtime-operator:audit .
docker build --pull -f services/platform-api/Dockerfile -t mcp-platform-api:audit .
docker build --pull -f services/analytics-api/Dockerfile -t mcp-analytics-api:audit .
docker build --pull -f services/runtime-api/Dockerfile -t mcp-runtime-api:audit .
docker build --pull -f services/platform-api/Dockerfile -t mcp-platform-api:audit .
docker build --pull -f services/runtime-api/Dockerfile -t mcp-runtime-api:audit .
docker build --pull -f services/analytics-api/Dockerfile -t mcp-analytics-api:audit .
docker build --pull -f services/ui/Dockerfile -t mcp-sentinel-ui:audit .
docker build --pull -f services/ingest/Dockerfile -t mcp-sentinel-ingest:audit .
docker build --pull -f services/processor/Dockerfile -t mcp-sentinel-processor:audit .
docker build --pull -f services/mcp-gateway/Dockerfile -t mcp-sentinel-mcp-gateway:audit .
bash hack/trivy-sentinel-images.sh
for img in mcp-runtime-operator:audit mcp-platform-api:audit mcp-runtime-api:audit \
mcp-analytics-api:audit mcp-sentinel-ui:audit \
mcp-sentinel-ingest:audit mcp-sentinel-processor:audit \
mcp-sentinel-mcp-gateway:audit; do
trivy image --exit-code 0 --severity CRITICAL,HIGH --ignore-unfixed \
--vuln-type os,library --format table "$img"
done
For each image, also confirm:
- Distroless or static base where applicable; no shell unless explicitly
needed.
- Non-root user in the final stage (
USER directive present, UID ≠ 0).
HEALTHCHECK either present or intentionally absent and documented.
- No
ADD of remote URLs (use COPY with hashed assets, or
RUN curl ... | sha256sum -c style).
- Build args do not bake secrets into layers (
docker history shows no
--build-arg token leakage).
Each gap is a finding (severity per the rubric).
Step 4 — SBOM generation and diff
Match the CI step using anchore/sbom-action (currently
@e22c389904149dbc22b58101806040fa8d37a610 v0.24.0). Locally run syft:
go install github.com/anchore/syft/cmd/syft@latest
for img in mcp-runtime-operator:audit mcp-platform-api:audit mcp-runtime-api:audit \
mcp-analytics-api:audit mcp-sentinel-ui:audit mcp-sentinel-ingest:audit \
mcp-sentinel-processor:audit mcp-sentinel-mcp-gateway:audit; do
out=$(echo "$img" | tr ':/' '__').spdx.json
syft "$img" -o spdx-json="/tmp/$out"
done
When auditing a release, diff against the previous release's SBOM
(downloaded from the prior operator-image-sbom artifact) and call out
new components, new transitive deps, and any drop in pinning quality.
Step 5 — Image signatures (cosign)
If the repo signs images (check .github/workflows/ for cosign / Sigstore
steps):
If no signing is configured, that absence is at least a Low finding for an
alpha project, and Medium when targeting release.
Step 6 — GitHub Actions hardening
For every workflow under .github/workflows/:
Step 7 — Dependency review and licensing
Step 8 — Pre-commit, gitleaks, and secret hygiene
pre-commit run --all-files runs the pinned hooks; any drift in
.pre-commit-config.yaml versions vs CI is a Low finding.
gitleaks detect --source . --config .gitleaks.toml --redact against
the working tree.
gitleaks detect --log-opts="--all" against full history (slow; run
for release audits). Any historical leak triggers a credential
rotation, not just removal.
Step 9 — Reusable artifacts and provenance
- If CI publishes images, verify the registry uses immutable tags or
digest-based deploys.
- If SLSA / in-toto attestations are produced, verify them with
slsa-verifier or cosign verify-attestation.
- If none exist, recommend at least signed SBOMs for release builds.
Step 10 — Report
Use ../_shared/FINDINGS-TEMPLATE.md. For supply-chain audits,
include in the Summary section:
- Total Go modules and direct vs transitive count.
- Number of images scanned and total CVEs by severity.
- Workflow count, % pinned by SHA, list of unpinned actions.
- SBOM diff vs previous release if applicable.
Cross-reference findings against security-audit-platform (e.g., a CVE in
the gateway proxy is also a runtime finding) so the same root cause is not
counted twice.