v3 Signature Mismatch - Public UIE (Local Dev + Proxy)
SOLVE
Hey Devs! Stuck on a persistent v3 signature mismatch for our public UI Extension that we're looking for some guidance on:
`hubspot.fetch()` calls to our local Node.js backend (proxied via `local.json` + Cloudflare tunnel, with `CLIENT_SECRET` injected into `hs project dev`) consistently result in a 403 "Invalid HubSpot signature" from our middleware.
Key Findings:
`CLIENT_SECRET` is confirmed identical everywhere.
`@hubspot/api-client`'s `Signature.isValid()` returns `false`, even when passed the full URL (from `req.originalUrl` with documented URI decoding), method, empty raw body (for GET), numeric timestamp, and our client secret.
Our manual Node.js `crypto` calculation for the _same base string_ matches standard online HMAC tools, but this "standard" signature does **not** match the signature header sent by the `hs project dev` proxy.
If I understand correctly, this suggests the base string signed by the `hs project dev` proxy differs from our reconstruction (and likely from what `Signature.isValid()` expects in this proxied scenario).
Question: Are there any known specific nuances to how `hs project dev` proxy constructs its string-to-sign for v3 (e.g., query param order, specific URL encoding details beyond the documented list) that we might be missing?
Happy to provide more detailed logs/code if anyone has encountered this, and might be willing to provide some direction. Thanks in advance for any insight here!
v3 Signature Mismatch - Public UIE (Local Dev + Proxy)
SOLVE
Thanks so much for sharing your code, @KKauper! It's very helpful to see a working manual implementation.
We've also been down the manual calculation path (Node.js/Express) and found, like you, that **bleep** is in the details of that base string, especially the exacturicomponent.
Our manual Node.jscryptocalculations actually match standard online HMAC tools for a given base string and ourCLIENT_SECRET. However, this "standard" signature still doesn't match theX-HubSpot-Signature-V3header sent by thehs project devproxy when usinghubspot.fetch()from our UI extension. This suggests the proxy's string-to-sign has a nuance we haven't yet replicated.
We're also finding that@hubspot/api-client'sSignature.isValid()is similarly failing for us in this proxied dev scenario. Your example reinforces that a precise manual approachcanwork, so we're continuing to investigate the exact base string formation by the local dev proxy. Appreciate you posting your solution!
@DianaGomez - Would love to keep this thread / conversation open to everyone while we continue working through a solution, as we will report back with an update when we do in case it helps anyone else out now or in the future.
I would like to invite some members of our community who may offer valuable insights.— hey @EMalueg, @KKauper, @09156, @zach_threadint - Could you share your advice with @Milest?
Thanks for taking a look!
Diana
HubSpot’s AI-powered customer agent resolves up to 50% of customer queries instantly, with some customers reaching up to 90% resolution rates. Learn More.
v3 Signature Mismatch - Public UIE (Local Dev + Proxy)
SOLVE
Unfortunately, I can't help here. I do not use this new UI extensions framework, and I don't use `Signature.isValid()` from the Hubspot API client. Instead I use `crypto.timingSafeEqual()` after building the signature. Happy to share my code, however, if it would help.
v3 Signature Mismatch - Public UIE (Local Dev + Proxy)
SOLVE
Thank you, @DianaGomez - I look forward to connecting with more of the community!
@KKauper - I appreciate your quick response and insight. I'm definitely open to trying alternative approaches. Anything that you're able to share would be highly appreciated. Thanks so much again for your help!