Jan 27, 2023
Colin Sidoti
We switched to the familiar Publishable Key, but we changed less than you'd think
Like most other developer tools, Clerk's SDKs are configured with two "keys," one for the backend and one for the frontend.
And we share the same core requirements:
Although there's no security benefit in doing so, many tools have their frontend key mirror the format and length of their backend key. Take Stripe, for example:
But as an authentication company, Clerk has an extra requirement for our frontend key, and it meant that mirroring our secret key would cause performance issues.
Wait, what? How could a key cause performance issues?
The purpose of a frontend key is to be a unique identifier when interacting with a frontend-facing API. Here's an example of how Stripe's SDK uses the publishable key:
Notice how this request is being sent to a stripe.com domain? Stripe SDKs always make requests to stripe.com, even if you're embedding their elements into your own website.
But since Clerk runs an authentication API and since we're responsible for maintaining sessions, we can't securely do the same. We need to set HttpOnly cookies
When we launched, our frontend key was simply the hostname where our frontend API is hosted. Developers configured it like this in their React apps:
1<ClerkProvider frontendApi="clerk.example.com">
By passing the API hostname directly, we avoided making an extra, waterfalled API request to exchange a traditional random key with the hostname. This led to faster overall loading speeds.
But we hit an unexpected problem with this strategy: it really confused developers. It was a common complaint in friction logs, and when we watched developers integrate Clerk we could see the confusion wash over their face.
A hostname as a frontend key is completely unfamiliar, and no matter what we tried with design and naming, we couldn't get over the hurdle.
So this week, we finally threw in the towel. Our new frontend API keys look just like Stripes:
But we refuse to exchange developer experience for performance, so there's a not-so-secret subtlety to our new publishable key. Take a closer look:
pk_test_Y2xlcmsuZXhhbXBsZS5jb20k
Now, base64-decode the part after pk_test_
:
clerk.example.com$
Indeed, we just base64-encoded the old value and started calling it a publishable key. We added a $ as a simple stop character so we can detect when keys are malformed.
As a final step, we changed the prop name for React:
1<ClerkProvider publishableKey="pk_test_Y2xlcmsuZXhhbXBsZS5jb20k">
Quick, dirty, and a little silly – but it works! We haven't sacrificed performance and our new publishable key feels much more familiar. Developers have stopped raising their eyebrows and breeze through initial setup.
Start completely free for up to 10,000 monthly active users and up to 100 monthly active orgs. No credit card required.
Learn more about our transparent per-user costs to estimate how much your company could save by implementing Clerk.
The latest news and updates from Clerk, sent to your inbox.