constellation/.github/actions/constellation_measure/action.yml
2022-09-02 19:08:33 +02:00

120 lines
4.9 KiB
YAML

name: Constellation measure
description: |
Create measurements of a Constellation cluster and print to stdout.
Optionally sign and/or upload to S3, if corresponding inputs are provided.
inputs:
cloudProvider:
description: "Either 'gcp' or 'azure'."
required: true
cosignPublicKey:
description: "Cosign public key"
required: false
default: ""
cosignPrivateKey:
description: "Cosign private key"
required: false
default: ""
cosignPassword:
description: "Password for Cosign private key"
required: false
default: ""
awsAccessKeyID:
description: "AWS access key ID to upload measurements"
required: false
default: ""
awsSecretAccessKey:
description: "AWS secret access key to upload measurements"
required: false
default: ""
awsDefaultRegion:
description: "AWS region of S3 bucket to upload measurements"
required: false
default: ""
awsBucketName:
description: "S3 bucket name to upload measurements to"
required: false
default: ""
runs:
using: "composite"
steps:
- name: Build hack/pcr-reader
run: |
go build .
echo "$(pwd)" >> $GITHUB_PATH
working-directory: hack/pcr-reader
shell: bash
# Check /docs/secure_software_distribution.md#sign-measurements
# for why we ignore certain measurement values.
- name: Fetch PCRs
run: |
KUBECONFIG="$PWD/constellation-admin.conf" kubectl rollout status ds/verification-service -n kube-system --timeout=3m
CONSTELL_IP=$(jq -r ".bootstrapperhost" constellation-state.json)
pcr-reader --constell-ip ${CONSTELL_IP} -format yaml > measurements.yaml
case $CSP in
azure)
yq e 'del(.[0,6,10,11,12,13,14,15,16,17,18,19,20,21,22,23])' -i measurements.yaml
;;
gcp)
yq e 'del(.[11,12,13,14,15,16,17,18,19,20,21,22,23])' -i measurements.yaml
;;
esac
cat measurements.yaml
shell: bash
env:
CSP: ${{ inputs.cloudProvider }}
# TODO: Replace with https://github.com/sigstore/sigstore-installer/tree/initial
# once it has the functionality
- name: Install Cosign
uses: sigstore/cosign-installer@48866aa521d8bf870604709cd43ec2f602d03ff2
if: ${{ inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' }}
- name: Install Rekor
run: |
curl -sLO https://github.com/sigstore/rekor/releases/download/v0.9.0/rekor-cli-linux-amd64
sudo install rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
shell: bash
if: ${{ inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' }}
- name: Sign measurements
run: |
echo "$COSIGN_PUBLIC_KEY" > cosign.pub
# Enabling experimental mode also publishes signature to Rekor
COSIGN_EXPERIMENTAL=1 cosign sign-blob --key env://COSIGN_PRIVATE_KEY measurements.yaml > measurements.yaml.sig
# Verify - As documentation & check
# Local Signature (input: artifact, key, signature)
cosign verify-blob --key cosign.pub --signature measurements.yaml.sig measurements.yaml
# Transparency Log Signature (input: artifact, key)
uuid=$(rekor-cli search --artifact measurements.yaml | tail -n 1)
sig=$(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.content)
cosign verify-blob --key cosign.pub --signature <(echo $sig) measurements.yaml
shell: bash
env:
COSIGN_PUBLIC_KEY: ${{ inputs.cosignPublicKey }}
COSIGN_PRIVATE_KEY: ${{ inputs.cosignPrivateKey }}
COSIGN_PASSWORD: ${{ inputs.cosignPassword }}
if: ${{ inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' }}
- name: Install AWS CLI
run: |
echo "::group::Install AWS CLI"
sudo apt-get update && sudo apt-get -y install awscli
echo "::endgroup::"
shell: bash
if: ${{ inputs.awsAccessKeyID != '' && inputs.awsSecretAccessKey != '' && inputs.awsDefaultRegion != '' && inputs.awsBucketName != '' }}
- name: Upload to S3
run: |
IMAGE=$(yq e ".provider.${CSP}.image" constellation-conf.yaml)
S3_PATH=s3://${PUBLIC_BUCKET_NAME}/${IMAGE}
aws s3 cp measurements.yaml ${S3_PATH}/measurements.yaml
if test -f measurements.yaml.sig; then
aws s3 cp measurements.yaml.sig ${S3_PATH}/measurements.yaml.sig
fi
shell: bash
env:
AWS_ACCESS_KEY_ID: ${{ inputs.awsAccessKeyID }}
AWS_SECRET_ACCESS_KEY: ${{ inputs.awsSecretAccessKey }}
AWS_DEFAULT_REGION: ${{ inputs.awsDefaultRegion }}
PUBLIC_BUCKET_NAME: ${{ inputs.awsBucketName }}
CSP: ${{ inputs.cloudProvider }}
if: ${{ inputs.awsAccessKeyID != '' && inputs.awsSecretAccessKey != '' && inputs.awsDefaultRegion != '' && inputs.awsBucketName != '' }}