Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container provenance #88

Merged
merged 23 commits into from
Dec 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4dc7f6f
Add IMAGE_DIGEST output to release job
marcofranssen Nov 5, 2021
0c0ed88
Implement first draft to generate provenance for containers
marcofranssen Nov 18, 2021
cc02d63
Use variable for repos in Makefile
marcofranssen Dec 2, 2021
1489f06
Get container variables for provenance in workflow
marcofranssen Dec 2, 2021
2e451be
Refactor action to support multiple usecases
marcofranssen Dec 14, 2021
5c3277b
Add container provenance job
marcofranssen Dec 14, 2021
a28c1a8
Try fix action.yml
marcofranssen Dec 14, 2021
c4d4dc4
Switch to composite action to dynamically build the image args
marcofranssen Dec 15, 2021
4233703
Publish as draft when tag has suffix -draft
marcofranssen Dec 15, 2021
8778fdc
Fix arguments
marcofranssen Dec 15, 2021
60802d7
Resolve issue with CONTAINER_DIGEST var in ci
marcofranssen Dec 21, 2021
065eab8
Use base64 encoding for github and runner context
marcofranssen Dec 21, 2021
8595578
Remove docker username secret
marcofranssen Dec 21, 2021
0645c6a
fix-snapshot release naming
marcofranssen Dec 22, 2021
636239e
Add tests for container command + fix digest flag error
marcofranssen Dec 22, 2021
b7c8807
Add tests for OCI subjecter
marcofranssen Dec 22, 2021
79973f2
Add debugging for the action arguments
marcofranssen Dec 23, 2021
9390333
Args as string output
marcofranssen Dec 24, 2021
5bd7c0a
Fix provenance args for dockers in CI
marcofranssen Dec 24, 2021
a8bd75c
Quote contexts in action.yml
marcofranssen Dec 24, 2021
7e2ee54
Attest the container using cosign
marcofranssen Dec 24, 2021
0a8c490
Prevent whitelines in base64 encoding
marcofranssen Dec 24, 2021
204d953
Update documentation
marcofranssen Dec 24, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 69 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ jobs:
release:
name: release
needs: [build]
outputs:
container_digest: ${{ steps.container_info.outputs.container_digest }}
container_tags: ${{ steps.container_info.outputs.container_tags }}
container_repos: ${{ steps.container_info.outputs.container_repos }}

runs-on: ubuntu-20.04

steps:
Expand All @@ -79,7 +84,7 @@ jobs:
- name: Login to Container registries
if: startsWith(github.ref, 'refs/tags/')
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u philipssoftware --password-stdin
echo "${{ secrets.GITHUB_TOKEN }}" | docker login -u ${{ github.actor }} --password-stdin ghcr.io

- name: Set release variables
Expand All @@ -99,12 +104,71 @@ jobs:
uses: goreleaser/goreleaser-action@v2
with:
version: latest
args: release --rm-dist ${{ (!startsWith(github.ref, 'refs/tags/') && '--snapshot') || '' }}
args: release --rm-dist ${{ (!startsWith(github.ref, 'refs/tags/') && '--snapshot') || '' }} ${{ ((startsWith(github.ref, 'refs/tags/') && endsWith(github.ref, '-draft')) && '-f .goreleaser.draft.yml') || '' }}
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
LDFLAGS: ${{ steps.release-vars.outputs.LDFLAGS }}
GIT_HASH: ${{ steps.release-vars.outputs.GIT_HASH }}

- name: Get container info
id: container_info
if: startsWith(github.ref, 'refs/tags/')
run: |
export CONTAINER_DIGEST=$(make container-digest GITHUB_REF=${{ github.ref_name }})
echo "::set-output name=container_digest::$CONTAINER_DIGEST"
echo "::set-output name=container_tags::$(make container-tags CONTAINER_DIGEST="${CONTAINER_DIGEST}" | paste -s -d ',' -)"
echo "::set-output name=container_repos::$(make container-repos CONTAINER_DIGEST="${CONTAINER_DIGEST}" | jq --raw-input . | jq --slurp -c)"

- name: Logout from Container registries
if: ${{ always() }}
run: |
docker logout
docker logout ghcr.io

container-provenance:
name: container-provenance
needs: [release]
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-20.04

strategy:
matrix:
repo: ${{ fromJSON(needs.release.outputs.container_repos) }}

steps:
- name: Install cosign
uses: sigstore/[email protected]
with:
cosign-release: 'v1.4.1'

- name: Generate provenance for ${{ matrix.repo }}
uses: philips-labs/[email protected]
with:
command: generate
subcommand: container
arguments: --repository ${{ matrix.repo }} --digest ${{ needs.release.outputs.container_digest }} --tags ${{ needs.release.outputs.container_tags }}

env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

- name: Login to Container registries
if: startsWith(github.ref, 'refs/tags/')
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u philipssoftware --password-stdin
echo "${{ secrets.GITHUB_TOKEN }}" | docker login -u ${{ github.actor }} --password-stdin ghcr.io

- name: Attach provenance to image
run: |
echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key
cosign attest --predicate provenance.json --key cosign.key ${{ matrix.repo }}@${{ needs.release.outputs.container_digest }}
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}

- name: Verify attestation
run: |
echo '${{ secrets.COSIGN_PUBLIC_KEY }}' > cosign.pub
cosign verify-attestation --key cosign.pub ${{ matrix.repo }}@${{ needs.release.outputs.container_digest }}

- name: Logout from Container registries
if: ${{ always() }}
run: |
Expand All @@ -121,9 +185,8 @@ jobs:
- name: Generate provenance for Release
uses: philips-labs/[email protected]
with:
sub-command: github-release
artifact_path: release-assets
output_path: 'provenance.json'
tag_name: ${{ github.ref_name }}
command: generate
subcommand: github-release
arguments: --artifact-path release-assets --output-path provenance.json --tag-name ${{ github.ref_name }}
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
4 changes: 3 additions & 1 deletion .github/workflows/example-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ jobs:
- name: Generate provenance
uses: philips-labs/[email protected]
with:
artifact_path: artifact/
command: generate
subcommand: files
arguments: --artifact-path artifact/ --output-path provenance.json

- name: Upload provenance
uses: actions/upload-artifact@v2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ dist/
coverage.out
.DS_Store
.env
cosign.key
77 changes: 77 additions & 0 deletions .goreleaser.draft.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
project_name: slsa-provenance

before:
hooks:
- go mod tidy

env:
- CGO_ENABLED=0

builds:
- id: binary
dir: cmd/slsa-provenance
goos:
- windows
- darwin
- linux
goarch:
- amd64
- arm64
goarm:
- 8
ldflags:
- "{{ .Env.LDFLAGS }}"

archives:
- id: archive
format: tar.gz
replacements:
darwin: macOS
files:
- LICENSE*
- README*
format_overrides:
- goos: windows
format: zip

dockers:
- goos: linux
goarch: amd64
image_templates:
- "philipssoftware/{{ .ProjectName }}:v{{ .Version }}"
- "philipssoftware/{{ .ProjectName }}:{{ .FullCommit }}"
- "ghcr.io/philips-labs/{{ .ProjectName }}:v{{ .Version }}"
- "ghcr.io/philips-labs/{{ .ProjectName }}:{{ .FullCommit }}"
build_flag_templates:
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.title={{.ProjectName}}"
- "--label=org.opencontainers.image.description={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version=v{{.Version}}"
- "--label=org.opencontainers.image.licenses=MIT"
- "--label=org.opencontainers.image.vendor=Koninklijke Philips N.V."
extra_files:
- "Makefile"
- "go.mod"
- "go.sum"
- "cmd"
- "lib"
checksum:
name_template: 'checksums.txt'

snapshot:
name_template: "{{ .Version }}-next"

changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- Merge pull request
- Merge branch

release:
draft: true
prerelease: auto
3 changes: 2 additions & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ checksum:
name_template: 'checksums.txt'

snapshot:
name_template: "{{ .Tag }}-next"
name_template: "{{ .Version }}-next"

changelog:
sort: asc
Expand All @@ -73,4 +73,5 @@ changelog:
- Merge branch

release:
draft: false
prerelease: auto
24 changes: 22 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ LDFLAGS="-X $(PKG).GitVersion=$(GIT_VERSION) -X $(PKG).gitCommit=$(GIT_HASH) -X
GO_BUILD_FLAGS := -trimpath -ldflags $(LDFLAGS)
COMMANDS := slsa-provenance

HUB_REPO := philipssoftware/slsa-provenance
GHCR_REPO := ghcr.io/philips-labs/slsa-provenance

check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
Expand Down Expand Up @@ -78,8 +81,11 @@ build: $(addprefix bin/,$(COMMANDS)) ## builds binaries
.PHONY: image
image: ## build the binary in a docker image
docker build \
-t "philipssoftware/slsa-provenance:$(GIT_TAG)" \
-t "philipssoftware/slsa-provenance:$(GIT_HASH)" .
-t "$(HUB_REPO):$(GIT_TAG)" \
-t "$(HUB_REPO):$(GIT_HASH)" \
-t "$(GHCR_REPO):$(GIT_TAG)" \
-t "$(GHCR_REPO):$(GIT_HASH)" \
.

$(GO_PATH)/bin/goreleaser:
go install github.com/goreleaser/[email protected]
Expand Down Expand Up @@ -119,3 +125,17 @@ gh-release: ## Creates a new release by creating a new tag and pushing it
@echo
@git stash pop

.PHONY: container-digest
container-digest: ## retrieves the container digest from the given tag
@:$(call check_defined, GITHUB_REF)
@docker inspect $(GHCR_REPO):$(subst refs/tags/,,$(GITHUB_REF)) --format '{{ index .RepoDigests 0 }}' | cut -d '@' -f 2

.PHONY: container-tags
container-tags: ## retrieves the container tags applied to the image with a given digest
@:$(call check_defined, CONTAINER_DIGEST)
@docker inspect ghcr.io/philips-labs/slsa-provenance@$(CONTAINER_DIGEST) --format '{{ join .RepoTags "\n" }}' | sed 's/.*://' | awk '!_[$$0]++'

.PHONY: container-repos
container-repos: ## retrieves the container tags applied to the image with a given digest
@:$(call check_defined, CONTAINER_DIGEST)
@docker inspect ghcr.io/philips-labs/slsa-provenance@$(CONTAINER_DIGEST) --format '{{ join .RepoTags "\n" }}' | sed 's/:.*//' | awk '!_[$$0]++'
33 changes: 12 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<h3 align="center">SLSA Provenance GitHub Action</h3>

<p align="center">
Github Action implementation of SLSA Provenance Generation of level 1
Github Action to generate [SLSA provenance][slsa-provenance]
<br>
<a href="https://github.com/philips-labs/slsa-provenance-action/issues">Report Bug</a>
·
Expand Down Expand Up @@ -145,11 +145,11 @@ The easiest way to use this action is to add the following into your workflow fi

steps:
- name: Generate provenance for Release
uses: philips-labs/slsa-provenance-action@v0.4.0
uses: philips-labs/slsa-provenance-action@v0.5.0
with:
artifact_path: release-assets
output_path: 'provenance.json'
tag_name: ${{ github.ref_name }}
command: generate
subcommand: files
arguments: --artifact-path release-assets --output-path 'provenance.json' --tag-name ${{ github.ref_name }}
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
```
Expand Down Expand Up @@ -180,10 +180,11 @@ The easiest way to use this action is to add the following into your workflow fi
path: extra-materials/

- name: Generate provenance
uses: philips-labs/SLSA-Provenance-Action@8c78a6b34703824b9561a26b1ae5893beea9a332
uses: philips-labs/[email protected]
with:
artifact_path: artifact/
extra_materials: extra-materials/file1.json extra-materials/some-more.json
command: generate
subcommand: files
arguments: --artifact-path artifact/ --extra-materials extra-materials/file1.json,extra-materials/some-more.json

- name: Upload provenance
uses: actions/upload-artifact@v2
Expand All @@ -201,22 +202,11 @@ An action to generate SLSA build provenance for an artifact

| parameter | description | required | default |
| - | - | - | - |
| command | The slsa-provenance command to run | `false` | generate |
| subcommand | The subcommand to use when generating provenance | `false` | files |
| artifact_path | path to artifact or directory of artifacts | `true` | |
| output_path | path to write build provenance file | `false` | provenance.json |
| github_context | internal (do not set): the "github" context object in json | `true` | ${{ toJSON(github) }} |
| runner_context | internal (do not set): the "runner" context object in json | `true` | ${{ toJSON(runner) }} |
| tag_name | The github release to generate provenance on.\n (if set the artifacts will be downloaded from the release and the provenance will be added as an additional release asset.) | `false` | |
| extra_materials | paths to files containing SLSA v0.1 formatted materials (JSON array) in to include in the provenance | `false` | |

### Available commands

- Generate
Command that generates the provenance.
- Help
Command that prints helpful information about what commands and arguments can be used.
- Version
Command that prints version information about the binary that is used.
| arguments | the arguments for the given `command` and `subcommand` | `true` | |

<p align="right">(<a href="#top">back to top</a>)</p>

Expand Down Expand Up @@ -270,3 +260,4 @@ This project is inspired by:
[issues-url]: https://github.com/philips-labs/slsa-provenance-action/issues
[license-shield]: https://img.shields.io/github/license/philips-labs/slsa-provenance-action.svg?style=for-the-badge
[license-url]: https://github.com/philips-labs/slsa-provenance-action/blob/main/LICENSE.md
[slsa-provenance]: https://slsa.dev/provenance/v0.2
Loading