Node Image Provenance: SLSA Attestations Before ECS or Lambda Pulls

Node Image Provenance: SLSA Attestations Before ECS or Lambda Pulls
11 views
This guide focuses on Node Image Provenance for production systems, with practical trade-offs for reliability, security, and cost. If ECS or Lambda will run whatever tag floated into ECR, a compromised CI job or confused-deputy push can ship malware. SLSA provenance attestations bind an image digest to the build system, source commit, and builder identity—so deploy hooks can refuse unsigned or mismatched artifacts.
⚡ TL;DR: Build Node images in hermetic CI, sign with Sigstore/Cosign, attach SLSA provenance, verify digest + attestation in CD before ECS/Lambda update. Block mutable :latest. Pair with Lambda Code Signing, Policy-as-Code for AI, and Agent Tool Allowlists.

Node Image Provenance: production guidance

text
Attacker pushes evil:latest to ECR
  OR steals CI OIDC to build from a fork
Without verify: ECS rolls out evil
With SLSA gate: digest lacks trusted provenance → deploy fails closed

Build, attest, push

yaml
# GitHub Actions sketch
- uses: docker/build-push-action@v6
  with:
    push: true
    tags: ${{ env.ECR }}/checkout:${{ github.sha }}
    provenance: true
    sbom: true

- name: Cosign sign
  run: |
    cosign sign --yes ${{ env.ECR }}/checkout@${{ steps.build.outputs.digest }}
    cosign attest --yes --predicate slsa-provenance.json \
      ${{ env.ECR }}/checkout@${{ steps.build.outputs.digest }}
dockerfile
# Node image: reproducible-ish defaults
FROM public.ecr.aws/docker/library/node:22-bookworm-slim@sha256:...
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY dist ./dist
USER node
CMD ["node", "dist/server.js"]
Pin base digests. Avoid npm install without lockfiles. Treat AI-generated Dockerfiles with the same gates as humans.

Verify before deploy

bash
# CD gate
DIGEST=$(aws ecr describe-images --repository-name checkout \
  --image-ids imageTag=$GIT_SHA --query 'imageDetails[0].imageDigest' --output text)

cosign verify --certificate-identity-regexp '.*github.com/acme/checkout.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  "$ECR/checkout@$DIGEST"

cosign verify-attestation --type slsaprovenance \
  "$ECR/checkout@$DIGEST" | jq -e '.payload' >/dev/null

# only then:
aws ecs update-service --force-new-deployment ...
# or Lambda package / container image URI with that digest
rego
# OPA/Conftest: deny mutable tags
deny[msg] {
  input.image.tag == "latest"
  msg := "mutable tag latest forbidden"
}
deny[msg] {
  not input.provenance.verified
  msg := "missing verified SLSA provenance"
}
For zip-based Lambda, use code signing configs—see Lambda Code Signing. Same policy spirit: only CI-built, attested artifacts reach prod.

Closing checklist

  • [ ] Images tagged by git SHA / digest only; :latest denied
  • [ ] Cosign signatures + SLSA attestations produced in CI
  • [ ] CD verifies signature and provenance before ECS/Lambda update
  • [ ] Base images pinned by digest
  • [ ] ECR scan-on-push + admission policy for critical CVEs
  • [ ] Break-glass unsigned deploys require dual-control and expire

Related reading

Last updated on September 11, 2026 Related: Lambda Cold Starts on Node 20: Measure, Cut, and Keep Cutting; Lambda Powertools for Node: Structured Logs That Survive On-Call; Lambda ADOT vs Powertools: Tracing Tradeoffs on Node 20 Runtimes.

Watch: 100 Days of AI on YouTube

Short videos from CheatCoders, one AI engineering topic per day.

Open the playlist on YouTube · CheatCoders on YouTube

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a comment

No account needed. Name and email are optional.