2022-07-13 08:04:46 -04:00
|
|
|
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:
|
|
|
|
# Check /docs/secure_software_distribution.md#sign-measurements
|
|
|
|
# for why we ignore certain measurement values.
|
|
|
|
- name: Fetch PCRs
|
|
|
|
run: |
|
|
|
|
case $CSP in
|
|
|
|
azure)
|
2022-07-18 08:00:57 -04:00
|
|
|
FIRST_NODE=$(jq -r ".azurecontrolplanes | keys | first" constellation-state.json)
|
|
|
|
CONSTELL_IP=$(jq -r ".azurecontrolplanes.\"${FIRST_NODE}\".PublicIP" constellation-state.json)
|
2022-07-13 08:04:46 -04:00
|
|
|
pcr-reader --constell-ip ${CONSTELL_IP} -format yaml > measurements.yaml
|
|
|
|
yq e 'del(.[0,6,10,11,12,13,14,15,16,17,18,19,20,21,22,23])' -i measurements.yaml
|
|
|
|
;;
|
|
|
|
gcp)
|
2022-07-18 08:00:57 -04:00
|
|
|
FIRST_NODE=$(jq -r ".gcpcontrolplanes | keys | first" constellation-state.json)
|
|
|
|
CONSTELL_IP=$(jq -r ".gcpcontrolplanes.\"${FIRST_NODE}\".PublicIP" constellation-state.json)
|
2022-07-13 08:04:46 -04:00
|
|
|
pcr-reader --constell-ip ${CONSTELL_IP} -format yaml > measurements.yaml
|
|
|
|
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@main
|
|
|
|
if: ${{ inputs.cosignPublicKey != '' && inputs.cosignPrivateKey != '' && inputs.cosignPassword != '' }}
|
|
|
|
- name: Install Rekor
|
|
|
|
run: |
|
|
|
|
curl -LO 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: |
|
|
|
|
set -e
|
|
|
|
set -o pipefail
|
|
|
|
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: sudo apt-get update && sudo apt-get -y install awscli
|
|
|
|
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 != '' }}
|