Skip to content

DAT-21009: Add Supply Chain Security to Liquibase Secure Docker Images#485

Merged
jandroav merged 3 commits intomainfrom
DAT-21009
Jan 27, 2026
Merged

DAT-21009: Add Supply Chain Security to Liquibase Secure Docker Images#485
jandroav merged 3 commits intomainfrom
DAT-21009

Conversation

@jandroav
Copy link
Contributor

Summary

Adds supply chain security features to Liquibase Secure Docker images for SLSA Level 3 compliance:

  • SBOM generation - Software Bill of Materials attached to images
  • Build provenance - Cryptographic attestation of build process
  • Cosign signing - Keyless image signing via GitHub OIDC

Changes

  • .github/workflows/create-release.yml - Add SBOM, provenance, and Cosign signing for secure images only
  • README.md - Add "Verifying Secure Images" documentation section

Key Details

  • All features apply only to liquibase-secure-release (Community images unchanged)
  • Uses keyless signing with GitHub OIDC (no private keys stored)
  • Signs images on all registries (Docker Hub, GHCR, ECR) based on push flags
  • Skips signing during dry-run mode

Verification Commands

# Verify signature
cosign verify liquibase/liquibase-secure:latest \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  --certificate-identity-regexp="https://github.com/liquibase/docker/.*"

# View SBOM
docker buildx imagetools inspect liquibase/liquibase-secure:latest --format '{{ json .SBOM }}'

# View provenance
docker buildx imagetools inspect liquibase/liquibase-secure:latest --format '{{ json .Provenance }}'

🤖 Generated with Claude Code

@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

📝 Walkthrough

Walkthrough

Adds SBOM and SLSA provenance generation to liquibase-secure builds, installs Cosign, and adds conditional keyless Cosign signing (Docker Hub, GHCR, ECR); updates README with verification instructions for signatures, SBOM, and provenance.

Changes

Cohort / File(s) Summary
CI/CD Supply Chain Security
/.github/workflows/create-release.yml
Enable provenance: true and sbom: true in docker/build-push-action for liquibase-secure-release; add Cosign installer step; add conditional keyless Cosign signing steps per registry (Docker Hub, GHCR, ECR) gated by secure-release and push flags; duplicate signing blocks for alternate workflow path.
Documentation
README.md
Add "Verifying Secure Images" section describing Cosign keyless signature verification, SBOM inspection (docker buildx imagetools inspect), and provenance verification; update Dockerfile snippet to show multiple image reference options; note features apply only to Liquibase Secure images.

Sequence Diagram(s)

sequenceDiagram
  participant GH as "GitHub Actions"
  participant Build as "docker/build-push-action"
  participant Registry as "Container Registry (DockerHub / GHCR / ECR)"
  participant Cosign as "Cosign (sigstore)"

  GH->>Build: trigger secure build (provenance: true, sbom: true)
  Build->>Registry: push image + attach SBOM & provenance
  GH->>Cosign: install cosign (secure release only)
  alt pushDockerHub == true
    GH->>Cosign: keyless sign image (Docker Hub)
    Cosign->>Registry: publish signature / transparency log
  end
  alt pushGHCR == true
    GH->>Cosign: keyless sign image (GHCR)
    Cosign->>Registry: publish signature / transparency log
  end
  alt pushECR == true
    GH->>Cosign: keyless sign image (ECR)
    Cosign->>Registry: publish signature / transparency log
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

type: ci

Suggested reviewers

  • jnewton03
  • sayaliM0412
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding supply chain security features (SBOM, provenance, Cosign signing) to Liquibase Secure Docker images with SLSA Level 3 compliance.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the supply chain security features being added, affected files, implementation approach, and verification commands.
Linked Issues check ✅ Passed The pull request successfully implements all core acceptance criteria from DAT-21009: SBOM and provenance enabled in build-push-action, Cosign installation and keyless signing implemented for secure images only, and README.md updated with verification documentation.
Out of Scope Changes check ✅ Passed All changes are in scope and directly support the DAT-21009 objectives: workflow modifications for SBOM/provenance/signing and README updates for verification instructions; no unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive supply chain security features to Liquibase Secure Docker images to achieve SLSA Level 3 compliance. The implementation includes SBOM generation, build provenance attestations, and keyless image signing using Cosign with GitHub OIDC, ensuring image authenticity and transparency without storing private keys.

Key changes:

  • Supply chain security features (SBOM, provenance, Cosign signing) for secure images only
  • Keyless signing via GitHub OIDC across all registries (Docker Hub, GHCR, ECR)
  • Comprehensive documentation for verifying image authenticity and viewing attestations

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
.github/workflows/create-release.yml Adds Cosign installation, SBOM/provenance generation in build step, and registry-specific signing steps with proper conditionals for secure images only
README.md Adds "Verifying Secure Images" section with command examples for signature verification, SBOM inspection, and provenance viewing

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/create-release.yml (1)

369-369: Critical: Fix typo in AWS credentials reference.

Line 369 and 380 have a typo: steps.configure-aws-credentials-prodoutputs should be steps.configure-aws-credentials-prod.outputs (missing dot after prod).

Apply this diff to fix the typo:

- password: ${{ steps.configure-aws-credentials-prodoutputs.aws_secret_access_key }}
+ password: ${{ steps.configure-aws-credentials-prod.outputs.aws_secret_access_key }}

Also applies to: 380-380

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc25cb and ad9649a.

📒 Files selected for processing (2)
  • .github/workflows/create-release.yml (4 hunks)
  • README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to DockerfileSecure : Docker Secure images should use distinct tagging strategy: Git tag format `v{version}-SECURE` (e.g., `v5.0.1-SECURE`), GitHub Release labeled `v{version}-SECURE`, and Docker image tags `liquibase/liquibase-secure:{version}`, `liquibase/liquibase-secure:{major.minor}`, and `liquibase/liquibase-secure:latest`
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Secure Docker images should be published to Docker Hub as `liquibase/liquibase-secure`, GitHub Container Registry as `ghcr.io/liquibase/liquibase-secure*`, and Amazon ECR Public as `public.ecr.aws/liquibase/liquibase-secure*`
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : Validate Liquibase and LPM binary SHA256 checksums for security in Dockerfile builds
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,docker-compose.yml} : Docker Community images should use distinct tagging strategy: Git tag format `v{version}` (e.g., `v5.0.1`), GitHub Release labeled `v{version}`, and Docker image tags `liquibase/liquibase:{version}`, `liquibase/liquibase:{major.minor}`, and `liquibase/liquibase:latest`
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to DockerfileSecure : Secure Liquibase versions should be sourced from repo.liquibase.com and controlled via `LIQUIBASE_PRO_VERSION` ARG
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to **/Dockerfile* : When extending Secure images, use `FROM liquibase/liquibase-secure:latest` as the base and set `LIQUIBASE_LICENSE_KEY` environment variable
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : When adding tools or runtime dependencies to images, switch to root user, run apt-get operations, and switch back to non-root `liquibase` user in multi-step processes
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to Dockerfile : Community Liquibase versions should be sourced from GitHub releases and controlled via `LIQUIBASE_VERSION` ARG
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Community Docker images should be published to Docker Hub as `liquibase/liquibase`, GitHub Container Registry as `ghcr.io/liquibase/liquibase*`, and Amazon ECR Public as `public.ecr.aws/liquibase/liquibase*`
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to DockerfileSecure : Docker Secure images should use distinct tagging strategy: Git tag format `v{version}-SECURE` (e.g., `v5.0.1-SECURE`), GitHub Release labeled `v{version}-SECURE`, and Docker image tags `liquibase/liquibase-secure:{version}`, `liquibase/liquibase-secure:{major.minor}`, and `liquibase/liquibase-secure:latest`

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Secure Docker images should be published to Docker Hub as `liquibase/liquibase-secure`, GitHub Container Registry as `ghcr.io/liquibase/liquibase-secure*`, and Amazon ECR Public as `public.ecr.aws/liquibase/liquibase-secure*`

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : Validate Liquibase and LPM binary SHA256 checksums for security in Dockerfile builds

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to DockerfileSecure : Secure Liquibase versions should be sourced from repo.liquibase.com and controlled via `LIQUIBASE_PRO_VERSION` ARG

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : When adding tools or runtime dependencies to images, switch to root user, run apt-get operations, and switch back to non-root `liquibase` user in multi-step processes

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,docker-compose.yml} : Docker Community images should use distinct tagging strategy: Git tag format `v{version}` (e.g., `v5.0.1`), GitHub Release labeled `v{version}`, and Docker image tags `liquibase/liquibase:{version}`, `liquibase/liquibase:{major.minor}`, and `liquibase/liquibase:latest`

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to Dockerfile : Community Liquibase versions should be sourced from GitHub releases and controlled via `LIQUIBASE_VERSION` ARG

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to **/Dockerfile* : When extending Secure images, use `FROM liquibase/liquibase-secure:latest` as the base and set `LIQUIBASE_LICENSE_KEY` environment variable

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : LPM (Liquibase Package Manager) version should be specified via `LPM_VERSION` ARG in all Dockerfiles

Applied to files:

  • .github/workflows/create-release.yml
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Community Docker images should be published to Docker Hub as `liquibase/liquibase`, GitHub Container Registry as `ghcr.io/liquibase/liquibase*`, and Amazon ECR Public as `public.ecr.aws/liquibase/liquibase*`

Applied to files:

  • .github/workflows/create-release.yml
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to **/Dockerfile* : When extending Community images, use `FROM liquibase/liquibase:latest` as the base and add database drivers using LPM (e.g., `lpm add mysql --global`)

Applied to files:

  • .github/workflows/create-release.yml
  • README.md
📚 Learning: 2025-11-24T16:48:37.150Z
Learnt from: CR
Repo: liquibase/docker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:48:37.150Z
Learning: Applies to {Dockerfile,DockerfileSecure,Dockerfile.alpine} : Set working directory to `/liquibase` in all Docker images

Applied to files:

  • README.md
🪛 GitHub Check: CodeQL
.github/workflows/create-release.yml

[warning] 322-322: Unpinned tag for a non-immutable Action in workflow
Unpinned 3rd party Action 'Release Extension (v2)' step Uses Step uses 'sigstore/cosign-installer' with ref 'v3', not a pinned commit hash

🔇 Additional comments (4)
.github/workflows/create-release.yml (3)

451-453: SBOM and provenance configuration is correct.

The conditional SBOM and provenance settings properly apply only to liquibase-secure-release images. The provenance mode is set to max for comprehensive SLSA Level 3 compliance.


475-495: Cosign signing steps are properly gated and structured.

The three signing steps (Docker Hub, GHCR, ECR) correctly target only secure releases, respect dry-run flags, and use the digest from the build-and-push step. Assuming the COSIGN_EXPERIMENTAL environment variable is added, the implementation aligns with keyless signing requirements.

Please verify that keyless signing operates correctly with the GitHub OIDC token available in GitHub Actions, once the missing environment variable is added.


475-495: Remove recommendation to add COSIGN_EXPERIMENTAL environment variable — it is obsolete.

As of Cosign 2.0, the COSIGN_EXPERIMENTAL=1 environment variable is no longer required for keyless signing. Keyless signing via GitHub OIDC is enabled by default in modern Cosign releases. The current workflow configuration is correct and does not need modification on this front.

If keyless signing fails at runtime, the issue would be due to missing id-token: write permissions in the job/workflow configuration, not the absence of COSIGN_EXPERIMENTAL.

Likely an incorrect or invalid review comment.

README.md (1)

244-276: Excellent documentation for supply chain security verification.

The new "Verifying Secure Images" section (lines 244-276) is well-structured and provides clear, actionable instructions for verifying image signatures, inspecting SBOMs, and viewing build provenance. The explanation of keyless signing via GitHub OIDC is concise, and the emphasis that these features apply only to Secure images prevents user confusion.

Copy link

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/create-release.yml (1)

399-418: Fix ECR login secret reference typo.

Line 407 and Line 418 reference steps.configure-aws-credentials-prodoutputs... (missing .outputs), which resolves to an empty password and breaks ECR login (both normal and dry-run).

🛠️ Proposed fix
-          password: ${{ steps.configure-aws-credentials-prodoutputs.aws_secret_access_key }}
+          password: ${{ steps.configure-aws-credentials-prod.outputs.aws_secret_access_key }}
...
-          password: ${{ steps.configure-aws-credentials-prodoutputs.aws_secret_access_key }}
+          password: ${{ steps.configure-aws-credentials-prod.outputs.aws_secret_access_key }}

Copy link

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/create-release.yml (1)

405-408: Pre-existing typo will cause ECR login to fail.

Line 407 has steps.configure-aws-credentials-prodoutputs.aws_secret_access_key — there's a missing dot between prod and outputs. This same typo appears at line 418. While not introduced by this PR, it will cause ECR login failures which would also prevent the new ECR signing step from working.

🐛 Recommended fix
-          password: ${{ steps.configure-aws-credentials-prodoutputs.aws_secret_access_key }}
+          password: ${{ steps.configure-aws-credentials-prod.outputs.aws_secret_access_key }}

Apply the same fix at line 418.

jandroav and others added 2 commits January 26, 2026 14:41
Add SBOM generation, SLSA Level 3 provenance attestation, and Cosign
keyless image signing for Liquibase Secure Docker images only.

Changes:
- Add SBOM and provenance to docker/build-push-action for secure images
- Install Cosign and sign images on Docker Hub, GHCR, and ECR
- Add "Verifying Secure Images" documentation to README.md

Community images remain unchanged.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pin sigstore/cosign-installer to specific commit hash for improved
security by preventing potential supply chain attacks through
unpinned action references.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@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: 1

🤖 Fix all issues with AI agents
In @.github/workflows/create-release.yml:
- Around line 511-533: The signing steps ("Sign Docker Hub Image with Cosign",
"Sign GHCR Image with Cosign", "Sign ECR Image with Cosign") are missing the
same releaseType == matrix.type guard used by the build step; update each step's
if condition to include the releaseType equality check so signing only runs when
the build ran (e.g. change each if to: ${{ matrix.type ==
'liquibase-secure-release' && needs.update-dockerfiles.outputs.dryRun == 'false'
&& env.PUSH_* == 'true' && env.releaseType == matrix.type }} using the
appropriate PUSH_DOCKERHUB / PUSH_GHCR / PUSH_ECR variable).

Add releaseType == matrix.type condition to Cosign signing steps to
ensure they only run when the corresponding build step actually
executed. This prevents signing steps from attempting to run with
empty digests during community releases where the secure build job
is skipped.

Addresses CodeRabbit review feedback on PR #485.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 27, 2026

Claude finished @jandroav's task in 1m 2s —— View job


Review Complete

I've reviewed the PR changes focusing on critical issues. The implementation is correct and well-structured.

Review Progress

  • Examine PR diff for changed lines
  • Review workflow changes
  • Review README changes
  • Post review feedback

Findings

Supply Chain Security Implementation - All Good ✅

The implementation correctly adds SBOM, provenance, and Cosign signing for Liquibase Secure images:

  1. Cosign Installation (line 360): Correctly pinned to commit hash faadad0cce49287aee09b3a48701e75088a2c6ad (v4.0.0) for supply chain security
  2. SBOM & Provenance (lines 490-491): Properly gated to secure images only with mode=max for SLSA Level 3
  3. Signing Steps (lines 513-532): Correctly conditional on:
    • liquibase-secure-release type
    • dryRun == 'false'
    • Registry-specific push flags (PUSH_DOCKERHUB, PUSH_GHCR, PUSH_ECR)
  4. Build Output (line 479): Added id: build-and-push to capture digest for signing
  5. Permissions (line 6): Workflow has required id-token: write for OIDC keyless signing
  6. README Documentation (lines 244-276): Clear, accurate documentation with all verification commands

Previous Review Findings Addressed:

  • ✅ Cosign action is now pinned to commit hash (addressed in commit 77e38e6)
  • ✅ ECR credentials are correctly referenced at lines 407 and 418 (no typo found in current code)

Verdict

LGTM - No critical issues found. The supply chain security implementation is correct and follows best practices.


@liquibase liquibase deleted a comment from claude bot Jan 27, 2026
@liquibase liquibase deleted a comment from claude bot Jan 27, 2026
@liquibase liquibase deleted a comment from claude bot Jan 27, 2026
@jandroav jandroav merged commit 41d6b86 into main Jan 27, 2026
8 checks passed
@jandroav jandroav deleted the DAT-21009 branch January 27, 2026 04:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants