From 5e453b7ca67e1cf5ac2b54dad08dd28a62b27ac0 Mon Sep 17 00:00:00 2001 From: Lucas Manuel Rodriguez Date: Thu, 27 Feb 2025 17:59:11 -0300 Subject: [PATCH] Check for timestamps on the new TUF repository (#26638) For #26483. --- .github/workflows/check-tuf-timestamps.yml | 21 +- .../workflows/check-updates-timestamps.yml | 180 ++++++++++++++++++ 2 files changed, 191 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/check-updates-timestamps.yml diff --git a/.github/workflows/check-tuf-timestamps.yml b/.github/workflows/check-tuf-timestamps.yml index b9f9720aa8..771fc19aca 100644 --- a/.github/workflows/check-tuf-timestamps.yml +++ b/.github/workflows/check-tuf-timestamps.yml @@ -1,4 +1,5 @@ -name: Check TUF timestamps +# Checks signatures that are about to expire on https://tuf.fleetctl.com. +name: "TUF expiration check: tuf.fleetctl.com" on: pull_request: @@ -6,7 +7,7 @@ on: - ".github/workflows/check-tuf-timestamps.yml" workflow_dispatch: # Manual schedule: - - cron: "0 10,22 * * *" + - cron: "0 10,22 * * *" # every day at 10 AM and 10 PM # This allows a subsequently queued workflow run to interrupt previous runs concurrency: @@ -37,7 +38,7 @@ jobs: - name: Check remote timestamp.json file id: check_timestamp run: | - expires=$(curl -s http://tuf.fleetctl.com/timestamp.json | jq -r '.signed.expires' | cut -c 1-10) + expires=$(curl -s https://tuf.fleetctl.com/timestamp.json | jq -r '.signed.expires' | cut -c 1-10) today=$(date "+%Y-%m-%d") warning_at=$(date -d "$today + 4 day" "+%Y-%m-%d") expires_sec=$(date -d "$expires" "+%s") @@ -52,7 +53,7 @@ jobs: - name: Check remote snapshot.json file id: check_snapshot run: | - expires=$(curl -s http://tuf.fleetctl.com/snapshot.json | jq -r '.signed.expires' | cut -c 1-10) + expires=$(curl -s https://tuf.fleetctl.com/snapshot.json | jq -r '.signed.expires' | cut -c 1-10) today=$(date "+%Y-%m-%d") warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") expires_sec=$(date -d "$expires" "+%s") @@ -67,7 +68,7 @@ jobs: - name: Check remote targets.json file id: check_targets run: | - expires=$(curl -s http://tuf.fleetctl.com/targets.json | jq -r '.signed.expires' | cut -c 1-10) + expires=$(curl -s https://tuf.fleetctl.com/targets.json | jq -r '.signed.expires' | cut -c 1-10) today=$(date "+%Y-%m-%d") warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") expires_sec=$(date -d "$expires" "+%s") @@ -82,7 +83,7 @@ jobs: - name: Check remote root.json file id: check_root run: | - expires=$(curl -s http://tuf.fleetctl.com/root.json | jq -r '.signed.expires' | cut -c 1-10) + expires=$(curl -s https://tuf.fleetctl.com/root.json | jq -r '.signed.expires' | cut -c 1-10) today=$(date "+%Y-%m-%d") warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") expires_sec=$(date -d "$expires" "+%s") @@ -106,7 +107,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "⚠️ TUF timestamp.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + "text": "⚠️ https://tuf.fleetctl.com/timestamp.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" } } ] @@ -127,7 +128,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "⚠️ TUF snapshot.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + "text": "⚠️ https://tuf.fleetctl.com/snapshot.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" } } ] @@ -148,7 +149,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "⚠️ TUF targets.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + "text": "⚠️ https://tuf.fleetctl.com/targets.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" } } ] @@ -169,7 +170,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "⚠️ TUF root.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + "text": "⚠️ https://tuf.fleetctl.com/root.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" } } ] diff --git a/.github/workflows/check-updates-timestamps.yml b/.github/workflows/check-updates-timestamps.yml new file mode 100644 index 0000000000..e9bf4b2b2a --- /dev/null +++ b/.github/workflows/check-updates-timestamps.yml @@ -0,0 +1,180 @@ +# Checks signatures that are about to expire on https://updates.fleetdm.com. +name: "TUF expiration check: updates.fleetdm.com" + +on: + pull_request: + paths: + - ".github/workflows/check-updates-timestamps.yml" + workflow_dispatch: # Manual + schedule: + - cron: "0 10,22 * * *" # every day at 10 AM and 10 PM + +# This allows a subsequently queued workflow run to interrupt previous runs +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}} + cancel-in-progress: true + +defaults: + run: + # fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference + shell: bash + +permissions: + contents: read + +jobs: + test-go: + strategy: + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + + steps: + - name: Harden Runner + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + with: + egress-policy: audit + + - name: Check remote timestamp.json file + id: check_timestamp + run: | + expires=$(curl -s https://updates.fleetdm.com/timestamp.json | jq -r '.signed.expires' | cut -c 1-10) + today=$(date "+%Y-%m-%d") + warning_at=$(date -d "$today + 4 day" "+%Y-%m-%d") + expires_sec=$(date -d "$expires" "+%s") + warning_at_sec=$(date -d "$warning_at" "+%s") + + if [ "$expires_sec" -le "$warning_at_sec" ]; then + echo "timestamp_warn=true" >> ${GITHUB_OUTPUT} + else + echo "timestamp_warn=false" >> ${GITHUB_OUTPUT} + fi + + - name: Check remote snapshot.json file + id: check_snapshot + run: | + expires=$(curl -s https://updates.fleetdm.com/snapshot.json | jq -r '.signed.expires' | cut -c 1-10) + today=$(date "+%Y-%m-%d") + warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") + expires_sec=$(date -d "$expires" "+%s") + warning_at_sec=$(date -d "$warning_at" "+%s") + + if [ "$expires_sec" -le "$warning_at_sec" ]; then + echo "snapshot_warn=true" >> ${GITHUB_OUTPUT} + else + echo "snapshot_warn=false" >> ${GITHUB_OUTPUT} + fi + + - name: Check remote targets.json file + id: check_targets + run: | + expires=$(curl -s https://updates.fleetdm.com/targets.json | jq -r '.signed.expires' | cut -c 1-10) + today=$(date "+%Y-%m-%d") + warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") + expires_sec=$(date -d "$expires" "+%s") + warning_at_sec=$(date -d "$warning_at" "+%s") + + if [ "$expires_sec" -le "$warning_at_sec" ]; then + echo "targets_warn=true" >> ${GITHUB_OUTPUT} + else + echo "targets_warn=false" >> ${GITHUB_OUTPUT} + fi + + - name: Check remote root.json file + id: check_root + run: | + expires=$(curl -s https://updates.fleetdm.com/root.json | jq -r '.signed.expires' | cut -c 1-10) + today=$(date "+%Y-%m-%d") + warning_at=$(date -d "$today + 30 day" "+%Y-%m-%d") + expires_sec=$(date -d "$expires" "+%s") + warning_at_sec=$(date -d "$warning_at" "+%s") + + if [ "$expires_sec" -le "$warning_at_sec" ]; then + echo "root_warn=true" >> ${GITHUB_OUTPUT} + else + echo "root_warn=false" >> ${GITHUB_OUTPUT} + fi + + - name: Slack timestamp notification + if: ${{ steps.check_timestamp.outputs.timestamp_warn == 'true' }} + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + with: + payload: | + { + "text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "⚠️ https://updates.fleetdm.com/timestamp.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: Slack snapshot notification + if: ${{ steps.check_snapshot.outputs.snapshot_warn == 'true' }} + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + with: + payload: | + { + "text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "⚠️ https://updates.fleetdm.com/snapshot.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: Slack targets notification + if: ${{ steps.check_targets.outputs.targets_warn == 'true' }} + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + with: + payload: | + { + "text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "⚠️ https://updates.fleetdm.com/targets.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: Slack root notification + if: ${{ steps.check_root.outputs.root_warn == 'true' }} + uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + with: + payload: | + { + "text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "⚠️ https://updates.fleetdm.com/root.json is about to expire or has already expired\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK