Skip to content

Commit d884b47

Browse files
authored
DEVOPS-3072 - adding SLSA provenance generation (#1664)
2 parents d77170f + abf79fa commit d884b47

File tree

4 files changed

+81
-11
lines changed

4 files changed

+81
-11
lines changed

.github/workflows/publish.yml

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ permissions:
2525
jobs:
2626
build:
2727
runs-on: ubuntu-latest
28+
outputs:
29+
hashes: ${{ steps.hash.outputs.hashes }}
2830
steps:
2931
- uses: actions/checkout@v4
3032
with:
31-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
3233
ref: ${{ inputs.tag }}
3334
- name: Install the latest version of rye
3435
uses: eifinger/setup-rye@v2
@@ -43,10 +44,25 @@ jobs:
4344
run: |
4445
rye sync
4546
rye build
47+
- name: "Generate hashes"
48+
id: hash
49+
run: |
50+
cd dist && echo "hashes=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT
4651
- uses: actions/upload-artifact@v4
4752
with:
4853
name: build
4954
path: ./dist
55+
provenance_python:
56+
needs: [build]
57+
permissions:
58+
actions: read
59+
contents: write
60+
id-token: write # Needed to access the workflow's OIDC identity.
61+
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
62+
with:
63+
base64-subjects: "${{ needs.build.outputs.hashes }}"
64+
upload-assets: true
65+
upload-tag-name: ${{ inputs.tag }} # Tag from the initiation of the workflow
5066
test-build:
5167
if: ${{ !inputs.skip-tests }}
5268
needs: ['build']
@@ -73,7 +89,6 @@ jobs:
7389
steps:
7490
- uses: actions/checkout@v4
7591
with:
76-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
7792
ref: ${{ inputs.tag }}
7893
- name: Install the latest version of rye
7994
uses: eifinger/setup-rye@v2
@@ -115,6 +130,24 @@ jobs:
115130
rye add labelbox --path ./$(find ./dist/ -name *.tar.gz) --sync --absolute --features data
116131
cd libs/labelbox
117132
rye run pytest tests/data
133+
publish-python-package-to-release:
134+
runs-on: ubuntu-latest
135+
needs: ['build']
136+
permissions:
137+
contents: write
138+
steps:
139+
- uses: actions/checkout@v4
140+
with:
141+
ref: ${{ inputs.tag }}
142+
- uses: actions/download-artifact@v4
143+
with:
144+
name: build
145+
path: ./artifact
146+
- name: Upload dist to release
147+
run: |
148+
gh release upload ${{ inputs.tag }} ./artifact/*
149+
env:
150+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
118151
pypi-publish:
119152
runs-on: ubuntu-latest
120153
needs: ['build', 'test-build']
@@ -141,6 +174,9 @@ jobs:
141174
needs: ['build', 'test-build']
142175
permissions:
143176
packages: write
177+
outputs:
178+
image: ${{ steps.image.outputs.image }}
179+
digest: ${{ steps.build_container.outputs.digest }}
144180
if: |
145181
always() &&
146182
(needs.test-build.result == 'success' || needs.test-build.result == 'skipped') && github.event.inputs.tag
@@ -149,7 +185,6 @@ jobs:
149185
steps:
150186
- uses: actions/checkout@v4
151187
with:
152-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
153188
ref: ${{ inputs.tag }}
154189

155190
- name: downcase CONTAINER_IMAGE
@@ -168,6 +203,7 @@ jobs:
168203

169204
- name: Build and push
170205
uses: docker/build-push-action@v5
206+
id: build_container
171207
with:
172208
context: .
173209
file: ./libs/labelbox/Dockerfile
@@ -181,5 +217,24 @@ jobs:
181217
tags: |
182218
${{ env.CONTAINER_IMAGE }}:latest
183219
${{ env.CONTAINER_IMAGE }}:${{ inputs.tag }}
184-
185-
# Note that the build and pypi-publish jobs are split so that the additional permissions are only granted to the pypi-publish job.
220+
- name: Output image
221+
id: image
222+
run: |
223+
# NOTE: Set the image as an output because the `env` context is not
224+
# available to the inputs of a reusable workflow call.
225+
image_name="${CONTAINER_IMAGE}"
226+
echo "image=$image_name" >> "$GITHUB_OUTPUT"
227+
228+
provenance_container:
229+
needs: [container-publish]
230+
permissions:
231+
actions: read # for detecting the Github Actions environment.
232+
id-token: write # for creating OIDC tokens for signing.
233+
packages: write # for uploading attestations.
234+
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
235+
with:
236+
image: ${{ needs. container-publish.outputs.image }}
237+
digest: ${{ needs. container-publish.outputs.digest }}
238+
registry-username: ${{ github.actor }}
239+
secrets:
240+
registry-password: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/python-package-develop.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ jobs:
5454
steps:
5555
- uses: actions/checkout@v4
5656
with:
57-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
5857
ref: ${{ github.head_ref }}
5958
- uses: ./.github/actions/python-package-shared-setup
6059
with:
@@ -85,7 +84,6 @@ jobs:
8584
steps:
8685
- uses: actions/checkout@v4
8786
with:
88-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
8987
ref: ${{ github.head_ref }}
9088

9189
- name: downcase CONTAINER_IMAGE

.github/workflows/python-package-shared.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ jobs:
2525
steps:
2626
- uses: actions/checkout@v4
2727
with:
28-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
2928
ref: ${{ github.head_ref }}
3029
- uses: ./.github/actions/python-package-shared-setup
3130
with:
@@ -42,7 +41,6 @@ jobs:
4241
steps:
4342
- uses: actions/checkout@v4
4443
with:
45-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
4644
ref: ${{ github.head_ref }}
4745
- uses: ./.github/actions/python-package-shared-setup
4846
with:
@@ -61,7 +59,6 @@ jobs:
6159
steps:
6260
- uses: actions/checkout@v4
6361
with:
64-
token: ${{ secrets.ACTIONS_ACCESS_TOKEN }}
6562
ref: ${{ github.head_ref }}
6663
- uses: ./.github/actions/python-package-shared-setup
6764
with:

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
[![Twitter Follow](https://img.shields.io/twitter/follow/labelbox.svg?style=social&label=Follow)](https://twitter.com/labelbox)
1313
[![LinkedIn Follow](https://img.shields.io/badge/Follow-LinkedIn-blue.svg?style=flat&logo=linkedin)](https://www.linkedin.com/company/labelbox/)
1414
[![Supported Python Versions](https://img.shields.io/pypi/pyversions/labelbox)](https://img.shields.io/pypi/pyversions/labelbox)
15+
[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev)
1516

1617
# Labelbox
1718

@@ -94,4 +95,23 @@ c.InteractiveShellApp.exec_lines = [
9495
'import sys; sys.path.insert(0, "<labelbox-python root folder>")'
9596
]
9697
```
97-
4. Go to the root of your project and run `jupyter notebook` to start the server.
98+
4. Go to the root of your project and run `jupyter notebook` to start the server.
99+
100+
## Provenance
101+
102+
To enhance the software supply chain security of Labelbox's users, as of v.3.72.2, every Labelbox SDK release contains a [SLSA Level 3 Provenance](https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md) document.
103+
This document provides detailed information about the build process, including the repository and branch from which the package was generated.
104+
105+
By using the [SLSA framework's official verifier](https://github.com/slsa-framework/slsa-verifier), you can verify the provenance document to ensure that the package is from a trusted source. Verifying the provenance helps confirm that the package has not been tampered with and was built in a secure environment.
106+
107+
Example of usage for the v.3.72.2 release wheel:
108+
109+
```
110+
VERSION=v.3.72.2 #tag
111+
pip download --no-deps labelbox==${VERSION}
112+
113+
curl --location -O \
114+
https://github.com/Labelbox/labelbox-python/releases/download/${VERSION}/multiple.intoto.jsonl
115+
116+
slsa-verifier verify-artifact --source-branch develop --builder-id 'https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v2.0.0' --source-uri "git+https://github.com/Labelbox/labelbox-python" --provenance-path multiple.intoto.jsonl ./labelbox-${VERSION}-py3-none-any.whl
117+
```

0 commit comments

Comments
 (0)