Skip to content
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 documentation and Cloud Build configs for releasing the recovery tool. #53

Merged
merged 7 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion recovery/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,48 @@
# Recovery

The Dockerfile in this directory is used for building an image to be used as a
recovery/provisioning tool for the armored witness.
recovery/provisioning tool for the Armored Witness.

We currently use the firmware in the github.com/usbarmory/armory-ums repo as
the recovery tool.

While that repo does offer prebuilt binary releases, we rebuild from scratch
here so we can be sure about which TamaGo toolchain version is used, etc.

## Build and Release Process

A
[Cloud Build trigger](https://cloud.google.com/build/docs/automating-builds/create-manage-triggers)
is defined by a yaml config file. The Transparency.dev team invokes it manually
when we want to publish a release.

The pipeline includes two main steps: building and making available the recovery
tool files, and writing the release metadata (Claimant Model Statement) to the
firmware transparency log.

1. Cloud Build builds the recovery builder Docker image and copies the compiled
recovery imx file to a public Google Cloud Storage bucket.
1. Cloud Build runs the
[`manifest`](https://github.com/transparency-dev/armored-witness/tree/main/cmd/manifest)
tool to construct the Claimant Model Statement with arguments specific to
this release. It signs the Statement with the
[`sign`](https://github.com/transparency-dev/armored-witness/tree/main/cmd/sign)
tool and adds the resulting signed Statement as an entry to the public
firmware transparency log.

TODO: add links for the GCS buckets once public.

## Claimant Model

| Role | Description |
| ----------- | ----------- |
| **Claimant** | Transparency.dev team |
| **Claim** | <ol><li>The digest of the recovery tool is derived from this source Github repository, and is reproducible.</li><li>The recovery tool is issued by the Transparency.dev team.</li></ol> |
| **Believer** | The [provision](https://github.com/transparency-dev/armored-witness/tree/main/cmd/provision) and [verify](https://github.com/transparency-dev/armored-witness/tree/main/cmd/verify) tools. |
| **Verifier** | <ol><li>For Claim #1: third party auditing the Transparency.dev team</li><li>For Claim #2: the Transparency.dev team</li></ol> |
| **Arbiter** | Log ecosystem participants and reliers |

The **Statement** is defined in
[https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog/log_entries.go](https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog/log_entries.go).
An example is available at
[https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog//example_firmware_release.json](https://github.com/transparency-dev/armored-witness-common/tree/main/release/firmware/ftlog//example_firmware_release.json).
141 changes: 141 additions & 0 deletions recovery/cloudbuild_ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
steps:
### Build the recovery binary and upload it to GCS.
# Build an image containing the trusted applet artifacts with the Dockerfile.
- name: gcr.io/cloud-builders/docker
args:
- build
- --build-arg
- TAMAGO_VERSION=${_TAMAGO_VERSION}
- -t
- builder-image
- recovery
# Prepare a container with a copy of the artifacts.
- name: gcr.io/cloud-builders/docker
args:
- create
- --name
- builder_scratch
- builder-image
# Copy the artifacts from the container to the Cloud Build VM.
- name: gcr.io/cloud-builders/docker
args:
- cp
- builder_scratch:/build/armory-ums
- output
# List the artifacts.
- name: bash
args:
- ls
- output
# Copy the artifacts from the Cloud Build VM to GCS.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage cp \
output/armory-ums.imx \
gs://${_FIRMWARE_BUCKET}/$(sha256sum output/armory-ums.imx | cut -f1 -d" ")
### Construct log entry / Claimant Model statement.
# This step needs to be a bash script in order to substitute the fake tag in
# the command args.
- name: golang
entrypoint: bash
args:
- -c
- |
go run github.com/transparency-dev/armored-witness/cmd/manifest@${_ARMORED_WITNESS_REPO_VERSION} \
create \
--git_tag=${_MANUAL_TAG} \
--git_commit_fingerprint=${COMMIT_SHA} \
--firmware_file=output/armory-ums.imx \
--firmware_type=RECOVERY \
--tamago_version=${_TAMAGO_VERSION} \
--raw \
--output_file=output/recovery_manifest_unsigned.json
# Sign the log entry.
- name: golang
args:
- go
- run
- github.com/transparency-dev/armored-witness/cmd/sign@${_ARMORED_WITNESS_REPO_VERSION}
- --project_name=${PROJECT_ID}
- --release=ci
- --artefact=recovery
- --manifest_file=output/recovery_manifest_unsigned.json
- --output_file=output/recovery_manifest
# Print the content of the signed manifest.
- name: bash
args:
- cat
- output/recovery_manifest
### Write the firmware release to the transparency log.
# Copy the log entry to the sequence bucket, preparing to write to log.
#
# Use the SHA256 of the manifest as the name of the manifest. This allows
# multiple triggers to run without colliding.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage cp output/recovery_manifest \
gs://${_LOG_NAME}/${_ENTRIES_DIR}/$(sha256sum output/recovery_manifest | cut -f1 -d" ")
# Sequence log entry.
- - name: gcr.io/cloud-builders/gcloud
args:
- functions
- call
- sequence
- '--data'
- >-
{
"entriesDir": "${_ENTRIES_DIR}",
"origin": "${_ORIGIN}",
"bucket": "${_LOG_NAME}",
"kmsKeyName": "ft-log-ci",
"kmsKeyRing": "firmware-release-ci",
"kmsKeyVersion": ${_KEY_VERSION},
"kmsKeyLocation": "global",
"noteKeyName": "transparency.dev-aw-ftlog-ci",
"checkpointCacheControl": "${_CHECKPOINT_CACHE}"
}
# Integrate log entry.
- name: gcr.io/cloud-builders/gcloud
args:
- functions
- call
- integrate
- --data
- >-
{
"origin": "${_ORIGIN}",
"bucket": "${_LOG_NAME}",
"kmsKeyName": "ft-log-ci",
"kmsKeyRing": "firmware-release-ci",
"kmsKeyVersion": ${_KEY_VERSION},
"kmsKeyLocation": "global",
"noteKeyName": "transparency.dev-aw-ftlog-ci",
"checkpointCacheControl": "${_CHECKPOINT_CACHE}"
}
# Clean up the file we added to the _ENTRIES_DIR bucket now that it's been
# integrated to the log.
- name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
gcloud storage rm \
gs://${_LOG_NAME}/${_ENTRIES_DIR}/$(sha256sum output/recovery_manifest | cut -f1 -d" ")
substitutions:
# Build-related.
_FIRMWARE_BUCKET: armored-witness-firmware-ci-1
_MANUAL_TAG: 0.0.0
_TAMAGO_VERSION: '1.21.3'
# Log-related.
_ARMORED_WITNESS_REPO_VERSION: d37d6b19ec4dbd1cad3586ae8ba3ec913829d718
# This must correspond with the trailing number on the _FIRMWARE_BUCKET, _ORIGIN, _LOG_NAME values.
_KEY_VERSION: '1'
_LOG_NAME: armored-witness-firmware-log-ci-1
_ORIGIN: transparency.dev/armored-witness/firmware_transparency/ci/1
_CHECKPOINT_CACHE: 'public, max-age=30'
60 changes: 60 additions & 0 deletions recovery/cloudbuild_presubmit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
steps:
### Build the recovery binary and upload it to GCS.
# Build an image containing the trusted applet artifacts with the Dockerfile.
- name: gcr.io/cloud-builders/docker
args:
- build
- --build-arg
- TAMAGO_VERSION=${_TAMAGO_VERSION}
- -t
- builder-image
- recovery
# Prepare a container with a copy of the artifacts.
- name: gcr.io/cloud-builders/docker
args:
- create
- --name
- builder_scratch
- builder-image
# Copy the artifacts from the container to the Cloud Build VM.
- name: gcr.io/cloud-builders/docker
args:
- cp
- builder_scratch:/build/armory-ums
- output
# List the artifacts.
- name: bash
args:
- ls
- output
### Construct log entry / Claimant Model statement.
# This step needs to be a bash script in order to substitute the fake tag in
# the command args.
- name: golang
entrypoint: bash
args:
- -c
- |
go run github.com/transparency-dev/armored-witness/cmd/manifest@${_ARMORED_WITNESS_REPO_VERSION} \
create \
--git_tag=${_MANUAL_TAG} \
--git_commit_fingerprint=${COMMIT_SHA} \
--firmware_file=output/armory-ums.imx \
--firmware_type=RECOVERY \
--tamago_version=${_TAMAGO_VERSION} \
--raw \
--output_file=output/recovery_manifest_unsigned.json
# TODO: sign the log entry with github.com/transparency-dev/armored-witness/cmd/sign
# after we create presubmit keys.
#
# Print the content of the signed manifest.
- name: bash
args:
- cat
- output/recovery_manifest_unsigned.json
substitutions:
# Build-related.
_MANUAL_TAG: 0.0.0
_TAMAGO_VERSION: '1.21.3'
# Log-related.
_ARMORED_WITNESS_REPO_VERSION: d37d6b19ec4dbd1cad3586ae8ba3ec913829d718
Loading