Skip to content

Supply chain hardening: Docker image cosigning, dependency lockdown, and CI pinning#365

Open
OlivierTrudeau wants to merge 3 commits into
mainfrom
cosign
Open

Supply chain hardening: Docker image cosigning, dependency lockdown, and CI pinning#365
OlivierTrudeau wants to merge 3 commits into
mainfrom
cosign

Conversation

@OlivierTrudeau
Copy link
Copy Markdown
Contributor

@OlivierTrudeau OlivierTrudeau commented May 4, 2026

Summary

  • Docker image cosigning: Sign all GHCR images (aurora-server, aurora-frontend) with Sigstore cosign keyless signing in publish-images.yml after multi-arch manifest creation. Sign Helm chart OCI artifacts in publish-helm.yml using cosign + crane for digest resolution.
  • Dependency lockdown: Enforce --frozen-lockfile --ignore-scripts in the production Dockerfile builder stage to prevent lockfile drift and block postinstall hook attacks (axios RAT vector). Add client/.npmrc with ignore-scripts=true for local dev parity.
  • Signature verification: make prod-prebuilt and make deploy verify image signatures before running, failing hard if cosign detects invalid or missing signatures. Verification logic centralized in scripts/cosign-verify.sh.
  • Makefile improvements: Decouple make deploy from deploy-build so K8s deployments can use prebuilt images. Add --no-build to make prod-prebuilt to prevent accidental rebuilds. Add cosign signing to make deploy-build for self-hosted registry pushes.
  • Documentation: New image-verification.md docs page covering manual verification, automatic Makefile verification, and Sigstore policy-controller setup for K8s runtime enforcement.

All GitHub Actions (existing and newly added) are pinned by full commit SHA.

Test plan

  • docker build --target builder -f client/Dockerfile ./client succeeds with synced lockfile
  • docker build fails with --frozen-lockfile when lockfile is out of sync
  • bun install in client/ skips postinstall scripts (.npmrc)
  • scripts/cosign-verify.sh exits 1 on unsigned images
  • scripts/cosign-verify.sh warns and exits 0 when cosign is not installed
  • website/ docs build succeeds with new page
  • publish-images.yml cosign signing succeeds (trigger workflow_dispatch on this branch)
  • cosign verify succeeds locally after CI signing completes
  • publish-helm.yml signing (verified on first v*.*.* tag after merge)

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Container images and Helm charts are now cryptographically signed using Sigstore Cosign with keyless OIDC signing.
    • Deployment process automatically verifies signatures before installation; verification failures abort deployment.
    • Added comprehensive documentation for manual and automated artifact signature verification.
  • Chores

    • Enhanced build consistency with frozen lockfile constraints and script isolation.

@OlivierTrudeau OlivierTrudeau requested a review from a team as a code owner May 4, 2026 19:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Warning

Rate limit exceeded

@OlivierTrudeau has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 18 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: cffca40d-ddd2-46d1-9155-2f55e6e90672

📥 Commits

Reviewing files that changed from the base of the PR and between b7f3afc and 44830f5.

📒 Files selected for processing (1)
  • .github/workflows/publish-images.yml

Walkthrough

This PR introduces cryptographic image signature verification for Aurora's container artifacts using Sigstore Cosign. CI workflows now sign published images and Helm charts after pushing to GHCR, a new verification script validates signatures during deployment, and the Makefile orchestrates signing/verification in build and deployment flows. Documentation describes manual and automatic verification, plus Kubernetes policy enforcement.

Changes

Image Signing and Verification System

Layer / File(s) Summary
CI Permissions
.github/workflows/publish-helm.yml, .github/workflows/publish-images.yml
Both workflows grant id-token: write permission to support Cosign's OIDC-based keyless signing.
Cosign Installation & Signing in Publish Workflows
.github/workflows/publish-helm.yml, .github/workflows/publish-images.yml
Workflows install cosign-installer and sign OCI artifacts (Helm chart and Docker images) using computed digests after push to GHCR.
Signature Verification Script
scripts/cosign-verify.sh
New Bash script verifies Cosign signatures against expected certificate identity and OIDC issuer; exits cleanly if Cosign is unavailable.
Build Reproducibility
client/.npmrc, client/Dockerfile
Client dependencies install with --frozen-lockfile and --ignore-scripts to ensure deterministic builds and prevent lifecycle script execution.
Deployment Integration
Makefile
deploy-build target now computes image digests and signs with Cosign; prod-prebuilt verifies signatures before startup; deploy target verifies all image signatures before Helm installation.
Documentation & Navigation
website/docs/deployment/image-verification.md, website/sidebars.ts
New deployment guide covers manual Cosign verification, automatic verification via Makefile, and Kubernetes runtime policy enforcement with policy-controller. Sidebar entry added.

Sequence Diagram

sequenceDiagram
    participant CI as GitHub Actions
    participant GHCR as Container Registry<br/>(GHCR)
    participant Cosign as Sigstore Cosign
    participant Local as Local Build/Deploy
    participant K8s as Kubernetes

    CI->>GHCR: Build & Push Images
    CI->>Cosign: Sign Image Digest (OIDC)
    Cosign-->>GHCR: Signature Stored
    
    Local->>GHCR: Pull Signed Images
    Local->>Cosign: Verify Signatures
    Cosign-->>Local: ✓ Verified
    Local->>K8s: Deploy via Helm
    
    Local->>Local: Build Images Locally
    Local->>Cosign: Sign Local Images
    Cosign-->>Local: ✓ Signed
    Local->>K8s: Deploy via Helm
    
    K8s->>Cosign: (Optional) Enforce Signatures<br/>via policy-controller
    Cosign-->>K8s: ✓ Admission Allowed
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Arvo-AI/aurora#238: Extends the Helm OCI publish job by adding Cosign installation and signing of pushed chart digests.
  • Arvo-AI/aurora#239: Modifies publish-images.yml and the Makefile deploy-build flow; this PR layers Cosign signing and verification into that publishing pipeline.

Suggested reviewers

  • isiddharthsingh
  • Zarlanx

Poem

🐰 A rabbit hops through signed containers bright,
With Cosign keys that verify each site,
No tampered images shall pass the gate,
Sigstore keeps our deployments great! ✨🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main objectives of the changeset: Docker image cosigning, dependency lockdown, and CI pinning for supply chain hardening.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cosign

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 6 minutes and 18 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/publish-images.yml:
- Around line 227-234: The workflow inspects the bare IMAGE_NAME (which defaults
to :latest) and thus grabs the wrong manifest; change the docker buildx
imagetools inspect call that sets DIGEST to target the explicitly tagged image
reference used when pushing (the same image reference used in the "Inspect and
verify multi-arch manifest" step) instead of the bare IMAGE_NAME, so that DIGEST
reflects the newly created tag (e.g., inspect "${IMAGE_NAME}:${IMAGE_TAG}" or
the exact image variable from the earlier push), and keep the cosign sign
invocation using "${IMAGE_NAME}@${DIGEST}" so cosign signs the correct manifest.

In `@Makefile`:
- Around line 341-345: The deploy-build → deploy failure is because cosign
keyless signatures produced locally don’t match the GitHub Actions OIDC
issuer/identity restrictions enforced by scripts/cosign-verify.sh; either make
signing CI-only by gating the cosign sign steps in the Makefile (the cosign sign
lines for aurora-server, aurora-frontend, aurora-terminal under deploy-build) so
they only run when GITHUB_ACTIONS (or another CI-only env flag) is true, or add
a local signing path and verification policy: create a separate local-sign
branch in the Makefile (e.g., deploy-build-local) and/or a second verification
mode in scripts/cosign-verify.sh that accepts a local issuer/identity-regexp or
a SKIP_LOCAL_VERIFICATION flag, and update deploy to choose the appropriate
verification path based on the same CI/local flag.
- Around line 339-345: The Makefile currently computes SERVER_DIGEST,
FRONTEND_DIGEST, and TERMINAL_DIGEST by hashing the raw manifest bytes which can
include an extra newline; instead, query the registry for the canonical digest
and use that for cosign. Replace the docker buildx imagetools inspect --raw |
sha256sum pipeline for SERVER_DIGEST, FRONTEND_DIGEST and TERMINAL_DIGEST with a
direct lookup such as docker buildx imagetools inspect IMAGE:TAG --format
'{{.Manifest.Digest}}' (or crane digest IMAGE:TAG) to set those variables before
calling cosign sign --yes IMAGE@$$SERVER_DIGEST (and the frontend/terminal
equivalents).

In `@scripts/cosign-verify.sh`:
- Around line 11-14: The script currently exits 0 when cosign is missing which
silently bypasses verification; change this to fail closed by exiting non-zero
unless an explicit opt-out is provided (e.g., an env var SKIP_COSIGN=true or a
--allow-unverified/--skip-cosign flag). Update the cosign presence check (the if
! command -v cosign ... block) to: 1) detect an opt-out (check $SKIP_COSIGN or
parse a --skip-cosign flag), 2) if no opt-out, print a clear error and exit with
a non-zero status, and 3) if opt-out is present, print a conspicuous warning
including why it is unsafe and proceed. Ensure all messages reference cosign and
the opt-out variable/flag so callers can audit the behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 17cbb153-4d25-4f7b-b0c5-1a76a93ef5c2

📥 Commits

Reviewing files that changed from the base of the PR and between e4f7f73 and b7f3afc.

⛔ Files ignored due to path filters (1)
  • client/bun.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (8)
  • .github/workflows/publish-helm.yml
  • .github/workflows/publish-images.yml
  • Makefile
  • client/.npmrc
  • client/Dockerfile
  • scripts/cosign-verify.sh
  • website/docs/deployment/image-verification.md
  • website/sidebars.ts

Comment thread .github/workflows/publish-images.yml Outdated
Comment thread Makefile
Comment on lines +339 to +345
SERVER_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-server:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
FRONTEND_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-frontend:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
cosign sign --yes $$IMAGE_REGISTRY/aurora-server@$$SERVER_DIGEST; \
cosign sign --yes $$IMAGE_REGISTRY/aurora-frontend@$$FRONTEND_DIGEST; \
if [ "$$ENABLE_POD_ISOLATION" = "true" ]; then \
TERMINAL_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-terminal:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
cosign sign --yes $$IMAGE_REGISTRY/aurora-terminal@$$TERMINAL_DIGEST; \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Is the SHA256 of docker buildx imagetools inspect --raw IMAGE:TAGoutput guaranteed to equal the registry manifest digest, or shoulddocker buildx imagetools inspect IMAGE:TAG --format '{{.Manifest.Digest}}'/crane digest be used when signing with Cosign?

💡 Result:

No, the SHA256 of docker buildx imagetools inspect --raw IMAGE:TAG output is not guaranteed to equal the registry manifest digest. The --raw flag outputs the original unformatted JSON manifest bytes fetched from the registry, but the command may add a trailing newline character when printing to stdout. This extra byte alters the hash, making a direct SHA256 (e.g., sha256sum) mismatch the true registry digest. To reliably obtain the exact registry manifest digest: - Use docker buildx imagetools inspect IMAGE:TAG --format '{{.Manifest.Digest}}' (computes and displays the digest directly). - Or crane digest IMAGE:TAG (fetches via HEAD or GET and returns the precise SHA256 digest). For Cosign signing, use one of these digest commands, as Cosign requires the exact registry manifest digest (e.g., cosign sign IMAGE@sha256:digest). Relying on hashing --raw output risks incorrect digests due to the potential trailing newline, as noted in Docker Buildx issue #181 where developers recommend stripping it (e.g., docker buildx imagetools inspect --raw IMAGE | perl -pe 'chomp if eof' | sha256sum).

Citations:


Replace manifest digest derivation with direct registry lookup.

Lines 339-345 compute digests by piping docker buildx imagetools inspect --raw output to sha256sum. This approach is unreliable: the --raw flag outputs manifest JSON bytes, but a trailing newline is appended when writing to stdout. This extra byte changes the hash, causing it to diverge from the actual registry manifest digest. Cosign would then sign a non-existent digest.

Use docker buildx imagetools inspect IMAGE:TAG --format '{{.Manifest.Digest}}' to retrieve the digest directly from the registry (or alternatively, crane digest IMAGE:TAG).

Suggested fix
-	SERVER_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-server:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
-	FRONTEND_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-frontend:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
+	SERVER_DIGEST=$$(docker buildx imagetools inspect $$IMAGE_REGISTRY/aurora-server:$$GIT_SHA --format '{{.Manifest.Digest}}'); \
+	FRONTEND_DIGEST=$$(docker buildx imagetools inspect $$IMAGE_REGISTRY/aurora-frontend:$$GIT_SHA --format '{{.Manifest.Digest}}'); \
 	cosign sign --yes $$IMAGE_REGISTRY/aurora-server@$$SERVER_DIGEST; \
 	cosign sign --yes $$IMAGE_REGISTRY/aurora-frontend@$$FRONTEND_DIGEST; \
 	if [ "$$ENABLE_POD_ISOLATION" = "true" ]; then \
-		TERMINAL_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-terminal:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
+		TERMINAL_DIGEST=$$(docker buildx imagetools inspect $$IMAGE_REGISTRY/aurora-terminal:$$GIT_SHA --format '{{.Manifest.Digest}}'); \
 		cosign sign --yes $$IMAGE_REGISTRY/aurora-terminal@$$TERMINAL_DIGEST; \
 	fi; \
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 339 - 345, The Makefile currently computes
SERVER_DIGEST, FRONTEND_DIGEST, and TERMINAL_DIGEST by hashing the raw manifest
bytes which can include an extra newline; instead, query the registry for the
canonical digest and use that for cosign. Replace the docker buildx imagetools
inspect --raw | sha256sum pipeline for SERVER_DIGEST, FRONTEND_DIGEST and
TERMINAL_DIGEST with a direct lookup such as docker buildx imagetools inspect
IMAGE:TAG --format '{{.Manifest.Digest}}' (or crane digest IMAGE:TAG) to set
those variables before calling cosign sign --yes IMAGE@$$SERVER_DIGEST (and the
frontend/terminal equivalents).

Comment thread Makefile
Comment on lines +341 to +345
cosign sign --yes $$IMAGE_REGISTRY/aurora-server@$$SERVER_DIGEST; \
cosign sign --yes $$IMAGE_REGISTRY/aurora-frontend@$$FRONTEND_DIGEST; \
if [ "$$ENABLE_POD_ISOLATION" = "true" ]; then \
TERMINAL_DIGEST=$$(docker buildx imagetools inspect --raw $$IMAGE_REGISTRY/aurora-terminal:$$GIT_SHA | sha256sum | awk '{print "sha256:"$$1}'); \
cosign sign --yes $$IMAGE_REGISTRY/aurora-terminal@$$TERMINAL_DIGEST; \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🌐 Web query:

When cosign sign --yes IMAGE@DIGESTis run locally outside GitHub Actions, what certificate issuer and subject are embedded in the Fulcio certificate? Willcosign verify --certificate-identity-regexp='https://github.com/Arvo-AI/aurora/.*' --certificate-oidc-issuer='https://token.actions.githubusercontent.com' IMAGE:TAG accept those locally generated signatures?

💡 Result:

Certificate embedded in the Fulcio (keyless) certificate when you run cosign sign --yes IMAGE@DIGEST locally: 1) Certificate issuer - The OIDC token issuer (“iss” in the OIDC JWT) is embedded/checked via Fulcio’s certificate custom field, and for GitHub Actions workloads it is https://token.actions.githubusercontent.com. 2) Certificate subject - For GitHub Actions, the subject is the workflow identity URI placed into the certificate’s Subject Alternative Name (SAN) as a URI, of the form: https://github.com///.github/workflows/<WORKFLOW_FILE>@refs/heads/ (Fulcio includes the GitHub Actions workflow identity in the certificate SAN.) Will cosign verify --certificate-identity-regexp='https://github.com/Arvo-AI/aurora/.*' --certificate-oidc-issuer='https://token.actions.githubusercontent.com' accept those locally generated signatures? - Yes, provided the locally generated signature was created using a GitHub Actions OIDC identity with certificate-oidc-issuer https://token.actions.githubusercontent.com and its certificate SAN subject matches the GitHub workflow-identity URI pattern. Key caveat about “locally outside GitHub Actions” - Running cosign locally does not inherently mint a GitHub Actions OIDC token; cosign obtains an OIDC identity token from ambient providers or from configured flags/tokens. Therefore, if the OIDC token used locally is not a GitHub Actions token (i.e., its iss is not https://token.actions.githubusercontent.com), the resulting Fulcio certificate will not have that issuer and cosign verify with --certificate-oidc-issuer=https://token.actions.githubusercontent.com will fail. What you should check - Inspect the certificate identity/issuer in the verification output or by running cosign verify with verbose/identity flags; the SAN URI subject and issuer must match the expectations above.

Citations:


🏁 Script executed:

# Check the Makefile to understand the deploy-build and deploy targets
git ls-files | grep -i makefile

Repository: Arvo-AI/aurora

Length of output: 67


🏁 Script executed:

# Read the relevant sections of the Makefile
sed -n '330,370p' Makefile

Repository: Arvo-AI/aurora

Length of output: 2356


🏁 Script executed:

# Check if cosign-verify.sh exists and examine its verification policy
find . -name "cosign-verify.sh" -type f 2>/dev/null

Repository: Arvo-AI/aurora

Length of output: 85


🏁 Script executed:

# Read the cosign-verify.sh script
cat -n scripts/cosign-verify.sh

Repository: Arvo-AI/aurora

Length of output: 1390


deploy-builddeploy flow will fail for local execution.

The deploy-build target signs images with cosign sign --yes, but immediately afterward, the deploy target runs scripts/cosign-verify.sh which enforces verification against GitHub Actions OIDC (https://token.actions.githubusercontent.com) and GitHub workflow identity patterns only.

When cosign signs locally outside GitHub Actions, it obtains an OIDC token from a different provider/context, producing a Fulcio certificate with a different issuer and subject. The verification in cosign-verify.sh (lines 26–27) will reject these locally-signed images:

--certificate-identity-regexp="https://github.com/Arvo-AI/aurora/.*"
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"

Choose one model: either make deploy-build CI-only (run signing in GitHub Actions exclusively), or add a separate local signing path with its own verification policy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 341 - 345, The deploy-build → deploy failure is
because cosign keyless signatures produced locally don’t match the GitHub
Actions OIDC issuer/identity restrictions enforced by scripts/cosign-verify.sh;
either make signing CI-only by gating the cosign sign steps in the Makefile (the
cosign sign lines for aurora-server, aurora-frontend, aurora-terminal under
deploy-build) so they only run when GITHUB_ACTIONS (or another CI-only env flag)
is true, or add a local signing path and verification policy: create a separate
local-sign branch in the Makefile (e.g., deploy-build-local) and/or a second
verification mode in scripts/cosign-verify.sh that accepts a local
issuer/identity-regexp or a SKIP_LOCAL_VERIFICATION flag, and update deploy to
choose the appropriate verification path based on the same CI/local flag.

Comment thread scripts/cosign-verify.sh
Comment on lines +11 to +14
if ! command -v cosign >/dev/null 2>&1; then
echo "WARNING: cosign not installed, skipping signature verification."
echo "Install cosign to verify image provenance: https://docs.sigstore.dev/cosign/system_config/installation/"
exit 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't silently bypass verification when cosign is missing.

These deployment paths are presented as enforcement, but this block returns success when the verifier is absent. That makes "don't install cosign" an easy bypass for the new supply-chain check. Fail closed here, or require an explicit opt-out flag for unverified deployments.

Suggested fix
 if ! command -v cosign >/dev/null 2>&1; then
-    echo "WARNING: cosign not installed, skipping signature verification."
-    echo "Install cosign to verify image provenance: https://docs.sigstore.dev/cosign/system_config/installation/"
-    exit 0
+    if [ "${ALLOW_UNVERIFIED_IMAGES:-0}" = "1" ]; then
+        echo "WARNING: cosign not installed, skipping signature verification."
+        exit 0
+    fi
+    echo "ERROR: cosign is required for image signature verification." >&2
+    exit 1
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ! command -v cosign >/dev/null 2>&1; then
echo "WARNING: cosign not installed, skipping signature verification."
echo "Install cosign to verify image provenance: https://docs.sigstore.dev/cosign/system_config/installation/"
exit 0
if ! command -v cosign >/dev/null 2>&1; then
if [ "${ALLOW_UNVERIFIED_IMAGES:-0}" = "1" ]; then
echo "WARNING: cosign not installed, skipping signature verification."
exit 0
fi
echo "ERROR: cosign is required for image signature verification." >&2
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/cosign-verify.sh` around lines 11 - 14, The script currently exits 0
when cosign is missing which silently bypasses verification; change this to fail
closed by exiting non-zero unless an explicit opt-out is provided (e.g., an env
var SKIP_COSIGN=true or a --allow-unverified/--skip-cosign flag). Update the
cosign presence check (the if ! command -v cosign ... block) to: 1) detect an
opt-out (check $SKIP_COSIGN or parse a --skip-cosign flag), 2) if no opt-out,
print a clear error and exit with a non-zero status, and 3) if opt-out is
present, print a conspicuous warning including why it is unsafe and proceed.
Ensure all messages reference cosign and the opt-out variable/flag so callers
can audit the behavior.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

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