Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
177 changes: 84 additions & 93 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
id-token: write # needed for keyless signing
outputs:
digest: ${{ steps.image.outputs.digest }}
subjects-as-file: ${{ steps.hashes.outputs.handle }}
checksums-digest: ${{ steps.checksums.outputs.digest }}
steps:
- name: Extract Version from Tag
id: tag_name
Expand All @@ -162,13 +162,14 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: './go.mod'
cache-dependency-path: './go.sum'
check-latest: true
cache: false # avoid cache poisoning in the release build

- name: Set up QEMU
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
Expand Down Expand Up @@ -198,6 +199,12 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}

- name: Checksums digest
id: checksums
run: |
set -euo pipefail
echo "digest=$(sha256sum dist/checksums.txt | cut -d ' ' -f1)" >> "$GITHUB_OUTPUT"

- name: Update Docker Hub Description
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0
with:
Expand All @@ -206,20 +213,6 @@ jobs:
repository: openfga/cli
short-description: ${{ github.event.repository.description }}

- name: Generate binary hashes
id: binary
env:
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
run: |
set -euo pipefail
hashes=$(echo $ARTIFACTS | jq --raw-output '[.[] | {name, "digest": (.extra.Digest // .extra.Checksum)}] | unique | .[] | select(.digest) | {digest} + {name} | join(" ") | sub("^sha256:";"")' | base64 -w0)
echo $hashes > digests.txt

- uses: slsa-framework/slsa-github-generator/actions/generator/generic/create-base64-subjects-from-file@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # [email protected]
id: hashes
with:
path: digests.txt

- name: Image digest
id: image
env:
Expand All @@ -239,98 +232,91 @@ jobs:
digest=$(echo "$artifact" | jq -r '.extra.Digest')
echo "digest=$digest" >> "$GITHUB_OUTPUT"

binary-provenance:
attest:
needs: [ goreleaser ]
permissions:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
# write required even with upload-assets:false due to slsa-framework/slsa-github-generator#2044
contents: write

# Note: this _must_ be referenced by tag. See: https://github.com/slsa-framework/slsa-verifier/issues/12
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
base64-subjects-as-file: "${{ needs.goreleaser.outputs.subjects-as-file }}"
provenance-name: "fga.intoto.jsonl"
# Don't let the generator attach the provenance:
# - it uses softprops/[email protected], whose paginated draft lookup
# creates a duplicate draft once a repo has >100 releases (2 pages)
# - the provenance is still published as a workflow artifact, so the
# release-provenance job attaches it via `gh release upload` (by tag)
upload-assets: false

release-provenance:
needs: [ binary-provenance ]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write # To add the provenance asset to the draft release.
contents: write # to read the draft release and attach the provenance
id-token: write # needed for keyless signing
attestations: write # needed for artifact attestations
artifact-metadata: write # needed for the image storage record
steps:
- name: Download the provenance
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
- name: Login to Docker Hub
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# The draft is mutable, so check it against the file GoReleaser built.
- name: Download checksums
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CHECKSUMS_DIGEST: ${{ needs.goreleaser.outputs.checksums-digest }}
run: |
set -euo pipefail
gh release download "$GITHUB_REF_NAME" -p checksums.txt \
--repo "$GITHUB_REPOSITORY"
Comment thread
SoulPancake marked this conversation as resolved.
echo "$CHECKSUMS_DIGEST checksums.txt" | sha256sum -c --strict

- name: Attest release artifacts
Comment thread
Siddhant-K-code marked this conversation as resolved.
id: attest
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
name: ${{ needs.binary-provenance.outputs.provenance-name }}
subject-checksums: checksums.txt

# Scorecard's Signed-Releases check only detects provenance as a
# *.intoto.jsonl release asset. The bundle is a single JSON line.
- name: Attach provenance to the draft release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROVENANCE: ${{ needs.binary-provenance.outputs.provenance-name }}
BUNDLE: ${{ steps.attest.outputs.bundle-path }}
run: |
set -euo pipefail
gh release upload "$GITHUB_REF_NAME" "$PROVENANCE" \
cp "$BUNDLE" fga.intoto.jsonl
gh release upload "$GITHUB_REF_NAME" fga.intoto.jsonl \
--repo "$GITHUB_REPOSITORY" --clobber
Comment thread
Siddhant-K-code marked this conversation as resolved.

image-provenance:
needs: [ goreleaser ]
permissions:
actions: read
id-token: write
packages: write

# Note: this _must_ be referenced by tag. See: https://github.com/slsa-framework/slsa-verifier/issues/12
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: openfga/cli
digest: ${{ needs.goreleaser.outputs.digest }}
secrets:
registry-username: ${{ secrets.DOCKERHUB_USERNAME }}
registry-password: ${{ secrets.DOCKERHUB_TOKEN }}

undraft-release:
needs: [ release-provenance, image-provenance ]
permissions:
contents: write
uses: openfga/.github/.github/workflows/undraft-release.yml@835baf31562809ad9eb884c73efc5b79318f700f # pin@main
- name: Attest image
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-name: docker.io/openfga/cli
subject-digest: ${{ needs.goreleaser.outputs.digest }}
push-to-registry: true

verification-with-slsa-verifier:
needs: [ undraft-release, binary-provenance ]
verify-binary-provenance:
needs: [ attest ]
runs-on: ubuntu-latest
permissions: read-all
permissions:
contents: write # to download from the draft release
attestations: read
steps:
- name: Install the verifier
uses: slsa-framework/slsa-verifier/actions/installer@ea584f4502babc6f60d9bc799dbbb13c1caa9ee6 # [email protected]

- name: Download assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROVENANCE: "${{ needs.binary-provenance.outputs.provenance-name }}"
run: |
set -euo pipefail
gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" \
-p "$PROVENANCE" -p "*.tar.gz" -p "*.tar.gz.sbom.json"
-p "*.tar.gz" -p "*.sbom.json" -p "*.apk" -p "*.deb" -p "*.rpm" -p "*.pkg.tar.zst" \
-p fga.intoto.jsonl

- name: Verify assets
env:
PROVENANCE: "${{ needs.binary-provenance.outputs.provenance-name }}"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
slsa-verifier verify-artifact \
--provenance-path "$PROVENANCE" \
--source-uri "github.com/$GITHUB_REPOSITORY" \
--source-tag "$GITHUB_REF_NAME" \
*.tar.gz *.tar.gz.sbom.json

verification-with-cosign:
needs: [ goreleaser, image-provenance ]
set -euo pipefail
verify() {
gh attestation verify "$@" \
--repo "$GITHUB_REPOSITORY" \
--cert-identity "https://github.com/$GITHUB_REPOSITORY/.github/workflows/main.yaml@$GITHUB_REF" \
--source-ref "$GITHUB_REF"
}
for artifact in *.tar.gz *.sbom.json *.apk *.deb *.rpm *.pkg.tar.zst; do
verify "$artifact"
verify "$artifact" --bundle fga.intoto.jsonl
done
Comment thread
Siddhant-K-code marked this conversation as resolved.

verify-image-provenance:
needs: [ goreleaser, attest ]
runs-on: ubuntu-latest
permissions: read-all
steps:
Expand All @@ -340,18 +326,23 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
with:
cosign-release: "v2.6.1"

- name: Verify image
env:
IMAGE: openfga/cli
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DIGEST: ${{ needs.goreleaser.outputs.digest }}
run: |
cosign verify-attestation \
--type slsaprovenance \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v[0-9]+.[0-9]+.[0-9]+$' \
$IMAGE@$DIGEST
set -euo pipefail
verify() {
gh attestation verify "oci://docker.io/openfga/cli@$DIGEST" "$@" \
--repo "$GITHUB_REPOSITORY" \
--cert-identity "https://github.com/$GITHUB_REPOSITORY/.github/workflows/main.yaml@$GITHUB_REF" \
--source-ref "$GITHUB_REF"
}
verify
verify --bundle-from-oci

undraft-release:
needs: [ verify-binary-provenance, verify-image-provenance ]
permissions:
contents: write
uses: openfga/.github/.github/workflows/undraft-release.yml@835baf31562809ad9eb884c73efc5b79318f700f # pin@main
8 changes: 5 additions & 3 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ dockers_v2:
- images:
- openfga/cli
tags:
- latest
- "{{ if not .Prerelease }}latest{{ end }}"
- "{{ .Tag }}"
- "v{{ .Major }}"
- "v{{ .Major }}.{{ .Minor }}"
- "{{ if not .Prerelease }}v{{ .Major }}{{ end }}"
- "{{ if not .Prerelease }}v{{ .Major }}.{{ .Minor }}{{ end }}"
dockerfile: .goreleaser.Dockerfile
platforms:
- linux/amd64
Expand Down Expand Up @@ -82,6 +82,7 @@ docker_signs:

brews:
- name: "{{.ProjectName}}"
skip_upload: auto
repository:
owner: openfga
name: homebrew-tap
Expand All @@ -108,6 +109,7 @@ brews:
test: |
system "#{bin}/fga version"
- name: "{{.ProjectName}}@{{.Version}}"
skip_upload: auto
repository:
owner: openfga
name: homebrew-tap
Expand Down
Loading