Skip to content

chore(ci): sign and attest published images, pin base by digest#134

Merged
abubnalitic-nbl merged 2 commits into
mainfrom
chore/harden-container-publish-dockerhub
May 8, 2026
Merged

chore(ci): sign and attest published images, pin base by digest#134
abubnalitic-nbl merged 2 commits into
mainfrom
chore/harden-container-publish-dockerhub

Conversation

@abubnalitic-nbl

@abubnalitic-nbl abubnalitic-nbl commented May 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Supply-chain hardening for the Docker Hub publish pipeline introduced in #132. Carries over the intent of the (now-closed) #127, restructured to fit the matrix-build / manifest-merge workflow.

  • Base image pinned by digest (Dockerfile, both stages). Prevents a compromised python:3.14-alpine3.23 tag from substituting the base. Renovate's docker manager will bump digests.
  • Cosign keyless signing of the published multi-arch manifest (Sigstore + GitHub OIDC, no key material to manage). Pullers can verify each image came from this repo's Actions.
  • SLSA build provenance attestations via actions/attest-build-provenance, pushed to the registry alongside the manifest. Cryptographically links any published digest back to the exact workflow run and commit that produced it.
  • Minimum extra permissions on the merge job: id-token: write, attestations: write.
  • README documents the cosign verify command in the Docker Hub section.

Why sign in the merge job

The matrix build jobs push per-arch images by digest as internal artifacts. The public-facing object is the multi-arch manifest list created in merge. Signing once at the manifest-list digest covers all aliased tags (latest, X.Y.Z, X.Y, X) since they all resolve to the same digest.

Verify

After merge + the next v*.*.* tag push, pulling and verifying an image should work:

cosign verify \
  --certificate-identity-regexp '^https://github.com/netboxlabs/netbox-mcp-server/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  netboxlabs/netbox-mcp-server:<tag>

Test plan

  • CI workflows pass on this branch
  • After merge, the next tagged release produces a signed manifest with a provenance attestation at docker.io/netboxlabs/netbox-mcp-server
  • `cosign verify` against a post-release tag returns success

Relates to #83.

🤖 Generated with Claude Code

Adds supply-chain hardening to the Docker Hub publish pipeline introduced
in #132:

- Pin the python:3.14-alpine3.23 base image by digest in both Dockerfile
  stages so a compromised tag cannot substitute the base.
- Sign the published multi-arch manifest with cosign keyless (Sigstore +
  GitHub OIDC) so pullers can verify each image came from this repo's
  Actions.
- Generate SLSA build provenance attestations via
  actions/attest-build-provenance, pushed to the registry alongside the
  manifest, linking any published digest back to the workflow run that
  produced it.
- Document `cosign verify` in the README's Docker Hub section.

Carries over the intent of #127, restructured to fit the matrix-build /
manifest-merge workflow merged in #132. Signing happens once on the
manifest-list digest in the merge job; all aliased tags (latest, X.Y.Z,
X.Y, X) resolve to the same digest, so a single signature covers them.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@abubnalitic-nbl abubnalitic-nbl requested a review from ltucker as a code owner May 7, 2026 21:02
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Vulnerability Scan: Passed

Image: netbox-mcp-server:scan

Source Library CVE Severity Installed Fixed Title
netbox-mcp-server:scan (alpine 3.23.4) xz-libs CVE-2026-34743 🟡 MEDIUM 5.8.2-r0 5.8.3-r0 xz: XZ Utils: Denial of Service via buffer overflow in index decoding
Python Pygments CVE-2026-4539 ⚪ LOW 2.19.2 2.20.0 pygments: Pygments: Denial of Service via inefficient regular expression process
Python pip CVE-2026-6357 🟡 MEDIUM 26.0.1 26.1 pip: pip: Arbitrary code execution or information disclosure via malicious wheel

Commit: 2ec4ce3

@abubnalitic-nbl abubnalitic-nbl merged commit 17f4866 into main May 8, 2026
13 checks passed
@abubnalitic-nbl abubnalitic-nbl deleted the chore/harden-container-publish-dockerhub branch May 8, 2026 13:40
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.

2 participants