fix(velero-drill): switch webhook from bearer to github_hmac (DEV-590)
The 2026-10-01 monthly drill passed but the post-run webhook got HTTP 401 from the home Paperclip. Root cause: the home server's global actorMiddleware (/app/server/src/middleware/auth.ts) rejects every Authorization: Bearer <...> that is not a board API key or an agent JWT before per-route handlers run, so the trigger's own `bearer` signingMode handler is unreachable with a 48-hex random secret. Only publicMcpGatewayProtocolPath is exempted. Fix: - Trigger 6983798e-018c-459d-95ea-4b5959441e2d switched to signingMode: github_hmac via PATCH (secret unchanged). - post_webhook now computes HMAC-SHA256(body, secret) with openssl (already in alpine/k8s) and sends X-Hub-Signature-256 instead of Authorization: Bearer. HMAC headers bypass the Bearer branch of the global middleware entirely. Verified end-to-end: synthetic HMAC-signed body posted to .../fire returned 202 issue_created and spawned DEV-591 under parent DEV-578. SealedSecret is unchanged (same secret value reused as the HMAC key). Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
5188784e86
commit
0164c8cb4e
2 changed files with 16 additions and 1 deletions
|
|
@ -58,9 +58,16 @@ data:
|
||||||
printf '{"source":"velero-restore-drill","status":"%s","timestamp":"%s","backup":"%s","restore":"%s","restore_phase":"%s","restore_duration_s":"%s","target_namespace":"%s","source_namespace":"%s","diff_summary":"%s"}\n' \
|
printf '{"source":"velero-restore-drill","status":"%s","timestamp":"%s","backup":"%s","restore":"%s","restore_phase":"%s","restore_duration_s":"%s","target_namespace":"%s","source_namespace":"%s","diff_summary":"%s"}\n' \
|
||||||
"${status}" "${TS}" "${backup}" "${restore}" "${restore_phase}" \
|
"${status}" "${TS}" "${backup}" "${restore}" "${restore_phase}" \
|
||||||
"${restore_duration_s}" "${target_ns}" "${source_ns}" "${diff_summary}" > "${body_file}"
|
"${restore_duration_s}" "${target_ns}" "${source_ns}" "${diff_summary}" > "${body_file}"
|
||||||
|
# DEV-590: trigger is in github_hmac signingMode. Compute HMAC-SHA256 over
|
||||||
|
# the raw body and send X-Hub-Signature-256; sending Authorization: Bearer
|
||||||
|
# here is a trap because the home Paperclip's global actor middleware
|
||||||
|
# rejects any Bearer header that is not a board API key or agent JWT
|
||||||
|
# before the per-trigger handler runs.
|
||||||
|
local sig
|
||||||
|
sig=$(openssl dgst -sha256 -hmac "${PAPERCLIP_WEBHOOK_SECRET}" -r "${body_file}" | awk '{print $1}')
|
||||||
local hc
|
local hc
|
||||||
hc=$(curl -sS -o /tmp/webhook.out -w '%{http_code}' -m 30 \
|
hc=$(curl -sS -o /tmp/webhook.out -w '%{http_code}' -m 30 \
|
||||||
-X POST -H "Authorization: Bearer ${PAPERCLIP_WEBHOOK_SECRET}" \
|
-X POST -H "X-Hub-Signature-256: sha256=${sig}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
--data-binary "@${body_file}" \
|
--data-binary "@${body_file}" \
|
||||||
"${PAPERCLIP_WEBHOOK_URL}" 2>&1) || hc="000"
|
"${PAPERCLIP_WEBHOOK_URL}" 2>&1) || hc="000"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,14 @@ Velero cluster-reconstruction backup layer.
|
||||||
the `velero-restore-drill-webhook` Secret is present. The CronJob uses a
|
the `velero-restore-drill-webhook` Secret is present. The CronJob uses a
|
||||||
`hostAliases` entry to route `paperclip.home.imicros.de` at the home
|
`hostAliases` entry to route `paperclip.home.imicros.de` at the home
|
||||||
public IP so the webhook reaches the routine from Hetzner (DEV-579).
|
public IP so the webhook reaches the routine from Hetzner (DEV-579).
|
||||||
|
Authentication is `github_hmac` — the script computes an HMAC-SHA256
|
||||||
|
of the raw body with the webhook secret as key and sends it as
|
||||||
|
`X-Hub-Signature-256: sha256=<hex>`. The matching trigger `signingMode`
|
||||||
|
is `github_hmac` on routine `c9d941fa-fb97-4e6a-a305-8e46f296e0cd`.
|
||||||
|
Previously it was `bearer`, but the home Paperclip's global actor
|
||||||
|
middleware rejects any `Authorization: Bearer …` whose value is not a
|
||||||
|
board API key or an agent JWT before the per-trigger handler runs,
|
||||||
|
making the bearer path unreachable (DEV-590).
|
||||||
|
|
||||||
## Failure signalling
|
## Failure signalling
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue