Skip to content

Commit 980c2fa

Browse files
sxdfcanovaigbartolini
authored
feat: add cosign to sign the images (#137)
Using the output from the bake action, we sign every container image tag plus each specific digest using cosign. Closes #136 Signed-off-by: Francesco Canovai <[email protected]> Signed-off-by: Jonathan Gonzalez V <[email protected]> Signed-off-by: Gabriele Bartolini <[email protected]> Co-authored-by: Francesco Canovai <[email protected]> Co-authored-by: Gabriele Bartolini <[email protected]>
1 parent 588f8dc commit 980c2fa

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

.github/workflows/bake.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ on:
1212
- production
1313
default: testing
1414
description: "Choose the environment to bake the images for"
15+
target:
16+
type: string
17+
default: ""
18+
description: "A comma separated list of targets to build. If empty, all targets will be built."
1519

1620
jobs:
1721
# Start by building images for testing. We want to run security checks before pushing those to production.
@@ -22,6 +26,8 @@ jobs:
2226
contents: read
2327
packages: write
2428
security-events: write
29+
# Required by the cosign step
30+
id-token: write
2531
outputs:
2632
metadata: ${{ steps.build.outputs.metadata }}
2733
images: ${{ steps.images.outputs.images }}
@@ -55,13 +61,26 @@ jobs:
5561
revision: ${{ github.sha }}
5662
with:
5763
push: true
64+
targets: ${{ github.event.inputs.target }}
5865

5966
# Get a list of the images that were built and pushed. We only care about a single tag for each image.
6067
- name: Generated images
6168
id: images
6269
run: |
6370
echo "images=$(echo '${{ steps.build.outputs.metadata }}' | jq -c '[ .[]."image.name" | sub(",.*";"") ]')" >> "$GITHUB_OUTPUT"
6471
72+
# Even if we're testing we sign the images, so we can push them to production later if that's required
73+
- name: Install cosign
74+
uses: sigstore/cosign-installer@v3
75+
# See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/
76+
# and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on
77+
# how to use cosign.
78+
- name: Sign images
79+
run: |
80+
echo '${{ steps.build.outputs.metadata }}' | \
81+
jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"' | \
82+
xargs cosign sign --yes
83+
6584
security:
6685
name: Security checks
6786
runs-on: ubuntu-latest
@@ -144,3 +163,15 @@ jobs:
144163
revision: ${{ github.sha }}
145164
with:
146165
push: true
166+
167+
- name: Install cosign
168+
uses: sigstore/cosign-installer@v3
169+
# See https://github.blog/security/supply-chain-security/safeguard-container-signing-capability-actions/
170+
# and https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml for more details on
171+
# how to use cosign.
172+
- name: Sign images
173+
run: |
174+
images=$(echo '${{ steps.build.outputs.metadata }}' |
175+
jq '.[] | (."image.name" | sub(",.*";"" )) + "@" + ."containerimage.digest"'
176+
)
177+
cosign sign --yes ${images}

BUILD.md

+7
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ docker run -d --rm -p 5000:5000 --name registry registry:2
122122
This command runs a lightweight, temporary instance of the `registry:2`
123123
container on port `5000`.
124124

125+
## Image Signing Workflow
126+
127+
Postgres operand images are securely signed with [cosign](https://github.com/sigstore/cosign)
128+
based on their digest through a GitHub workflow, using the
129+
[`cosign-installer` action](https://github.com/marketplace/actions/cosign-installer), which leverages
130+
[short-lived tokens issued through OpenID Connect](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
131+
125132
## Trademarks
126133

127134
*[Postgres, PostgreSQL and the Slonik Logo](https://www.postgresql.org/about/policies/trademarks/)

README.md

+23
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,29 @@ docker buildx imagetools inspect <IMAGE> --format "{{ json .SBOM.SPDX }}"
118118
This command outputs the SBOM in JSON format, providing a detailed view of the
119119
software components and build dependencies.
120120

121+
## Image Signatures
122+
123+
CloudNativePG container images are securely signed using
124+
[cosign](https://github.com/sigstore/cosign), a tool within the
125+
[Sigstore](https://www.sigstore.dev/) ecosystem.
126+
This signing process is automated via GitHub Actions and leverages
127+
[short-lived tokens issued through OpenID Connect](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
128+
129+
The token issuer is `https://token.actions.githubusercontent.com`, and the
130+
signing identity corresponds to a GitHub workflow executed under the
131+
`cloudnative-pg/postgres-containers` repository. This workflow uses the
132+
[`cosign-installer` action](https://github.com/marketplace/actions/cosign-installer)
133+
to facilitate the signing process.
134+
135+
To verify the authenticity of an image using its digest, you can run the
136+
following `cosign` command:
137+
138+
```sh
139+
cosign verify IMAGE \
140+
--certificate-identity-regexp="^https://github.com/cloudnative-pg/postgres-containers/" \
141+
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
142+
```
143+
121144
## Building Images
122145

123146
For detailed instructions on building PostgreSQL container images, refer to the

0 commit comments

Comments
 (0)