-
Notifications
You must be signed in to change notification settings - Fork 4
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
Add SCAI reusable actions (KubeCon NA '23 Demo) #13
Changes from all commits
8ff0291
08c34e6
084001d
eb77ed7
594ece2
bf88711
81ddce5
5eced77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: "SCAI AttributeAssertion generator" | ||
description: "Generates a SCAI AttributeAssertion with evidence" | ||
inputs: | ||
attribute: | ||
description: "The attribute being asserted" | ||
required: true | ||
evidence-file: | ||
description: "The file containing the evidence. This action assumes the evidence was an artifact uploaded during a previous step, unless otherwise specified." | ||
required: true | ||
evidence-path: | ||
description: "The path to the evidence file. Defaults to GITHUB_WORKSPACE." | ||
required: false | ||
default: "$GITHUB_WORKSPACE" | ||
evidence-type: | ||
description: "The media type of the evidence" | ||
required: optional | ||
default: "application/json" | ||
download-evidence: | ||
description: "Flag to download the evidence artifact" | ||
required: false | ||
default: 'true' | ||
assertion-name: | ||
description: "The artifact name of the unsigned SCAI AttributeAssertion. The file must have the .json extension. Defaults to <attribute>-assert.json when not specified." | ||
required: false | ||
default: "scai-assertion.json" | ||
assertion-path: | ||
description: "The path to save the generated assertion" | ||
default: "$GITHUB_WORKSPACE/temp" | ||
outputs: | ||
assertion-name: | ||
description: "Filename of the generated AttributeAssertion" | ||
value: ${{ steps.scai-gen-assert.outputs.assertion-name }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Get the evidence artifact | ||
id: get-evidence | ||
if: ${{ inputs.download-evidence == 'true' }} | ||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 | ||
with: | ||
name: "${{ inputs.evidence-file }}" | ||
|
||
- name: Generate ResourceDescriptor for evidence | ||
id: gen-rd | ||
uses: ./.github/actions/scai-gen-rd | ||
with: | ||
name: "${{ inputs.evidence-file }}" | ||
path: "${{ inputs.evidence-path }}" | ||
media-type: "${{ inputs.evidence-type }}" | ||
rd-name: "${{ inputs.evidence-file }}-desc.json" | ||
|
||
- name: Run scai-gen assert | ||
id: scai-gen-assert | ||
shell: bash | ||
run: | | ||
mkdir -p ${{ inputs.assertion-path }} | ||
scai-gen assert -e ${{ steps.gen-rd.outputs.file-rd-name }} -o ${{ inputs.assertion-path }}/${{ inputs.assertion-name }} ${{ inputs.attribute}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you use the full flag names instead of the short ones? I think it makes it more readable in this context and possibly more maintainable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! I'll make these changes as part of a follow-up PR that focuses on readability and usability of the demo, so I can unblock testing on the implementer end. |
||
echo "assertion-name=${{ inputs.assertion-path }}/${{ inputs.assertion-name }}" >> "$GITHUB_OUTPUT" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
name: "in-toto ResourceDescriptor generator" | ||
description: "Generates an in-toto ResourceDescriptor for a local file or remote resource" | ||
inputs: | ||
is-file: | ||
description: "Flag indicating whether the resource is a local file or remote. Default is `is-file=true`." | ||
required: false | ||
default: 'true' | ||
name: | ||
description: "The name of the resource file." | ||
required: true | ||
path: | ||
description: "The path to the resource file. Defaults to GITHUB_WORKSPACE." | ||
required: false | ||
default: "$GITHUB_WORKSPACE" | ||
uri: | ||
description: "The URI of the remote resource." | ||
required: false | ||
default: "https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA" | ||
digest: | ||
description: "The digest associated with the remote resource (hex-encoded)" | ||
required: false | ||
default: "" | ||
hash-alg: | ||
description: "The hash algorithm used to compute the digest associated with the remote resource." | ||
required: false | ||
default: "sha256" | ||
location: | ||
description: "The download location of the file" | ||
required: false | ||
default: "https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" | ||
media-type: | ||
description: "The media type of the file" | ||
required: false | ||
default: "text/plain" | ||
rd-name: | ||
description: "The name of the output ResourceDescriptor file. The file must have the .json extension." | ||
required: true | ||
rd-path: | ||
description: "The path to save the generated descriptor" | ||
default: "$GITHUB_WORKSPACE/temp" | ||
outputs: | ||
file-rd-name: | ||
description: "Filename of the generated ResourceDescriptor" | ||
value: ${{ steps.scai-gen-rd-file.outputs.rd-name }} | ||
remote-rd-name: | ||
description: "Filename of the generated ResourceDescriptor" | ||
value: ${{ steps.scai-gen-rd-remote.outputs.rd-name }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Run scai-gen rd file | ||
id: scai-gen-rd-file | ||
if: ${{ inputs.is-file == 'true' }} | ||
shell: bash | ||
run: | | ||
mkdir -p ${{ inputs.rd-path }} | ||
scai-gen rd file -n ${{ inputs.name }} -l ${{ inputs.location }} -t ${{ inputs.media-type }} -o ${{ inputs.rd-path }}/${{ inputs.rd-name }} ${{ inputs.path }}/${{ inputs.name }} | ||
echo "rd-name=${{ inputs.rd-path }}/${{ inputs.rd-name }}" >> "$GITHUB_OUTPUT" | ||
|
||
- name: Run scai-gen rd remote | ||
id: scai-gen-rd-remote | ||
if: ${{ inputs.is-file == 'false' }} | ||
shell: bash | ||
run: | | ||
mkdir -p ${{ inputs.rd-path }} | ||
scai-gen rd remote -n ${{ inputs.name }} -d ${{ inputs.digest }} -g ${{ inputs.hash-alg }} -o ${{ inputs.rd-path }}/${{ inputs.rd-name }} ${{ inputs.uri }} | ||
echo "rd-name=${{ inputs.rd-path }}/${{ inputs.rd-name }}" >> "$GITHUB_OUTPUT" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: "scai-gen-report" | ||
description: "Generates a signed SCAI AttributeReport" | ||
inputs: | ||
subject: | ||
description: "The subject ResourceDescriptor. This action currently assumes a single subject." | ||
required: true | ||
attr-assertions: | ||
description: "The names of the SCAI AttributeAssertions to be listed in the Report. This action assumes the Assertions were generated using the scai-gen-assert action." | ||
required: true | ||
report-name: | ||
description: "The name of the AttributeReport file" | ||
required: false | ||
default: "scai-report.json" | ||
report-path: | ||
description: "The directory to place the in-toto SCAI predicate attestation" | ||
required: false | ||
default: "$GITHUB_WORKSPACE/temp" | ||
outputs: | ||
report-name: | ||
description: "Filename of the generated AttributeReport" | ||
value: ${{ steps.scai-gen-report.outputs.report-name }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Run scai-gen rd file | ||
id: scai-gen-report | ||
shell: bash | ||
run: | | ||
mkdir -p ${{ inputs.report-path }} | ||
scai-gen report -s ${{ inputs.subject }} -o ${{ inputs.report-path }}/${{ inputs.report-name }} ${{ inputs.attr-assertions }} | ||
echo "report-name=${{ inputs.report-path }}/${{ inputs.report-name }}" >> "$GITHUB_OUTPUT" | ||
ls ${{ inputs.report-path }} | ||
|
||
- name: Upload the signed SCAI AttributeReport | ||
id: upload-assert | ||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 | ||
with: | ||
name: ${{ inputs.report-name }} | ||
path: ${{ steps.scai-gen-report.outputs.report-name }} | ||
retention-days: 15 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: "in-toto Sigstore signer" | ||
description: "Generates a signed in-toto Attestation using cosign, and uploads it to the public Rekor log" | ||
inputs: | ||
save-signed: | ||
description: "Flag indicating whether to save the signed attestation as a local artifact (using actions/upload-artifact). Default is `save-signed=true`." | ||
required: false | ||
default: 'true' | ||
statement-file: | ||
description: "The name of the unsigned in-toto Statement file." | ||
required: true | ||
statement-path: | ||
description: "The path to the statement-file. Defaults to GITHUB_WORKSPACE." | ||
required: false | ||
default: "$GITHUB_WORKSPACE" | ||
attestation-name: | ||
description: "The name of the DSSE formatted signed in-toto Attestation file." | ||
required: true | ||
attestation-path: | ||
description: "The directory to place the signed in-toto Attestation." | ||
required: false | ||
default: "$GITHUB_WORKSPACE/attestations" | ||
|
||
outputs: | ||
attestation-name: | ||
description: "Filename of the generated signed in-toto Attestation" | ||
value: ${{ steps.sign.outputs.attestation-name }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Sign and upload in-toto Statement | ||
id: sign | ||
shell: bash | ||
run: | | ||
mkdir -p ${{ inputs.attestation-path }} | ||
scai-gen sigstore -o ${{ inputs.attestation-path}}/${{ inputs.attestation-name }} ${{ inputs.statement-path }}/${{ inputs.statement-name }} | ||
echo "attestation-name=${{ inputs.attestation-path }}/${{ inputs.attestation-name }}" >> "$GITHUB_OUTPUT" | ||
|
||
- name: Save the signed in-toto Attestation | ||
if: ${{ inputs.save-signed == 'true' }} | ||
id: upload-signed | ||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 | ||
with: | ||
name: ${{ steps.sign.inputs.attestation-name }} | ||
path: ${{ steps.sign.outputs.attestation-name }} | ||
retention-days: 15 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
name: Test composite actions on SBOM+SLSA example | ||
on: | ||
push: | ||
branch: | ||
- main | ||
paths: | ||
- "scai-gen/**" | ||
# Want to trigger these tests whenever the Go CLI or | ||
# APIs are modified | ||
pull_request: | ||
paths: | ||
- "scai-gen/**" | ||
|
||
jobs: | ||
sbom-slsa-ex: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Install Go | ||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe | ||
with: | ||
go-version: 1.20.x | ||
|
||
- name: Checkout updated scai-gen CLI tools | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 | ||
|
||
- name: Setup Env | ||
run: | | ||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH | ||
|
||
- name: Install scai-gen CLI tools | ||
shell: bash | ||
run: | | ||
go install ./scai-gen | ||
mkdir -p temp | ||
|
||
- name: Generate SBOM SCAI AttributeAssertion | ||
id: gen-sbom-assert | ||
uses: ./.github/actions/scai-gen-assert | ||
with: | ||
attribute: "HasSBOM" | ||
evidence-file: "pdo_client_wawaka.spdx.json" | ||
evidence-path: "examples/sbom+slsa/metadata" | ||
evidence-type: "application/json" | ||
download-evidence: false | ||
assertion-name: "hassbom-assertion.json" | ||
|
||
- name: Generate SLSA Provenance SCAI AttributeAssertion | ||
id: gen-slsa-assert | ||
uses: ./.github/actions/scai-gen-assert | ||
with: | ||
attribute: "HasSLSA" | ||
evidence-file: "pdo_client_wawaka.provenance.json" | ||
evidence-path: "examples/sbom+slsa/metadata" | ||
evidence-type: "application/vnd.in-toto.provenance+dsse" | ||
download-evidence: false | ||
assertion-name: "hasslsa-assertion.json" | ||
|
||
- name: Generate SCAI AttributeReport | ||
id: gen-sbom-slsa-report | ||
uses: ./.github/actions/scai-gen-report | ||
with: | ||
subject: "examples/sbom+slsa/metadata/container-img-desc.json" | ||
attr-assertions: "${{ steps.gen-sbom-assert.outputs.assertion-name }} ${{ steps.gen-slsa-assert.outputs.assertion-name }}" | ||
report-name: "evidence-collection.scai.json" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Test Sigstore integration | ||
on: | ||
# Want to trigger these tests whenever the Sigstore command | ||
# is modified and PR is closed and merged. | ||
# Reason: OIDC token access constraints in PRs | ||
pull_request: | ||
paths: | ||
- "scai-gen/cmd/sigstore.go" | ||
types: | ||
- closed | ||
|
||
jobs: | ||
sigstore: | ||
if: github.event.pull_request.merged == true | ||
runs-on: ubuntu-22.04 | ||
permissions: | ||
id-token: write # Needed for signing | ||
steps: | ||
- name: Install Go | ||
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe | ||
with: | ||
go-version: 1.20.x | ||
|
||
- name: Checkout updated scai-gen CLI tools | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 | ||
|
||
- name: Setup Env | ||
run: | | ||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH | ||
|
||
- name: Install scai-gen CLI tools | ||
shell: bash | ||
run: | | ||
go install ./scai-gen | ||
|
||
- name: Sign and upload SCAI report (Sigstore) | ||
id: sign-report | ||
shell: bash | ||
uses: ./.github/actions/scai-gen-sigstore | ||
with: | ||
statement-file: examples/sbom+slsa/metadata/evidence-collection.scai.json | ||
attestation-name: evidence-collection.scai.sig.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly out of scope but perhaps the output dir creation should be handled by
scai-gen assert
so that the action's usable even without mkdir. IDK if mkdir is aliased / supported on Windows, for example.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point, and shouldn't be too hard to implement, I hope. What I'll do is merge this PR so I can start testing this with my test build. I have some documentation for the demo in-flight (nothing major) that I think would fit well into a "make the demo more legible/usable" PR.