From 527e053a82e169ddfdc415f6f747d667061c244a Mon Sep 17 00:00:00 2001 From: Hayden Blauzvern Date: Wed, 13 Mar 2024 22:53:40 +0000 Subject: [PATCH] Trigger preproduction sync only after merge to main In #916, we restructured the sync scripts. As part of this, the sync to preprod after a ceremony completed would occur from the ceremony branch. We only allow workload impersonation (which is needed to push to GCS and update the CDN cache) from main, so this breaks. To fix this, we simply split the workflow into two: The first triggers on a push to ceremony and creates a PR to merge to main. After merging from main and updating the root, we sync all contents from the repository directory. I also removed the cron job because I don't think it's needed. Also updated documentation for post-merge steps. Signed-off-by: Hayden Blauzvern --- .github/workflows/sync-ceremony-to-main.yml | 73 +-------------------- playbooks/ORCHESTRATION.md | 16 +++-- 2 files changed, 12 insertions(+), 77 deletions(-) diff --git a/.github/workflows/sync-ceremony-to-main.yml b/.github/workflows/sync-ceremony-to-main.yml index 29e6bf3f..6bdc325a 100644 --- a/.github/workflows/sync-ceremony-to-main.yml +++ b/.github/workflows/sync-ceremony-to-main.yml @@ -13,9 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This workflow is triggered when a ceremony branch is completed, and will: -# - Create a PR that merges the completed ceremony branch to main -# - Sync the ceremony branch to the GCS preprod bucket +# This workflow is triggered when a ceremony branch is completed, +# creating a PR that merges the completed ceremony branch to main name: Sync Published Ceremony Branch to Main and Preprod @@ -23,8 +22,6 @@ name: Sync Published Ceremony Branch to Main and Preprod permissions: {} on: - schedule: - - cron: '0 */12 * * *' # every 12 hours workflow_dispatch: inputs: branch: @@ -63,73 +60,9 @@ jobs: pr_body: "Merge ceremony branch to main" pr_reviewer: bobcallaway,haydentherapper,joshuagl,kommendorkapten - sync: - permissions: - id-token: 'write' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - fetch-depth: 0 - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 - with: - go-version-file: './go.mod' - check-latest: true - # Setup OIDC->SA auth - - uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c # v2.1.2 - id: auth - with: - token_format: 'access_token' - workload_identity_provider: 'projects/306323169285/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider' - service_account: 'tuf-gha@project-rekor.iam.gserviceaccount.com' - create_credentials_file: true - - uses: google-github-actions/setup-gcloud@98ddc00a17442e89a24bbf282954a3b65ce6d200 # v2.1.0 - with: - project_id: project-rekor - - name: Login - run: | - gcloud auth login --brief --cred-file="${{ steps.auth.outputs.credentials_file_path }}" - gcloud auth list - # sync - - name: sync - run: | - check_expiration() { - expiry=$(jq -r '.signed.expires' $1) - expires=$(date -d $expiry +%s) - current=$(date +%s) - if (( expires < current )); then - echo "Detected expired metadata file $1 at $expiry!" - exit 1 - fi; - } - # Upload all but TUF timestamp. Once timestamp is uploaded, all other files must have been uploaded. - for f in $(ls repository/repository/ -I *timestamp.json) - do - # Check for expiration if this is a non-versioned metadata file. - # Versioned metadata like 1.root.json may be expired. - # TODO(asraa): When consistent snapshots are enabled, this logic must be changed so that - # only old versioned metadata can be expired. - if [[ $f == [^0-9]*.json ]]; then - check_expiration repository/repository/$f - fi; - gcloud --quiet storage cp --cache-control=no-store -r repository/repository/$f gs://sigstore-preprod-tuf-root/ - done - # Upload timestamp after checking latest timestamp expiration - check_expiration repository/repository/timestamp.json - gcloud --quiet storage cp --cache-control=no-store -r repository/repository/*timestamp.json gs://sigstore-preprod-tuf-root/ - # delete any files present in sigstore-preprod-tuf-root not in repository/repository - gcloud --quiet storage cp -r gs://sigstore-preprod-tuf-root/ . - diff -qr repository/repository sigstore-preprod-tuf-root | while read l; do - if [[ $l =~ "Only in sigstore-preprod-tuf-root" ]]; then - path=$(python3 -c "import re; s='$l'; pattern=r'^Only in sigstore-preprod-tuf-root(\/?)(.*): (.*)$'; match=re.search(pattern, s); print('/'.join([match.group(2), match.group(3)]).lstrip('/'))") - gcloud --quiet storage rm gs://sigstore-preprod-tuf-root/$path - fi; - done - gcloud compute url-maps invalidate-cdn-cache tuf-preprod-repo-cdn-lb --path "/*" --async - if-failed: runs-on: ubuntu-latest - needs: [sync] + needs: [push] permissions: issues: 'write' actions: 'read' diff --git a/playbooks/ORCHESTRATION.md b/playbooks/ORCHESTRATION.md index c325a87e..9d3e1b68 100644 --- a/playbooks/ORCHESTRATION.md +++ b/playbooks/ORCHESTRATION.md @@ -389,21 +389,23 @@ required. ## Step 7: Publication -Once the PR from [Step 3](#step-3-snapshotting-and-timestamping) is merged, a [workflow](../.github/workflows/sync-ceremony-to-main.yml) will automatically create a PR merging the changes on the completed ceremony branch to main. +Once the PR from [Step 6](#step-6-snapshotting-and-timestamping) is merged, a [workflow](../.github/workflows/sync-ceremony-to-main.yml) will automatically create a PR merging the changes on the completed ceremony branch to main. -Submitting this PR will trigger a push to the preproduction GCS bucket, so ensure that this PR is verified and ready to be pushed! +Submitting this PR will trigger [a workflow](../.github/workflows/sync-main-to-preprod.yml) to push to the preproduction GCS bucket for further testing, so ensure that this PR is verified and ready to be pushed! ## Post-ceremony Steps -1. The preproduction GCS bucket will need to be manually synced to the GCS production bucket as of [916](https://github.com/sigstore/root-signing/pull/916). +1. Perform manual testing against the preproduction environment. Assuming no issues, continue with the following steps. -2. If any root keyholders have changed, update the [current root keyholders](https://github.com/sigstore/root-signing#current-sigstore-root-keyholders) with their name, key ID, and location of their key material. +1. To push to the production environment, run [this workflow](../.github/workflows/sync-preprod-to-prod.yml), which syncs the preproduction and production GCS buckets. -3. If any targets have changed, update them and their usage in the table containing the [repository structure](https://github.com/sigstore/root-signing#tuf-repository-structure). +1. If any root keyholders have changed, update the [current root keyholders](https://github.com/sigstore/root-signing#current-sigstore-root-keyholders) with their name, key ID, and location of their key material. -4. Announce the root rotation on twitter and the community meeting, and thank the keyholders! +1. If any targets have changed, update them and their usage in the table containing the [repository structure](https://github.com/sigstore/root-signing#tuf-repository-structure). -5. Schedule the next root signing event one month before expiration on the calendar. Check [here](https://github.com/sigstore/root-signing/blob/e3f1fe5e487984f525afc81ac77fa5ce39737d0f/cmd/tuf/app/init.go#L29) for root expiration. Schedule a testing event for the week before. +1. Announce the root rotation on twitter and the community meeting, and thank the keyholders! + +1. Schedule the next root signing event one month before expiration on the calendar. Check [here](https://github.com/sigstore/root-signing/blob/e3f1fe5e487984f525afc81ac77fa5ce39737d0f/cmd/tuf/app/init.go#L29) for root expiration. Schedule a testing event for the week before. ### Other