NAIS SLSA Provenance Action
About
The project is started as an initiative by NAIS
NAV's Application Infrastructure Service
to establishing a Level 2 cryptographic chain of custody between trusted builds and our
release and code-signing workflows. SLSA is a framework intended to codify and
promote secure software supply-chain practices. This GitHub Action can be used to create, upload,
sign and verify a SBOM / in-toto attestation
also called a provenance using cosign. All
predicate payloads are signed using the DSSE.
This is not an official GitHub Action set up and maintained by the SLSA team. This GitHub Action is built to provide
teams and developers with the ability to trace software back to the source and define the moving parts in a complex
supply chain.
SLSA Security Levels
SLSA is organized into a series of levels that provide increasing integrity
guarantees. This gives the action user confidence that software hasn’t been tampered with and can be securely traced
back to its source.
Level 2 After the build
This Action fulfills the requirements for level 2 and shows more trustworthiness in
the build, builders are source-aware, and signatures are used to prevent provenance being tampered with.
Materials
This actions creates attestation with materials based on dependencies, the
action digest over listed dependencies from a supported build tool.
Support
Usage
In the examples below we are also using 2 other required
actions:
Not required
:
Key Management
This action use cosign with
supported Google KMS keys for signing and verifying the
attestation. Cosign supports all the
standard key management systems. If your project requires other
providers please feel free to submit an issue
or pull request.
Setup
KMS with cosign requires som pre-setup at you provider, in short for Google KMS:
- KMS is enabled in Google project
- create keyring
- create keys:
Elliptic Curve P-256 key SHA256 Digest
- Serviceuser in project has roles:
- Cloud KMS CryptoKey signer/verifier
- Cloud KMS viewer Role
- Set actions secret in github.com containing the serviceuser credentials.
- Set
with.key
to the right URI format for
Google: gcpkms://projects/$PROJECT/locations/$LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY/versions/$KEY_VERSION
Other KMS providers
NB! This is not tested, but theoretically it should be possible to switch Key Management provider
from Google Action with for example Azure Action. Please
see cosign KMS
for more information about setup and URI formats.
Example
Workflows
name: ci
on:
push:
branches:
- 'main'
env:
IMAGE: ttl.sh/nais/salsa-test:1h
KEY: gcpkms://projects/$PROJECT/locations/$LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY/versions/$KEY_VERSION
jobs:
provenance:
runs-on: ubuntu-20.04
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: 'Authenticate to Google Cloud'
id: 'google'
uses: 'google-github-actions/auth@v0'
with:
credentials_json: ${{ secrets.GCP_CREDENTIALS }}
- name: Build and push
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ env.IMAGE }}
- name: Provenance, upload and sign attestation
uses: nais/salsa@v0.0.1-alpha-10
with:
image: ${{ env.IMAGE }}
key: ${{ env.KEY }}
docker_user: ${{ github.actor }}
docker_pwd: ${{ secrets.GITHUB_TOKEN }}
Attestation
Customizing
Git context
The github context contains information about the workflow run and the event that triggered the run. By default, this
action uses the Git context.
Runner Context
The runner context contains information about the runner that is executing the current job. By default, this action uses
the Runner context.
The Following inputs can be used as step.with
keys
Name |
Type |
Default |
Description |
Required |
key |
String |
"" |
The key used to sign the attestation |
True |
docker_user |
String |
"" |
User to login to docker |
True |
docker_pwd |
String |
"" |
Pwd to login to docker |
True |
image |
String |
$ENV_IMAGE |
Docker image to sign |
True |
repo_name |
String |
github.repository |
This will name the generated provenance |
False |
repo_sub_dir |
String |
"" |
Specify a sub directory if build file not found in working root directory |
False |
dependencies |
Bool |
true |
Should the action digest dependencies |
False |
repo_dir |
String |
$GITHUB_WORKSPACE |
Internal value (do notset): Root of directory to look for build files |
False |
github_context |
String |
${{ toJSON(github) }} |
Internal value (do notset): the github context object in json |
False |
runner_context |
String |
${{ toJSON(runner) }} |
Internal value (do notset): the runner context object in json |
False |