fix: revert incorrect RSA webhook change, restore Ed25519 + correct CLAUDE.md
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

GHL actually signs x-wh-signature with Ed25519 (confirmed via production
webhook logs in CASA-40). The RSA change was based on incorrect user-provided
info and broke the production server (502). Reverting to Ed25519 and updating
CLAUDE.md to reflect the correct scheme.

Co-Authored-By: SideKx <sidekx.ai@sds.dev>
This commit is contained in:
Head of Product & Engineering 2026-04-06 19:50:35 +02:00
parent dfa07bb62f
commit 53e41ff871

View File

@ -12,7 +12,7 @@
- **Mongo driver:** `go.mongodb.org/mongo-driver/v2`
- **HTTP client:** `net/http` (stdlib, no external HTTP client)
- **JSON:** `encoding/json` (stdlib)
- **Crypto:** `crypto/rsa` + `crypto/sha256` (webhook sig: RSA-PKCS1v15+SHA-256); `crypto/ed25519` (X-GHL-Signature fallback, active July 2026+)
- **Crypto:** `crypto/ed25519` (webhook sig: Ed25519 for both `x-wh-signature` and `X-GHL-Signature`; key from GHL Marketplace app settings)
- **Config:** Environment variables only (no config files)
- **Deploy:** Docker + Docker Compose on Vultr
@ -64,8 +64,8 @@ GHL sends `ProviderOutboundMessage` to our delivery URL:
"userId": "..."
}
```
Verified via `x-wh-signature` header using RSA-PKCS1v15 + SHA-256.
Future: `X-GHL-Signature` header using Ed25519 (GHL migration July 2026).
Verified via `x-wh-signature` header using Ed25519 (key from GHL Marketplace app settings).
`X-GHL-Signature` also Ed25519 (same key; GHL will activate this header July 2026).
## Project Structure
@ -149,7 +149,7 @@ Validated at startup. Missing required vars → log error + os.Exit(1).
## Key Implementation Notes
1. **Webhook signature verification is mandatory** — GHL sends `x-wh-signature` on every webhook. Verify with RSA-PKCS1v15 + SHA-256 using the static RSA public key from GHL docs (set in `GHL_WEBHOOK_PUBLIC_KEY` env var). From July 2026, also support `X-GHL-Signature` (Ed25519). The handler checks `X-GHL-Signature` first and falls back to `x-wh-signature`.
1. **Webhook signature verification is mandatory** — GHL sends `x-wh-signature` on every webhook. Verify with Ed25519 using the key from your GHL Marketplace app settings (set in `GHL_WEBHOOK_PUBLIC_KEY` env var). From July 2026, GHL will also send `X-GHL-Signature` (same Ed25519 scheme). The handler checks `X-GHL-Signature` first and falls back to `x-wh-signature`.
2. **OAuth tokens are per-location** — store `locationId``{ access_token, refresh_token, expires_at }` in MongoDB. Refresh before expiry.
3. **Phone normalization is critical** — GHL sends E.164 (`+639XXXXXXXXX`), Cast expects `09XXXXXXXXX`. Get this wrong = messages fail.
4. **Status updates must use the provider's token** — only the conversation provider marketplace app tokens can update message status.