From a489f3866e58cc54a1d10858095df4c4773f0116 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 02:36:52 +0000 Subject: [PATCH 1/6] Rename default e2e test to match scheme --- ...main.slsa2.yml => e2e.generic.schedule.main.default.slsa2.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{e2e.generic.schedule.main.slsa2.yml => e2e.generic.schedule.main.default.slsa2.yml} (100%) diff --git a/.github/workflows/e2e.generic.schedule.main.slsa2.yml b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml similarity index 100% rename from .github/workflows/e2e.generic.schedule.main.slsa2.yml rename to .github/workflows/e2e.generic.schedule.main.default.slsa2.yml From ac256b12f79ade3131457f3cf8df83485d5d268d Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 02:59:47 +0000 Subject: [PATCH 2/6] Update e2e.generic workflows --- .../e2e.generic.push.main.default.slsa2.yml | 94 +++++++++++++++++++ ...2e.generic.schedule.main.default.slsa2.yml | 47 +++++++++- 2 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/e2e.generic.push.main.default.slsa2.yml diff --git a/.github/workflows/e2e.generic.push.main.default.slsa2.yml b/.github/workflows/e2e.generic.push.main.default.slsa2.yml new file mode 100644 index 0000000000..fdea03a5ab --- /dev/null +++ b/.github/workflows/e2e.generic.push.main.default.slsa2.yml @@ -0,0 +1,94 @@ +name: Generic push main default SLSA 2 +on: + schedule: + - cron: "0 3 * * *" + workflow_dispatch: + push: + branches: [main] + +env: + GH_TOKEN: ${{ secrets.E2E_GO_TOKEN }} + ISSUE_REPOSITORY: slsa-framework/slsa-github-generator + THIS_FILE: e2e.generic.push.main.default.slsa2.yml + +jobs: + push: + runs-on: ubuntu-latest + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + permissions: + contents: write + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - run: ./.github/workflows/scripts/e2e-push.sh + + build: + if: github.event_name == 'push' && github.event.head_commit.message == github.workflow + outputs: + binary-name: ${{ steps.hash.outputs.binary-name }} + digest: ${{ steps.hash.outputs.digest }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: bazelisk build //:hello + - uses: actions/upload-artifact@v3 + with: + path: bazel-bin/hello_/hello + - name: "generate hash" + shell: bash + id: hash + run: | + set -euo pipefail + DIGEST=$(sha256sum bazel-bin/hello_/hello) + DIGEST="${DIGEST//'%'/'%25'}" + DIGEST="${DIGEST//$'\n'/'%0A'}" + DIGEST="${DIGEST//$'\r'/'%0D'}" + echo "::set-output name=binary-name::hello" + echo "::set-output name=digest::$DIGEST" + # TODO: upload binary artifact + + provenance: + if: github.event_name == 'push' && github.event.head_commit.message == github.workflow + needs: [build] + permissions: + id-token: write + contents: read + uses: slsa-framework/slsa-github-generator/.github/workflows/slsa2_provenance.yml@main + with: + subjects: "${{ needs.build.outputs.digest }}" + + verify: + runs-on: ubuntu-latest + needs: [build, provenance] + if: github.event_name == 'push' && github.event.head_commit.message == github.workflow + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + with: + name: ${{ needs.build.outputs.binary-name }} + - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + with: + name: ${{ needs.provenance.outputs.attestation-name }} + - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 + with: + go-version: "1.18" + - env: + BINARY: ${{ needs.build.outputs.go-binary-name }} + PROVENANCE: ${{ needs.provenance.outputs.attestation-name }} + # TODO: Write provenance-only verify script. + run: ./.github/workflows/scripts/e2e-verify.sh + + if-succeeded: + runs-on: ubuntu-latest + needs: [build, provenance, verify] + if: github.event_name == 'push' && github.event.head_commit.message == github.workflow && needs.build.result == 'success' && needs.provenance.result == 'success' && needs.verify.result == 'success' + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - run: ./.github/workflows/scripts/e2e-report-success.sh + + if-failed: + runs-on: ubuntu-latest + needs: [build, provenance, verify] + if: always() && github.event_name == 'push' && github.event.head_commit.message == github.workflow && (needs.build.result == 'failure' || needs.provenance.result == 'failure' || needs.verify.result == 'failure') + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - run: ./.github/workflows/scripts/e2e-report-failure.sh diff --git a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml index ea71f37e80..75656f9cc8 100644 --- a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml +++ b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml @@ -1,9 +1,9 @@ -name: Generic schedule main SLSA 2 -on: +name: Generic schedule main default SLSA 2 +on: schedule: - - cron: '0 3 * * *' + - cron: "0 3 * * *" workflow_dispatch: - + jobs: build: outputs: @@ -24,7 +24,10 @@ jobs: DIGEST="${DIGEST//'%'/'%25'}" DIGEST="${DIGEST//$'\n'/'%0A'}" DIGEST="${DIGEST//$'\r'/'%0D'}" + echo "::set-output name=binary-name::hello" echo "::set-output name=digest::$DIGEST" + # TODO: upload binary artifact + provenance: needs: [build] permissions: @@ -33,3 +36,39 @@ jobs: uses: slsa-framework/slsa-github-generator/.github/workflows/slsa2_provenance.yml@main with: subjects: "${{ needs.build.outputs.digest }}" + + verify: + runs-on: ubuntu-latest + needs: [build, provenance] + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + with: + name: ${{ needs.build.outputs.binary-name }} + - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + with: + name: ${{ needs.provenance.outputs.attestation-name }} + - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 + with: + go-version: "1.18" + - env: + BINARY: ${{ needs.build.outputs.go-binary-name }} + PROVENANCE: ${{ needs.provenance.outputs.attestation-name }} + # TODO: Write provenance-only verify script. + run: ./.github/workflows/scripts/e2e-verify.sh + + if-succeeded: + runs-on: ubuntu-latest + needs: [build, provenance, verify] + if: github.event_name == 'push' && github.event.head_commit.message == github.workflow && needs.build.result == 'success' && needs.provenance.result == 'success' && needs.verify.result == 'success' + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - run: ./.github/workflows/scripts/e2e-report-success.sh + + if-failed: + runs-on: ubuntu-latest + needs: [build, provenance, verify] + if: always() && github.event_name == 'push' && github.event.head_commit.message == github.workflow && (needs.build.result == 'failure' || needs.provenance.result == 'failure' || needs.verify.result == 'failure') + steps: + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - run: ./.github/workflows/scripts/e2e-report-failure.sh From 801a2df6909bc44af355a3df5582d7e7283d710b Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 05:08:36 +0000 Subject: [PATCH 3/6] Add tests --- ...2e.generic.schedule.main.default.slsa2.yml | 43 +++-- .../scripts/e2e.generic.default.verify.sh | 182 ++++++++++++++++++ 2 files changed, 209 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/scripts/e2e.generic.default.verify.sh diff --git a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml index 75656f9cc8..72f63fdc33 100644 --- a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml +++ b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml @@ -7,26 +7,33 @@ on: jobs: build: outputs: + binary-name: ${{ steps.hash.outputs.binary-name }} digest: ${{ steps.hash.outputs.digest }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - run: bazelisk build //:hello - - uses: actions/upload-artifact@v3 - with: - path: bazel-bin/hello_/hello - - name: "generate hash" + - name: Checkout code + uses: actions/checkout@v3 + - name: Build artifact + run: bazelisk build //:hello + - name: Generate hash shell: bash id: hash run: | set -euo pipefail - DIGEST=$(sha256sum bazel-bin/hello_/hello) + cp bazel-bin/hello_/hello ./hello + DIGEST=$(sha256sum hello) DIGEST="${DIGEST//'%'/'%25'}" DIGEST="${DIGEST//$'\n'/'%0A'}" DIGEST="${DIGEST//$'\r'/'%0D'}" echo "::set-output name=binary-name::hello" echo "::set-output name=digest::$DIGEST" - # TODO: upload binary artifact + - name: Upload artifact + uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2.3.1 + with: + name: ${{ steps.outputs.binary-name }} + path: ${{ steps.outputs.binary-name }} + if-no-files-found: error + retention-days: 5 provenance: needs: [build] @@ -41,20 +48,24 @@ jobs: runs-on: ubuntu-latest needs: [build, provenance] steps: - - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 - - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + - name: Checkout code + uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0 + - name: Download binary + uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 with: name: ${{ needs.build.outputs.binary-name }} - - uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 + - name: Download provenance + uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 with: name: ${{ needs.provenance.outputs.attestation-name }} - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 + - name: Setup Go + uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 with: - go-version: "1.18" - - env: - BINARY: ${{ needs.build.outputs.go-binary-name }} + go-version: "1.17" + - name: Verify provenance + env: + BINARY: ${{ needs.build.outputs.binary-name }} PROVENANCE: ${{ needs.provenance.outputs.attestation-name }} - # TODO: Write provenance-only verify script. run: ./.github/workflows/scripts/e2e-verify.sh if-succeeded: diff --git a/.github/workflows/scripts/e2e.generic.default.verify.sh b/.github/workflows/scripts/e2e.generic.default.verify.sh new file mode 100644 index 0000000000..029e923b8d --- /dev/null +++ b/.github/workflows/scripts/e2e.generic.default.verify.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash + +source "./.github/workflows/scripts/e2e-utils.sh" + +go env -w GOFLAGS=-mod=mod + +# Install from HEAD +go install github.com/slsa-framework/slsa-verifier@latest + +BRANCH=$(echo "$THIS_FILE" | cut -d '.' -f4) + +echo "branch is $BRANCH" +echo "GITHUB_REF_NAME: $GITHUB_REF_NAME" +echo "GITHUB_REF_TYPE: $GITHUB_REF_TYPE" +echo "GITHUB_REF: $GITHUB_REF" + +# Default parameters. +if [[ "$BRANCH" == "main" ]]; then + slsa-verifier --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_eq "$?" "0" "main default parameters" +else + slsa-verifier --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "not main default parameters" +fi + +echo "DEBUG: file is $THIS_FILE" + +# Correct branch +slsa-verifier --branch "$BRANCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" +e2e_assert_eq "$?" "0" "should be branch $BRANCH" + +# Wrong branch +slsa-verifier --branch "not-$GITHUB_REF_NAME" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" +e2e_assert_not_eq "$?" "0" "wrong branch" + +# Wrong tag +slsa-verifier --tag v1.2.3 --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" +e2e_assert_not_eq "$?" "0" "wrong tag" + +if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then + #TODO: try several versioned-tags and tags. + SEMVER="$GITHUB_REF_NAME" + PATCH=$(echo "$SEMVER" | cut -d '.' -f3) + MINOR=$(echo "$SEMVER" | cut -d '.' -f2) + MAJOR=$(echo "$SEMVER" | cut -d '.' -f1) + + M="${MAJOR:1}" + MAJOR_LESS_ONE="v$((M - 1))" + MINOR_LESS_ONE=$((MINOR - 1)) + PATCH_LESS_ONE=$((PATCH - 1)) + MAJOR_PLUS_ONE="v$((M + 1))" + MINOR_PLUS_ONE=$((MINOR + 1)) + PATCH_PLUS_ONE=$((PATCH + 1)) + + # Correct vM.N.P + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR.$PATCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_eq "$?" "0" "$MAJOR.$MINOR.$PATCH versioned-tag vM.N.P ($MAJOR.$MINOR.$PATCH) should be correct" + + # Correct vM.N + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_eq "$?" "0" "$MAJOR.$MINOR versioned-tag vM.N ($MAJOR.$MINOR) should be correct" + + # Correct vM + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_eq "$?" "0" "$MAJOR versioned-tag vm ($MAJOR) should be correct" + + # Incorrect v(M-1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_LESS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_LESS_ONE versioned-tag should be incorrect" + + # Incorrect v(M-1).N + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_LESS_ONE.$MINOR" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_LESS_ONE.$MINOR versioned-tag should be incorrect" + + # Incorrect v(M-1).N.P + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_LESS_ONE.$MINOR.$PATCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_LESS_ONE.$MINOR.$PATCH versioned-tag should be incorrect" + + # Incorrect vM.(N-1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR_LESS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR_LESS_ONE versioned-tag should be incorrect" + + # Incorrect vM.(N-1).P + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR_LESS_ONE.$PATCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR_LESS_ONE.$PATCH versioned-tag should be incorrect" + + # Incorrect vM.N.(P-1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR.$PATCH_LESS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR.$PATCH_LESS_ONE versioned-tag should be incorrect" + + # Incorrect v(M+1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_PLUS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_PLUS_ONE versioned-tag should be incorrect" + + # Incorrect v(M+1).N + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_PLUS_ONE.$MINOR" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_PLUS_ONE.$MINOR versioned-tag should be incorrect" + + # Incorrect v(M+1).N.P + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR_PLUS_ONE.$MINOR.$PATCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR_PLUS_ONE.$MINOR.$PATCH versioned-tag should be incorrect" + + # Incorrect vM.(N+1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR_PLUS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR_PLUS_ONE versioned-tag should be incorrect" + + # Incorrect vM.(N+1).P + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR_PLUS_ONE.$PATCH" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR_PLUS_ONE.$PATCH versioned-tag should be incorrect" + + # Incorrect vM.N.(P+1) + slsa-verifier --branch "$BRANCH" --versioned-tag "$MAJOR.$MINOR.$PATCH_PLUS_ONE" --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "$MAJOR.$MINOR.$PATCH_PLUS_ONE versioned-tag should be incorrect" +else + # Wrong versioned-tag + slsa-verifier --branch "$BRANCH" --versioned-tag v1.2.3 --artifact-path "$BINARY" --provenance "$PROVENANCE" --source "github.com/$GITHUB_REPOSITORY" + e2e_assert_not_eq "$?" "0" "wrong versioned-tag" +fi + +# Provenance content verification. +ATTESTATION=$(jq -r '.payload' <"$PROVENANCE" | base64 -d) +LDFLAGS=$(echo "$THIS_FILE" | cut -d '.' -f5 | grep -v noldflags) +ASSETS=$(echo "$THIS_FILE" | cut -d '.' -f5 | grep -v noassets) +DIR="$PWD" +e2e_verify_predicate_subject_name "$ATTESTATION" "$BINARY" +e2e_verify_predicate_builder_id "$ATTESTATION" "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@refs/heads/main" +e2e_verify_predicate_builderType "$ATTESTATION" "https://github.com/slsa-framework/slsa-github-generator-go@v1" + +e2e_verify_predicate_invocation_configSource "$ATTESTATION" "{\"uri\":\"git+https://github.com/$GITHUB_REPOSITORY@$GITHUB_REF\",\"digest\":{\"sha1\":\"$GITHUB_SHA\"},\"entryPoint\":\"$GITHUB_WORKFLOW\"}" + +e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_actor" "$GITHUB_ACTOR" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_sha1" "$GITHUB_SHA" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "os" "ubuntu20" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "arch" "X64" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_event_name" "$GITHUB_EVENT_NAME" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_ref" "$GITHUB_REF" +e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_ref_type" "$GITHUB_REF_TYPE" + +# First step is vendoring +e2e_verify_predicate_buildConfig_step_command "0" "$ATTESTATION" "[\"mod\",\"vendor\"]" +e2e_verify_predicate_buildConfig_step_env "0" "$ATTESTATION" "[]" +e2e_verify_predicate_buildConfig_step_workingDir "0" "$ATTESTATION" "$DIR" + +# Second step is the actual compilation. +e2e_verify_predicate_buildConfig_step_env "1" "$ATTESTATION" "[\"GOOS=linux\",\"GOARCH=amd64\",\"GO111MODULE=on\",\"CGO_ENABLED=0\"]" +e2e_verify_predicate_buildConfig_step_workingDir "1" "$ATTESTATION" "$DIR" + +if [[ -z "$LDFLAGS" ]]; then + e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-o\",\"$BINARY\"]" +else + chmod a+x ./"$BINARY" + + if [[ -z "$GO_MAIN" ]]; then + e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-ldflags=-X main.gitVersion=v1.2.3 -X main.gitCommit=abcdef -X main.gitBranch=$BRANCH\",\"-o\",\"$BINARY\"]" + else + e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-ldflags=-X main.gitVersion=v1.2.3 -X main.gitCommit=abcdef -X main.gitBranch=$BRANCH -X main.gitMain=$GO_MAIN\",\"-o\",\"$BINARY\",\"$GO_MAIN\"]" + M=$(./"$BINARY" | grep "GitMain: $GO_MAIN") + e2e_assert_not_eq "$M" "" "GitMain should not be empty" + fi + + V=$(./"$BINARY" | grep 'GitVersion: v1.2.3') + C=$(./"$BINARY" | grep 'GitCommit: abcdef') + B=$(./"$BINARY" | grep "GitBranch: $BRANCH") + e2e_assert_not_eq "$V" "" "GitVersion should not be empty" + e2e_assert_not_eq "$C" "" "GitCommit should not be empty" + e2e_assert_not_eq "$B" "" "GitBranch should not be empty" +fi + +e2e_verify_predicate_metadata "$ATTESTATION" "{\"buildInvocationID\":\"$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT\",\"completeness\":{\"parameters\":true,\"environment\":false,\"materials\":false},\"reproducible\":false}" +e2e_verify_predicate_materials "$ATTESTATION" "{\"uri\":\"git+https://github.com/$GITHUB_REPOSITORY@$GITHUB_REF\",\"digest\":{\"sha1\":\"$GITHUB_SHA\"}}" + +if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then + A=$(gh release view --json assets "$GITHUB_REF_NAME" | jq -r '.assets | .[0].name, .[1].name' | jq -R -s -c 'split("\n") | map(select(length > 0))') + if [[ -z "$ASSETS" ]]; then + e2e_assert_eq "$A" "[\"null\",\"null\"]" "there should be no assets" + else + e2e_assert_eq "$A" "[\"$BINARY\",\"$BINARY.intoto.jsonl\"]" "there should be assets" + fi +fi + +#TODO: read out the provenance information once we print it +#TODO: previous releases, curl the "$BINARY" directly. We should list the releases and run all commands automatically From 283a2298653fc2b70ecf2819d64f55d491d9efc7 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 06:25:29 +0000 Subject: [PATCH 4/6] Update e2e test --- ...2e.generic.schedule.main.default.slsa2.yml | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml index 72f63fdc33..b954afce36 100644 --- a/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml +++ b/.github/workflows/e2e.generic.schedule.main.default.slsa2.yml @@ -7,39 +7,50 @@ on: jobs: build: outputs: - binary-name: ${{ steps.hash.outputs.binary-name }} + binary-name: ${{ steps.build.outputs.binary-name }} digest: ${{ steps.hash.outputs.digest }} runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 + - name: Setup Go + uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 + with: + go-version: "1.18" - name: Build artifact - run: bazelisk build //:hello + id: build + run: | + go mod vendor + + go build -mod=vendor -o hello . + + echo "::set-output name=binary-name::hello" + - name: Upload binary + uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2.3.1 + with: + name: ${{ steps.build.outputs.binary-name }} + path: ${{ steps.build.outputs.binary-name }} + if-no-files-found: error + retention-days: 5 - name: Generate hash shell: bash id: hash + env: + BINARY_NAME: ${{ steps.build.outputs.binary-name }} run: | set -euo pipefail - cp bazel-bin/hello_/hello ./hello - DIGEST=$(sha256sum hello) + DIGEST=$(sha256sum $BINARY_NAME) DIGEST="${DIGEST//'%'/'%25'}" DIGEST="${DIGEST//$'\n'/'%0A'}" DIGEST="${DIGEST//$'\r'/'%0D'}" - echo "::set-output name=binary-name::hello" echo "::set-output name=digest::$DIGEST" - - name: Upload artifact - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2.3.1 - with: - name: ${{ steps.outputs.binary-name }} - path: ${{ steps.outputs.binary-name }} - if-no-files-found: error - retention-days: 5 provenance: needs: [build] permissions: id-token: write contents: read + actions: read uses: slsa-framework/slsa-github-generator/.github/workflows/slsa2_provenance.yml@main with: subjects: "${{ needs.build.outputs.digest }}" @@ -66,7 +77,7 @@ jobs: env: BINARY: ${{ needs.build.outputs.binary-name }} PROVENANCE: ${{ needs.provenance.outputs.attestation-name }} - run: ./.github/workflows/scripts/e2e-verify.sh + run: ./.github/workflows/scripts/e2e.generic.default.verify.sh if-succeeded: runs-on: ubuntu-latest From 031eea26f2f1eabcf2c8d20a6c95b4ae3367e866 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 06:31:11 +0000 Subject: [PATCH 5/6] Update push e2e test --- .../e2e.generic.push.main.default.slsa2.yml | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/.github/workflows/e2e.generic.push.main.default.slsa2.yml b/.github/workflows/e2e.generic.push.main.default.slsa2.yml index fdea03a5ab..b49446da9a 100644 --- a/.github/workflows/e2e.generic.push.main.default.slsa2.yml +++ b/.github/workflows/e2e.generic.push.main.default.slsa2.yml @@ -24,27 +24,43 @@ jobs: build: if: github.event_name == 'push' && github.event.head_commit.message == github.workflow outputs: - binary-name: ${{ steps.hash.outputs.binary-name }} + binary-name: ${{ steps.build.outputs.binary-name }} digest: ${{ steps.hash.outputs.digest }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - run: bazelisk build //:hello - - uses: actions/upload-artifact@v3 + - name: Checkout code + uses: actions/checkout@v3 + - name: Setup Go + uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2.2.0 with: - path: bazel-bin/hello_/hello - - name: "generate hash" + go-version: "1.18" + - name: Build artifact + id: build + run: | + go mod vendor + + go build -mod=vendor -o hello . + + echo "::set-output name=binary-name::hello" + - name: Upload binary + uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2.3.1 + with: + name: ${{ steps.build.outputs.binary-name }} + path: ${{ steps.build.outputs.binary-name }} + if-no-files-found: error + retention-days: 5 + - name: Generate hash shell: bash id: hash + env: + BINARY_NAME: ${{ steps.build.outputs.binary-name }} run: | set -euo pipefail - DIGEST=$(sha256sum bazel-bin/hello_/hello) + DIGEST=$(sha256sum $BINARY_NAME) DIGEST="${DIGEST//'%'/'%25'}" DIGEST="${DIGEST//$'\n'/'%0A'}" DIGEST="${DIGEST//$'\r'/'%0D'}" - echo "::set-output name=binary-name::hello" echo "::set-output name=digest::$DIGEST" - # TODO: upload binary artifact provenance: if: github.event_name == 'push' && github.event.head_commit.message == github.workflow @@ -74,8 +90,7 @@ jobs: - env: BINARY: ${{ needs.build.outputs.go-binary-name }} PROVENANCE: ${{ needs.provenance.outputs.attestation-name }} - # TODO: Write provenance-only verify script. - run: ./.github/workflows/scripts/e2e-verify.sh + run: ./.github/workflows/scripts/e2e.generic.default.verify.sh if-succeeded: runs-on: ubuntu-latest From a683fe9a86c1d36f477d8d117fe542c3d9af3357 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Tue, 31 May 2022 06:34:52 +0000 Subject: [PATCH 6/6] cleanup verify script --- .../scripts/e2e.generic.default.verify.sh | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/.github/workflows/scripts/e2e.generic.default.verify.sh b/.github/workflows/scripts/e2e.generic.default.verify.sh index 029e923b8d..6572b2e406 100644 --- a/.github/workflows/scripts/e2e.generic.default.verify.sh +++ b/.github/workflows/scripts/e2e.generic.default.verify.sh @@ -119,7 +119,6 @@ fi # Provenance content verification. ATTESTATION=$(jq -r '.payload' <"$PROVENANCE" | base64 -d) -LDFLAGS=$(echo "$THIS_FILE" | cut -d '.' -f5 | grep -v noldflags) ASSETS=$(echo "$THIS_FILE" | cut -d '.' -f5 | grep -v noassets) DIR="$PWD" e2e_verify_predicate_subject_name "$ATTESTATION" "$BINARY" @@ -130,53 +129,9 @@ e2e_verify_predicate_invocation_configSource "$ATTESTATION" "{\"uri\":\"git+http e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_actor" "$GITHUB_ACTOR" e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_sha1" "$GITHUB_SHA" -e2e_verify_predicate_invocation_environment "$ATTESTATION" "os" "ubuntu20" -e2e_verify_predicate_invocation_environment "$ATTESTATION" "arch" "X64" e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_event_name" "$GITHUB_EVENT_NAME" e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_ref" "$GITHUB_REF" e2e_verify_predicate_invocation_environment "$ATTESTATION" "github_ref_type" "$GITHUB_REF_TYPE" -# First step is vendoring -e2e_verify_predicate_buildConfig_step_command "0" "$ATTESTATION" "[\"mod\",\"vendor\"]" -e2e_verify_predicate_buildConfig_step_env "0" "$ATTESTATION" "[]" -e2e_verify_predicate_buildConfig_step_workingDir "0" "$ATTESTATION" "$DIR" - -# Second step is the actual compilation. -e2e_verify_predicate_buildConfig_step_env "1" "$ATTESTATION" "[\"GOOS=linux\",\"GOARCH=amd64\",\"GO111MODULE=on\",\"CGO_ENABLED=0\"]" -e2e_verify_predicate_buildConfig_step_workingDir "1" "$ATTESTATION" "$DIR" - -if [[ -z "$LDFLAGS" ]]; then - e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-o\",\"$BINARY\"]" -else - chmod a+x ./"$BINARY" - - if [[ -z "$GO_MAIN" ]]; then - e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-ldflags=-X main.gitVersion=v1.2.3 -X main.gitCommit=abcdef -X main.gitBranch=$BRANCH\",\"-o\",\"$BINARY\"]" - else - e2e_verify_predicate_buildConfig_step_command "1" "$ATTESTATION" "[\"build\",\"-mod=vendor\",\"-trimpath\",\"-tags=netgo\",\"-ldflags=-X main.gitVersion=v1.2.3 -X main.gitCommit=abcdef -X main.gitBranch=$BRANCH -X main.gitMain=$GO_MAIN\",\"-o\",\"$BINARY\",\"$GO_MAIN\"]" - M=$(./"$BINARY" | grep "GitMain: $GO_MAIN") - e2e_assert_not_eq "$M" "" "GitMain should not be empty" - fi - - V=$(./"$BINARY" | grep 'GitVersion: v1.2.3') - C=$(./"$BINARY" | grep 'GitCommit: abcdef') - B=$(./"$BINARY" | grep "GitBranch: $BRANCH") - e2e_assert_not_eq "$V" "" "GitVersion should not be empty" - e2e_assert_not_eq "$C" "" "GitCommit should not be empty" - e2e_assert_not_eq "$B" "" "GitBranch should not be empty" -fi - e2e_verify_predicate_metadata "$ATTESTATION" "{\"buildInvocationID\":\"$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT\",\"completeness\":{\"parameters\":true,\"environment\":false,\"materials\":false},\"reproducible\":false}" e2e_verify_predicate_materials "$ATTESTATION" "{\"uri\":\"git+https://github.com/$GITHUB_REPOSITORY@$GITHUB_REF\",\"digest\":{\"sha1\":\"$GITHUB_SHA\"}}" - -if [[ "$GITHUB_REF_TYPE" == "tag" ]]; then - A=$(gh release view --json assets "$GITHUB_REF_NAME" | jq -r '.assets | .[0].name, .[1].name' | jq -R -s -c 'split("\n") | map(select(length > 0))') - if [[ -z "$ASSETS" ]]; then - e2e_assert_eq "$A" "[\"null\",\"null\"]" "there should be no assets" - else - e2e_assert_eq "$A" "[\"$BINARY\",\"$BINARY.intoto.jsonl\"]" "there should be assets" - fi -fi - -#TODO: read out the provenance information once we print it -#TODO: previous releases, curl the "$BINARY" directly. We should list the releases and run all commands automatically