Skip to content

Commit 7714fa3

Browse files
jiparisjavirln
andauthored
feat(workflows): attest all release artifacts at build time (#1743)
Signed-off-by: Javier Rodriguez <[email protected]> Signed-off-by: Jose I. Paris <[email protected]> Co-authored-by: Javier Rodriguez <[email protected]>
1 parent 9c18c11 commit 7714fa3

File tree

4 files changed

+124
-84
lines changed

4 files changed

+124
-84
lines changed

.github/workflows/build_and_package.yaml

Lines changed: 104 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,31 @@ jobs:
1313
test:
1414
uses: chainloop-dev/chainloop/.github/workflows/test.yml@main
1515

16+
init_attestation:
17+
runs-on: ubuntu-latest
18+
needs: test
19+
if: github.ref_type == 'tag' # Guard to make sure we are releasing once
20+
outputs:
21+
attestation_id: ${{ steps.init_attestation.outputs.attestation_id }}
22+
steps:
23+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
24+
- name: Install Chainloop
25+
run: |
26+
curl -sfL https://docs.chainloop.dev/install.sh | bash -s
27+
28+
- name: Initialize Attestation
29+
id: init_attestation
30+
run: |
31+
attestation_id=$(chainloop attestation init --workflow ${CHAINLOOP_WORKFLOW_NAME} --project ${CHAINLOOP_PROJECT_NAME} --release --remote-state -o json | jq -r .attestationID)
32+
echo "attestation_id=$attestation_id" >> $GITHUB_OUTPUT
33+
env:
34+
CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }}
35+
CHAINLOOP_WORKFLOW_NAME: "chainloop-vault-build-and-package"
36+
CHAINLOOP_PROJECT_NAME: "chainloop"
37+
1638
release:
1739
name: Release CLI and control-plane/artifact-cas container images
18-
needs: test
40+
needs: init_attestation
1941
runs-on: ubuntu-latest
2042
if: github.ref_type == 'tag' # Guard to make sure we are releasing once
2143
permissions:
@@ -24,12 +46,10 @@ jobs:
2446
pull-requests: write
2547
env:
2648
CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }}
27-
CONTAINER_IMAGE_CP: ghcr.io/chainloop-dev/chainloop/control-plane:${{ github.ref_name }}
28-
CONTAINER_IMAGE_CAS: ghcr.io/chainloop-dev/chainloop/artifact-cas:${{ github.ref_name }}
29-
CONTAINER_IMAGE_CLI: ghcr.io/chainloop-dev/chainloop/cli:${{ github.ref_name }}
30-
GH_TOKEN: ${{ github.token }}
31-
CHAINLOOP_WORKFLOW_NAME: "chainloop-vault-build-and-package"
32-
CHAINLOOP_PROJECT: "chainloop"
49+
ATTESTATION_ID: ${{ needs.init_attestation.outputs.attestation_id }}
50+
outputs:
51+
matrix: ${{ steps.attest_goreleaser.outputs.matrix }}
52+
3353
steps:
3454
- name: Install Cosign
3555
uses: sigstore/cosign-installer@ef6a6b364bbad08abd36a5f8af60b595d12702f8 # main
@@ -38,21 +58,11 @@ jobs:
3858

3959
- name: Install Chainloop
4060
run: |
41-
curl -sfL https://raw.githubusercontent.com/chainloop-dev/chainloop/01ad13af08950b7bfbc83569bea207aeb4e1a285/docs/static/install.sh | bash -s
42-
43-
- name: Download jq
44-
run: |
45-
sudo wget -q https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O /usr/local/bin/jq
46-
sudo chmod u+x /usr/local/bin/jq
61+
curl -sfL https://docs.chainloop.dev/install.sh | bash -s
4762
4863
- name: Checkout
4964
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
5065

51-
# mark this attestation as a release
52-
- name: Initialize Attestation
53-
run: |
54-
chainloop attestation init --workflow $CHAINLOOP_WORKFLOW_NAME --project $CHAINLOOP_PROJECT --release
55-
5666
- name: Docker login to Github Packages
5767
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
5868
with:
@@ -84,40 +94,19 @@ jobs:
8494
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
8595
POSTHOG_ENDPOINT: ${{ secrets.POSTHOG_ENDPOINT }}
8696

87-
- uses: anchore/sbom-action@c6aed38a4323b393d05372c58a74c39ae8386d02 # v0.15.6
88-
with:
89-
image: ${{ env.CONTAINER_IMAGE_CP }}
90-
format: cyclonedx-json
91-
artifact-name: controlplane.cyclonedx.json
92-
output-file: /tmp/sbom.cp.cyclonedx.json
93-
94-
- uses: anchore/sbom-action@c6aed38a4323b393d05372c58a74c39ae8386d02 # v0.15.6
95-
with:
96-
image: ${{ env.CONTAINER_IMAGE_CAS }}
97-
format: cyclonedx-json
98-
artifact-name: cas.cyclonedx.json
99-
output-file: /tmp/sbom.cas.cyclonedx.json
100-
101-
- uses: anchore/sbom-action@c6aed38a4323b393d05372c58a74c39ae8386d02 # v0.15.6
102-
with:
103-
image: ${{ env.CONTAINER_IMAGE_CLI }}
104-
format: cyclonedx-json
105-
artifact-name: cli.cyclonedx.json
106-
output-file: /tmp/sbom.cli.cyclonedx.json
107-
108-
- name: Add Attestation from Goreleaser Output
109-
run: |
110-
jq -r . <<< '${{ steps.release.outputs.artifacts }}' > /tmp/artifacts.json
111-
chainloop attestation add --name goreleaser-output --value /tmp/artifacts.json
112-
113-
- name: Finish and Record Attestation
114-
if: ${{ success() }}
97+
- name: Attest GoReleaser outputs
98+
id: attest_goreleaser
11599
run: |
116-
chainloop attestation status --full
117-
chainloop attestation push --key env://CHAINLOOP_SIGNING_KEY
118-
env:
119-
CHAINLOOP_SIGNING_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
120-
CHAINLOOP_SIGNING_KEY: ${{ secrets.COSIGN_KEY }}
100+
# goreleaser output resides in dist/artifacts.json
101+
# Attest all built containers and manifests
102+
images=$(cat dist/artifacts.json | jq -r '[.[] | select(.type=="Docker Image" or .type=="Docker Manifest") | {"type": "image", "path": .path}]')
103+
104+
# Attest CLI archives
105+
archives=$(cat dist/artifacts.json | jq -r '[.[] | select(.type=="Archive") | {"type": "archive", "path": .path}]')
106+
107+
# convert them to json and join arrays
108+
artifacts_json=$(jq -c -s 'add' <(echo "$images") <(echo "$archives"))
109+
echo "matrix=$artifacts_json" >> $GITHUB_OUTPUT
121110
122111
- name: Bump Chart and Dagger Version
123112
run: .github/workflows/utils/bump-chart-and-dagger-version.sh deployment/chainloop extras/dagger ${{ github.ref_name }}
@@ -137,14 +126,76 @@ jobs:
137126
automated
138127
helm
139128
129+
generate_sboms_and_attest:
130+
name: ${{ matrix.artifact.path }}
131+
permissions:
132+
packages: read
133+
contents: read
134+
needs: release
135+
runs-on: ubuntu-latest
136+
env:
137+
CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }}
138+
ATTESTATION_ID: ${{ needs.init_attestation.outputs.attestation_id }}
139+
strategy:
140+
matrix:
141+
artifact: ${{ fromJson(needs.release.outputs.matrix) }}
142+
143+
steps:
144+
- name: Docker login to Github Packages
145+
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
146+
with:
147+
registry: ghcr.io
148+
username: ${{ github.actor }}
149+
password: ${{ secrets.GITHUB_TOKEN }}
150+
151+
- name: Install Chainloop
152+
run: |
153+
curl -sfL https://docs.chainloop.dev/install.sh | bash -s
154+
- name: Checkout
155+
uses: actions/checkout@v3
156+
157+
- uses: anchore/sbom-action@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9
158+
if: ${{ matrix.artifact.type == 'image' }}
159+
with:
160+
image: ${{ matrix.artifact.path }}
161+
format: cyclonedx-json
162+
output-file: /tmp/sbom.cyclonedx.json
163+
164+
- uses: anchore/sbom-action@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9
165+
if: ${{ matrix.artifact.type == 'archive' }}
166+
with:
167+
file: ${{ matrix.artifact.path }}
168+
format: cyclonedx-json
169+
output-file: /tmp/sbom.cyclonedx.json
170+
171+
- name: Add Artifact and SBOM to attestation
172+
run: |
173+
chainloop attestation add --value ${{ matrix.artifact.path }} --attestation-id ${{ env.ATTESTATION_ID }}
174+
chainloop attestation add --value /tmp/sbom.cyclonedx.json --attestation-id ${{ env.ATTESTATION_ID }}
175+
176+
finish_attestation:
177+
name: Finish Attestation
178+
runs-on: ubuntu-latest
179+
needs: generate_sboms_and_attest
180+
steps:
181+
- name: Install Chainloop
182+
run: |
183+
curl -sfL https://docs.chainloop.dev/install.sh | bash -s
184+
185+
- name: Finish and Record Attestation
186+
if: ${{ success() }}
187+
run: |
188+
chainloop attestation push --attestation-id ${{ needs.init_attestation.outputs.attestation_id }}
189+
140190
- name: Mark attestation as failed
141191
if: ${{ failure() }}
142192
run: |
143-
chainloop attestation reset
193+
chainloop attestation reset --attestation-id ${{ needs.init_attestation.outputs.attestation_id }}
194+
144195
- name: Mark attestation as cancelled
145196
if: ${{ cancelled() }}
146197
run: |
147-
chainloop attestation reset --trigger cancellation
198+
chainloop attestation reset --trigger cancellation --attestation-id ${{ needs.init_attestation.outputs.attestation_id }}
148199
149200
github-release:
150201
needs: release

.github/workflows/contracts/chainloop-chainloop-github-release.yaml

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,6 @@ schemaVersion: v1
33
policies:
44
attestation:
55
- ref: source-commit
6-
policyGroups:
7-
- ref: sbom-quality
8-
with:
9-
sbom_name: cas-cyclonedx
10-
bannedLicenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later
11-
bannedComponents: [email protected]
12-
- ref: sbom-quality
13-
with:
14-
sbom_name: cli-cyclonedx
15-
bannedLicenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later
16-
bannedComponents: [email protected]
17-
- ref: sbom-quality
18-
with:
19-
sbom_name: controlplane-cyclonedx
20-
bannedLicenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later
21-
bannedComponents: [email protected]
6+
with:
7+
check_signature: yes
8+
Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
# Contract for the chainloop-vault-build-and-package workflow
22
schemaVersion: v1
3-
runner:
4-
type: GITHUB_ACTION
5-
materials:
6-
- type: ARTIFACT
7-
name: goreleaser-output
8-
output: true
93
policies:
104
attestation:
115
- ref: source-commit
6+
with:
7+
check_signature: yes
8+
- ref: containers-with-sbom
9+
materials:
10+
- ref: artifact-signed
11+
- ref: sbom-banned-licenses
12+
with:
13+
licenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later
14+
- ref: sbom-banned-components
15+
with:
16+
components: [email protected]
17+
- ref: sbom-ntia
18+
- ref: sbom-with-licenses
19+
- ref: sbom-freshness
20+
21+
runner:
22+
type: GITHUB_ACTION

.github/workflows/release.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,6 @@ jobs:
6060
gh release download $tag -A tar.gz -D /tmp
6161
chainloop attestation add --value "/tmp/chainloop-$version.tar.gz"
6262
63-
# Include control-plane image
64-
chainloop attestation add --value "ghcr.io/chainloop-dev/chainloop/control-plane:$tag"
65-
66-
# Include cas image
67-
chainloop attestation add --value "ghcr.io/chainloop-dev/chainloop/artifact-cas:$tag"
68-
69-
# Include cli image
70-
chainloop attestation add --value "ghcr.io/chainloop-dev/chainloop/cli:$tag"
71-
7263
- name: Finish and Record Attestation
7364
id: attestation-push
7465
if: ${{ success() }}

0 commit comments

Comments
 (0)