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>
- CronJob at 0 4 1 * * restores the latest openwebui-manifests backup into
a transient restore-test-<ts> namespace, diffs core resource-kind counts
against the live openwebui namespace, and deletes the target namespace.
- ServiceAccount + ClusterRole scoped to velero.io + namespace + configmap
ops. Script enforces the 'restore-test-' name prefix before deleting a
namespace. Cluster-wide 'view' bound for the diff.
- Failure surfaces via kube_job_status_failed (DEV-574 alert stack) and via
ConfigMap velero-restore-drill-last-result written on every run.
- Optional Paperclip webhook Secret is sealed but unreachable from Hetzner
right now (home Paperclip is LAN-only); wired as optional secretKeyRef so
the drill runs regardless. Connectivity is a follow-up.
- Argo Application velero-restore-drill points at velero/restore-drill/.
Co-Authored-By: Paperclip <noreply@paperclip.ing>