Node Image Provenance: SLSA Attestations Before ECS or Lambda Pulls

Node Image Provenance: SLSA Attestations Before ECS or Lambda Pulls

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.

Threat model in one line

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

# 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 }}
# 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

# 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
# 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


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 Reply