Skip to content

fix: add HMAC-SHA256 signing and verification to identity webhook VerifyToken (PILOT-240)#9

Merged
TeoSlayer merged 1 commit into
mainfrom
openclaw/pilot-240-20260529-182000
May 29, 2026
Merged

fix: add HMAC-SHA256 signing and verification to identity webhook VerifyToken (PILOT-240)#9
TeoSlayer merged 1 commit into
mainfrom
openclaw/pilot-240-20260529-182000

Conversation

@matthew-pilot
Copy link
Copy Markdown
Collaborator

Summary

Add HMAC-SHA256 request signing and response verification to the identity webhook VerifyToken method, matching the X-Pilot-Signature-256 pattern established in PR #8 (PILOT-239).

Problem

identity/identity.go:VerifyToken POSTed the user-supplied token to the configured identity webhook and accepted the returned external_id as 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

  • Store gains identityWebhookSecret field + SetIdentityWebhookSecret/getter
  • VerifyToken switches from client.Post to http.NewRequest + client.Do to support custom headers
  • When a secret is configured:
    • Outbound POST carries X-Pilot-Signature-256 (HMAC-SHA256 of body, hex-encoded)
    • Response MUST include X-Pilot-Signature-256 header — unsigned or mis-signed responses are rejected
  • When secret is empty: full backward compatibility (no headers, no verification)

Diff stat

identity.go               | 11 +++++
identity/identity.go      | 64 ++++++++++++++++++++++--
identity/zz_store_test.go | 122 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+), 4 deletions(-)

Verification

  • go build ./... — clean
  • go vet ./... — clean
  • go test ./... — all packages pass (identity: 15 tests, 6 new)
  • New tests cover: signed request HMAC correctness, unsigned response rejection, wrong-signature rejection, backward-compatible no-secret path, empty-token shortcut with secret, getter/setter roundtrip

Related

…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
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@matthew-pilot matthew-pilot added the canary-passed Canary harness passed label May 29, 2026
@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🦾 Matthew PR Check — #9 PILOT-240

Status

  • State: OPEN · MERGEABLE · canary-passed
  • CI: 2/2 green (test ✅, codecov/patch ✅)
  • Canary: passed (canary-passed label present)
  • Reviews: none yet
  • Created: 2026-05-29 18:28 UTC
  • Branch: openclaw/pilot-240-20260529-182000main
  • Files: 1 commit

What

Adds HMAC-SHA256 request signing and response verification to the identity webhook VerifyToken method, matching the X-Pilot-Signature-256 pattern established in PR #8 (PILOT-239).

Verdict

CLEAN — all CI green, canary passed, no review feedback. Ready for operator review.


automated by matthew-pilot

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🦾 Matthew PR Check — #9 PILOT-240

Status

  • State: OPEN · MERGEABLE · canary-passed
  • CI: 2/2 green (test ✅, codecov/patch ✅)
  • Canary: passed (canary-passed label)
  • Created: 2026-05-29 18:28 UTC
  • Files: 3 (+193/−4, identity.go, identity/identity.go, identity/zz_store_test.go)

Summary

Adds HMAC-SHA256 signing and verification to the identity webhook VerifyToken. New Sign() and VerifySignature() methods on the store backed by crypto/hmac with SHA-256. Comprehensive test coverage (122 lines of tests, all passing). Clean merge, all CI green.

🤖 Matthew PR Worker · 2026-05-29 19:01 UTC

@TeoSlayer TeoSlayer merged commit 348a454 into main May 29, 2026
3 checks passed
@TeoSlayer TeoSlayer deleted the openclaw/pilot-240-20260529-182000 branch May 29, 2026 20:36
@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🧹 Matthew Cleanup — #9 Merged

PR merged by TeoSlayer at 2026-05-29T20:36:35Z. Cleaning up now.

  • Branch: openclaw/pilot-240-20260529-182000 — will delete
  • Merge commit: 348a4549
  • Jira: PILOT-240 → Done

Thanks for the merge! 🚀

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

✅ Merged by @TeoSlayer — branch cleaned up. Thanks for the review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

canary-passed Canary harness passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants