Skip to content

Harden CI/CD supply chain: SHA-pin actions, scope perms, verify martin [skip release]#22

Merged
johncarmack1984 merged 1 commit into
mainfrom
audit/ci-supply-chain
Jun 27, 2026
Merged

Harden CI/CD supply chain: SHA-pin actions, scope perms, verify martin [skip release]#22
johncarmack1984 merged 1 commit into
mainfrom
audit/ci-supply-chain

Conversation

@johncarmack1984

Copy link
Copy Markdown
Owner

The audit's only High. Hardens the deploy/release pipeline against supply-chain drift.

Changes

  • SHA-pin every GitHub Action across all four workflows (ci, deploy, auto-release, release). Each pin keeps its version as a trailing comment (@<sha> # v6) so it stays readable and Dependabot-trackable. A moved/retagged action can no longer swap code into our pipeline.
  • Dependabot (github-actions, weekly) — bumps the pins so they don't rot. Scoped to actions for now (npm/cargo left out to limit PR volume).
  • Per-job permissions in deploy.yml — the workflow-level {id-token, contents, deployments} union is replaced with a contents: read floor; each job escalates only what it needs. The changes (paths-filter) job no longer receives an OIDC id-token it never used; infra/web get id-token, only web gets deployments.
  • Pin cargo-lambda==1.9.1 in both the ci cdk job and the deploy infra job.
  • Pin + checksum the martin binary — was curl … latest | tar with no integrity check. Now downloads a pinned release (martin-v1.11.0) to a file, verifies its sha256, then extracts. Overridable via MARTIN_RELEASE + MARTIN_SHA256.

Verification

  • actionlint clean on all workflows.
  • Ran build-martin-lambda.sh end-to-end: sha256 verified, zip built. The ci cdk job runs this same script, so the gate is exercised on ubuntu on this PR (pre-merge).
  • deploy.yml's per-job permissions / SHA pins only execute post-merge (deploy runs on push to main); reviewed carefully + actionlint-validated. Merging this triggers a full (idempotent) deploy that exercises the hardened pipeline — will watch it.

Out of scope

Tightening the CDK bootstrap cfn-exec role / OIDC AssumeRole permissions-boundary is a local admin op (CI never deploys the OIDC stack), tracked separately.

Docs & attribution

  • README IaC section documents the supply-chain posture. No data source / attribution change.

…kip release]

The audit's one High. Pins the deploy pipeline against supply-chain drift:

- SHA-pin every GitHub Action across all workflows (version kept as a trailing
  comment), so a moved tag can't swap action code under us. Add Dependabot
  (github-actions, weekly) to bump the pins.
- deploy.yml: replace the workflow-level union of permissions with a
  contents:read floor + per-job escalation — only infra/web get the OIDC
  id-token, and only web gets deployments:write. The changes (paths-filter)
  job no longer receives a token it never used.
- Pin cargo-lambda (==1.9.1) in both the ci cdk job and the deploy infra job.
- Pin the martin release (martin-v1.11.0) and verify its tarball sha256 before
  packaging — download to a file, check, then extract (was a curl|tar of
  "latest" with no integrity check). Override via MARTIN_RELEASE + MARTIN_SHA256.

README: document the supply-chain posture in the IaC section.

Out of scope (a local admin op, not CI): tightening the CDK bootstrap
cfn-exec role / OIDC AssumeRole boundary — tracked separately.
@johncarmack1984 johncarmack1984 merged commit 1b84f9b into main Jun 27, 2026
7 checks passed
@johncarmack1984 johncarmack1984 deleted the audit/ci-supply-chain branch June 27, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant