fix: add HMAC-SHA256 signing and verification to identity webhook VerifyToken (PILOT-240)#9
Conversation
…ifyToken (PILOT-240)
VerifyToken sends tokens to the configured identity webhook via
HTTP POST but neither signed the request nor verified the response.
An attacker who compromises the webhook endpoint, hijacks its DNS,
or MITMs its TLS could return {verified:true, external_id: victim}
for any token, bypassing the entire IDP-backed registration model.
Changes:
- Store gains identityWebhookSecret field + Set/Get accessors
- VerifyToken uses http.NewRequest + client.Do (was client.Post)
- When secret is set: outbound requests carry X-Pilot-Signature-256
(matching the PILOT-239 webhook event pattern)
- When secret is set: response X-Pilot-Signature-256 is verified;
unsigned or mis-signed responses are rejected
- When secret is empty: full backward compatibility (no headers)
Tested: 6 new tests covering signed request verification, unsigned
response rejection, wrong-signature rejection, no-signature-when-empty,
empty-token shortcut with secret, and getter/setter roundtrip.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
canary OK ✅ — run https://github.com/pilot-protocol/pilot-canary/actions/runs/26654954102 passed. |
🦾 Matthew PR Check — #9 PILOT-240Status
WhatAdds HMAC-SHA256 request signing and response verification to the identity webhook VerdictCLEAN — all CI green, canary passed, no review feedback. Ready for operator review. automated by matthew-pilot |
🦾 Matthew PR Check — #9 PILOT-240Status
SummaryAdds HMAC-SHA256 signing and verification to the identity webhook
|
🧹 Matthew Cleanup — #9 MergedPR merged by TeoSlayer at 2026-05-29T20:36:35Z. Cleaning up now.
Thanks for the merge! 🚀 |
|
✅ Merged by @TeoSlayer — branch cleaned up. Thanks for the review! |
Summary
Add HMAC-SHA256 request signing and response verification to the identity webhook
VerifyTokenmethod, matching theX-Pilot-Signature-256pattern established in PR #8 (PILOT-239).Problem
identity/identity.go:VerifyTokenPOSTed the user-supplied token to the configured identity webhook and accepted the returnedexternal_idas authoritative — with no HMAC on the request and no signature check on the response. If the identity webhook endpoint is compromised, its DNS hijacked, or its TLS MITM'd, an attacker returns{"verified":true,"external_id":"victim-user"}for any token → bypasses the entire IDP-backed registration model (PILOT-240).Fix
StoregainsidentityWebhookSecretfield +SetIdentityWebhookSecret/getterVerifyTokenswitches fromclient.Posttohttp.NewRequest+client.Doto support custom headersX-Pilot-Signature-256(HMAC-SHA256 of body, hex-encoded)X-Pilot-Signature-256header — unsigned or mis-signed responses are rejectedDiff stat
Verification
go build ./...— cleango vet ./...— cleango test ./...— all packages pass (identity: 15 tests, 6 new)Related
X-Pilot-Signature-256pattern for audit webhook events)