diff --git a/.github/workflows/cerberus-notify.yml b/.github/workflows/cerberus-notify.yml index 4f68cc76..690613f6 100644 --- a/.github/workflows/cerberus-notify.yml +++ b/.github/workflows/cerberus-notify.yml @@ -22,12 +22,20 @@ name: Cerberus notify # deleted with the GitLab files, was built around GitLab's CI_* variables, and # predates the `platform` field. # -# Prerequisite: CERBERUS_LAMBDA_URL must reach this repo as a REPO-level secret. -# The org-level copy is visibility=private, which excludes this PUBLIC repo, and -# widening it is not an option: the Cerberus endpoint is unauthenticated, so the -# URL is the whole capability. Until the pulumi-infra change applies, this -# workflow warns and exits 0 rather than adding a second red job to an already -# failed run -- the annotation is the signal. +# Prerequisites: CERBERUS_LAMBDA_URL and CERBERUS_API_TOKEN must both reach this +# repo as REPO-level secrets. The org-level copies are visibility=private, which +# excludes this PUBLIC repo. pulumi-infra provisions the pair together +# (github/repoVariables/resources.yaml). If either is missing this workflow warns +# and exits 0 rather than adding a second red job to an already failed run -- the +# annotation is the signal. +# +# The bearer token is not optional going forward. StackVista/cerberus#4 +# (STAC-24889) adds `Authorization: Bearer ` verification +# to every non-Slack request; before it, the endpoint was entirely +# unauthenticated. Sending the header is forward-compatible -- the currently +# deployed Lambda ignores unknown headers -- so this works either side of that +# deploy. Without it, the first master failure after cerberus#4 ships would get a +# 401 and no Slack message. # # The Slack channel is deliberately not sent. Cerberus resolves it as # `util.GetOrDefault(req.Context, "channel", s.Channel)`, and GetOrDefault treats @@ -48,6 +56,8 @@ on: # step's guard can warn -- the failure mode this workflow exists to avoid. CERBERUS_LAMBDA_URL: required: false + CERBERUS_API_TOKEN: + required: false # Nothing here reads the repository; the payload is built entirely from the # github context. @@ -62,6 +72,7 @@ jobs: - name: Post the failure to Cerberus env: CERBERUS_LAMBDA_URL: ${{ secrets.CERBERUS_LAMBDA_URL }} + CERBERUS_API_TOKEN: ${{ secrets.CERBERUS_API_TOKEN }} REPOSITORY: ${{ github.repository }} BRANCH: ${{ github.ref_name }} PIPELINE: ${{ github.run_id }} @@ -71,16 +82,20 @@ jobs: run: | set -euo pipefail - if [ -z "${CERBERUS_LAMBDA_URL}" ]; then - echo "::warning title=Cerberus not configured::CERBERUS_LAMBDA_URL is not visible to this repo, so the ${SUITE} failure was not reported to Slack. Needs the repo-level secret from pulumi-infra (STAC-25519)." + if [ -z "${CERBERUS_LAMBDA_URL}" ] || [ -z "${CERBERUS_API_TOKEN}" ]; then + echo "::warning title=Cerberus not configured::CERBERUS_LAMBDA_URL and/or CERBERUS_API_TOKEN is not visible to this repo, so the ${SUITE} failure was not reported to Slack. Both are provisioned as repo-level secrets by pulumi-infra (STAC-25519)." exit 0 fi COMMIT_TITLE=$(printf '%s' "${COMMIT_MESSAGE}" | head -n1) - curl --verbose --fail \ + # Not --verbose: it echoes request headers, and the Authorization + # header carries the shared token. GitHub would mask it, but not + # emitting it is better than relying on masking. + curl --fail --silent --show-error \ -X POST "${CERBERUS_LAMBDA_URL}" \ -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${CERBERUS_API_TOKEN}" \ -d "$(jq -n \ --arg repo "${REPOSITORY}" \ --arg branch "${BRANCH}" \ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6879fa09..de1f801e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -348,3 +348,4 @@ jobs: suite: build secrets: CERBERUS_LAMBDA_URL: ${{ secrets.CERBERUS_LAMBDA_URL }} + CERBERUS_API_TOKEN: ${{ secrets.CERBERUS_API_TOKEN }}