fix(webhooks): sign outbound webhooks with a dedicated secret, not JWT_SECRET #324
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/bunyip!324
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-332-dedicated-webhook-signing-secret"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Before this change
bunyip-api/src/main.rsconstructed theWebhookServicewithjwt_secret.clone(), meaning every RP that verified a bunyip webhook had to hold bunyip's access-token signing key. That is a far too broad grant: the same secret that verifies anaccount_deletedpayload could also mint valid bunyip access tokens for any user. And any rotation of JWT_SECRET (which happens for its own security reasons) silently broke webhook verification on the receiving side in flight, with no obvious connection between the two symptoms.Split the two secrets. Read a new
BUNYIP_WEBHOOK_SIGNING_SECRETvia the sharedsecret_envhelper (which resolvesBUNYIP_WEBHOOK_SIGNING_SECRET_FILEfirst for compose secrets, then the plain env var for dev .env). Same fail-shape asJWT_SECRET: production panics if unset, dev/test falls back to a stable placeholder sojust devstill boots. Pass the new value toWebhookService::new; the service itself is unchanged (itssigning_secret: Stringfield takes whatever the caller passes).Rollout: the value MUST match what mokosh-server already holds in its own
BUNYIP_WEBHOOK_SECRETon the same host, or every subsequent account-delete webhook fails HMAC verification and the mokosh soft-delete never fires. Wiring the secret into the docker compose stacks (c-01 and nc-01 bunyip-api) is a separate change; this PR is code-only. See BUNYIP-332 for the full rollout checklist including the mokosh-server-side comment fix.Also verified during triage:
WebhookServiceis used at runtime (constructed at main.rs:378 pre-change / :382 post-change, called fromhandlers/user.rs::delete_accountviafan_out_account_deletedafter a real user delete). A prior triage note claiming it was constructed only in tests was mistaken.Applicationmodel has nowebhook_secretcolumn; the signing secret is service-wide, not per-RP. mokosh-server's comment describing this as "the same per-app registry row in Bunyip'sapplicationstable" is misleading and will be corrected in a matching mokosh-server PR.#BUNYIP-332
393a5780ba055bcfb307