Hacker News new | past | comments | ask | show | jobs | submit | colinclerk's comments login

Clerk | Frontend & Backend SWE | Remote or in-person in SF

Clerk is hiring frontend and backend engineers, remote or in-office in San Francisco

We build developers tools for authentication. We're known for our React components like SignIn and UserProfile that "just work" when they're added to the page.

Our components are powered by a new type of API: a frontend-facing API that relies on session tokens for authorization, instead of a backend-facing API that relies on a secret key.

We've found this pattern unlocks a new level of efficiency. Developers can implement Clerk faster than traditional APIs because it comes built-in with UX and UI. To learn more about the approach, see our talk on A Component is Worth a Thousand APIs:

https://www.youtube.com/watch?v=enUuBY3HXh4

We're especially excited to work with engineers who are thoughtful about speed and craft. Clerk is defining the gold standard for components-as-a-service, and we are constantly searching for new ways to evolve and improve our approach. Apply here:

https://jobs.ashbyhq.com/Clerk/308e77a2-872b-4835-aaf3-532bb...

Separately, I'm one of Clerk's cofounders, and I'll be watching this thread through the day if I can be help with any questions. Or feel to email me (colin@ our domain)


Hey, the idea of delegating this to the front end is very interesting! I've integrated Auth0 before and felt that it was clunky for designing more customized flows from the UX/UI POV.

1. With the new server components paradigm, React and Next have gone through a lot of changes around how SSR is done. Are your helper functions (currentUser(), currentOrg(), etc.) compatible with both the old and new approaches? Or is adapting to both one of your current technical challenges?

2. Are you open to candidates in the Americas time zones (LatAm)?


Answering 2 first because it's easier: Yes.

1. It's a great question and we're still learning the answer. But, I believe the approach is ~95% compatible, and the last 5% just needs tweaking on the margins vs a major overhaul. Let me try to explain...

First: SSR definitely makes the framing of "frontend api" vs "backend api" very confusing. So ignore that, and think of it purely as "api authenticated with a session token" vs "api authenticated with a secret key."

I think authenticating via session token is the key to enabling faster development with Clerk than tools like Auth0 (or even Stripe/Twilio/etc). The reason why is that it shifts the problem of _authorization_ from our customer's backend to Clerk's backend.

As an example, consider a user updating their email...

In the past, you would build a frontend for collecting their new email, send it to your backend, ensure that the user is updating their own name (the authorization step), then forward the update along to your account system (Auth0, your own database, whatever).

With Clerk, you build a frontend for collecting their new email, then send it straight to Clerk to handle the update with the user's session token. We are responsible for ensuring the update is to the users own account, and there's no requirement to hop to your backend to relay the secret key.

In the end, that hop to the backend and authorization check is responsible for a lot of the "clunk" that Clerk eliminates. And ultimately, SSR doesn't change our ability to make things easier – we can authenticate our API with a session token just-as-well during SSR as we can from the frontend.

This feels like a paradox, right? A session token has such limited power compared to secret key, so surely it can't be used to build an easier API. But in practice, confidently knowing which user is making the request is necessary for shifting the authorization step to our service.

I'd add that this idea isn't particularly novel. Stripe Checkout depends on a CheckoutSession object, which you initialize by passing in the active user's ID. So there, you see that Stripe having the active user's ID enables them remove a ton of steps for building a checkout. Implicitly, under-the-hood Checkout relies on an API that uses a session token for authentication.

We just took the idea one step further and are exposing the API, instead of only using it to power a single, fairly rigid UI. With Clerk, developers can use React Hooks to build their own UI.

---

Now, regarding the 5% that we still need to figure out. It pertains exactly to the currentUser() and currentOrg() functions you're calling out. Those are compatible, but they require some extra thoughtfulness.

As an example, Clerk's User object has a field called "privateMetadata". From the backend, it's completely okay for currentUser() to return this private data, but Clerk needs to make sure it doesn't leak to the frontend. That creates some oddities - the User object on frontend is different than on backend, and I don't think we've really nailed the ergonomics / education on this part yet. But it generally feels like a solvable problem.


> A session token has such limited power compared to secret key

Does it though? Sure, it has different threat models, and you may choose to assign it different trust levels, but fundamentally (as I understand it) every session token _is_ a secret key, with added benefits.


Awesome! I applied. Just letting you know in case the system flags because I clicked "no" when asked if I'm in the US or the EU.

I agree that SSR makes the "frontend VS backend API" separation very confusing. Session token VS secret key is a better framing for this, and there's a very interesting insight into the paradox that you described! The ergonomics you mention for ensuring consistency sounds like a very interesting technical challenge.


Hey! Interested by the opportunity but does Clerk looking to hire new grad? Thanks!


Does the crowd on HN expect passkey support to become more ubiquitous in the future, similar to Google OAuth today?

I’ve been surprised at how few sites seem to be adopting rapidly since there are UX gains, but I suppose Google had a fairly slow trajectory as well.


Apple’s push is enough to convince me that this will be a default soon. Adoption has been slow because it takes some effort and the payoff isn’t immediately obvious. This new service from 1Password might start to change that. I expect others will follow with similar ideas.


Apple Pay but for passwords!

It will take over slowly, especially if they handle the edge cases well. Explaining passwords to people is a pain.


Apple Pay definitely hasn't taken over. I've heard of it, but never used it. I don't understand exactly what it does.

If explaining passwords to people is a pain, just wait until you try to explain a passkey.


The passkey needs to work like faceID does on apps, quietly, quickly, and without anyone even really noticing.

Apple Pay is nice when a website supports it AND it works, but those two are sadly vanishingly rare.

Works well on Apple's store, however.


have you ever used a tap credit card?


Yes but I’m speaking of using Apple Pay on websites.


Yes, I have.


I think once the account recovery problems, aka "oh no, dropped my phone in a pond, now I can't login", are resolved, it'll take off.

I've used it for some sites and it is pretty cool to not have to remember anything. Fingerprint readers are a bit touchy, but seem to be getting better.

I also think that it is far far easier than a password manager, the current go-to secure solution today.


> I think once the account recovery problems, aka "oh no, dropped my phone in a pond, now I can't login", are resolved, it'll take off.

The same recovery methods used for passwords also work for passkeys, e.g. as sending a link in an email or text message to create a new passkey.

In the "oh no, dropped my phone in a pond" scenario, my passkeys are already synced across devices via the cloud, so I would not have to create new passkeys.


> The same recovery methods used for passwords also work for passkeys, e.g. as sending a link in an email or text message to create a new passkey.

How does a site have your email address if you registered and logged in with a passkey? They only have that if you gave it to them. Maybe there's an Apple specific extension, but the WebAuthn spec (which is what passkeys are based on) doesn't require any contact info to be provided.

>In the "oh no, dropped my phone in a pond" scenario, my passkeys are already synced across devices via the cloud, so I would not have to create new passkeys.

That is not true for every set of passkeys/WebAuthn credentials, only for people using certain providers like Apple. But yes, if you have that set up, that handles it.


> but the WebAuthn spec (which is what passkeys are based on) doesn't require any contact info to be provided.

This isn't an issue with the spec, it's an issue with account creation, account information, and recovery flow on part of the operators of the website. Those operators are already familiar with this dance. They will use information that is required for registration in order to provide account recovery, and yes, this will include an optional, or possibly mandatory, email address/phone number/whatever to do so.

Existing registration flows that already work and ask for this information will barely need to change, and most users of Passkeys will be adding them to these already existing flows, so it's practically a non-issue. Or at least no more than it already was.


Big tech is salivating over the vendor lock this will enable, so there will be a big push for it. I’m just hoping password managers will allow us to store the key material in them so that cross-platform can work.


> Big tech is salivating over the vendor lock this will enable…

This enables vendor lock-in as much as passwords do. That is to say, not at all.

Example: Chrome supports passkeys, but uses a Chrome-only passkey store instead of the OS one. So I have one passkey for Chrome, and another for macOS/iOS.


That's literally describing vendor lock in meaning you need manage multiple vendor locked passkeys for the same service which is ridiculous.

Passkeys are massively less flexible than passwords as it stands.


> That's literally describing vendor lock in meaning you need manage multiple vendor locked passkeys for the same service which is ridiculous.

It makes more sense if you don't think of passkeys as passwords and more like "SSH keys for muggles". Passkeys are definitely not vendor-locked — they're a standard, and so Google Account passkeys work with anything that supports passkeys.

If you're unhappy that Chrome doesn't leverage the macOS passkey store, that's completely valid and you can point your frustration in their direction. In practice, taking 30 seconds to create an additional passkey wasn't onorous.

When 1Password supports passkeys, I'll generate another passkey for it and then use that globally.


> In practice, taking 30 seconds to create an additional passkey wasn't onorous.

Almost every site requires an account these days. I am quite fed up with the number of accounts I need to have, in general. Now you are telling me I have to go through a process of creating passkeys for each site for each browser/mobile os? 30 seconds times 100 is pretty onerous.

Oh, you mean you reuse the same passkey for all services that require accounts? I'm sorry to tell you, that's impossible. You didn't understand how this works.

"The same passkey is never used with more than one site." from here https://developers.google.com/identity/passkeys


Yes. To enable in Auth0, it's two checkboxes. For something more bespoke it's a few days of engineering time.

https://techcrunch.com/2023/05/03/google-now-lets-you-access...

https://passkeys.directory/

(managing passkey rollout at a fintech for customer iam)


Once Apple and Google have pushed it out with their mobile devices, things will move along fast.

I'd argue within 5-ish years you'll start encountering people who have never used a username + password combo at all.

Passkeys are the future - but how they will work across ecosystems remains to be seen (without a subscription)


Passkey support has been on iOS since the release of iOS 16 -- so more than a half-year!

Google has actually had support for passkey for many many months now, but for whatever reason, waited to formally announce it until just recently.

Cross-platform is also already solved. See the FAQ directly from the FIDO Alliance: https://fidoalliance.org/passkeys/#faq


> If the user does not have their old device or a security key, then the RP can treat sign-in from the new device (which might be from a different vendor) as a normal account recovery situation and take appropriate steps to get the user signed in.

LOL. This is not a serious answer.


> I'd argue within 5-ish years you'll start encountering people who have never used a username + password combo at all.

But can one register apple/google account without password with fresh phone on setup screen? What would happen if that phone would die? Apple often asks for icloud password in various places (which really surprises me, I mean it's Apple app on Apple device which logged in, why ask me about it).

It still looks to me like master password (which is google/icloud password) and other accounts are accessible with this master password. Just less friction: no need to copy random passwords around.


If anyone's facing this in their auth flows, we're happy to help at https://clerk.dev

We're in the same cat-and-mouse game with the attackers as everyone else, but since we're an auth company, we have full-time folks monitoring for issues and resolving when they come up.

It's worth mentioning that Twilio is in an understandably tough position here. They only receive API requests from your server, and real requests look the same as attack requests except for the phone number.

Clerk is in a better position to help because our API accepts traffic directly from the attacker (e.g. POST /verify-phone-number). We know their IP, user agent, whether they're connecting from AWS, etc, etc. We very much rely on this data to help stop them.


SameSite=Lax plus CORS does the trick.

Block requests where origin=helpdesk.mysite.com.

Also, since you're concerned about subdomain attacks, make sure you set the cookie on a subdomain rather than the naked domain to prevent it from leaking.

Edit: you can put it on the naked domain if your app is on the naked domain. If you do that, do not set the Domain= attribute in your Set-Cookie because that will cause it to leak to subdomains.


I don’t agree that the complex system is mediocre.

I like it because it’s faster and it’s enabling more powerful integrations.

We (Clerk) abstracted away the complexity so it’s just an implementation detail, and think other tools should do the same instead of letting developers trip over the hazards.


Usually people experience this when they're using a React frontend that's served from a CDN, while the backend is served from a separate service.

If that's the case, the pattern you're describing is pretty normal and not an inherent cause for concern.

If you really want to workaround it, you can do this:

First, host your backend and your frontend from the same origin, so the initial window navigation includes the httpOnly cookie (make sure your cookie is set to SameSite=Lax, NOT SameSite=Strict). Then, before the CDN serves your static content, run some middleware to ensure the httpOnly cookie is valid, and add some kind of marker to the page body to indicate they're signed in (or redirect away if they're signed out).

The not-so-trivial part is running middleware in front of the CDN, but that's possible with things like Cloudflare Workers, and these days it's built-in to Next.js for most hosts.

For this approach you'll also want to make sure you can check cookie validity quickly at the edge, or else you'll be slowing down your CDN a lot.


Disclosure: cofounder @ https://clerk.dev

Auth isn't "hard" per se, but it's still a big struggle because there's just so much to implement.

For example, one of the most common attacks today is "credential stuffing," which is simply the practice of taking leaked credentials and trying them on other websites.

Protection against this is arguably trivial: implement HaveIBeenPwned and a rate limiter, and create a mechanism to update the password when credentials leak.

But that's a lot of work, it can take a lot of tuning to get the rate limiter right, the UX/UI for updating passwords is time consuming, etc, etc.

And that's just one piece of authentication security – there are so many described in NIST 800-63B.

And then there's also the challenge of keeping up with user preferences - Sign in with Google, SAML, Touch ID, magic links, etc, etc. This seems to be fragmenting rather than consolidating.

Obviously biased, but all-in-all, I think you're better off sticking with a service than pulling it in-house, even if you stay with one of our competitors :)


Disclosure: I don't work for FusionAuth or Clerk, or any of their direct competitors, but I figured I'd join the disclosure club.

I've been using Clerk for the past few weeks and it is an absolute breeze. Docs are easy to read and understand. They've prebuilt enough and the features they included are pretty useful (like organizations!). However, they annoy you with lots of emails. Pros and cons.


Disclosure, I work for one of Colin's competitors, FusionAuth. :waves:

Well said. The other piece is that it's undifferentiated. I always say "no one ever fills out a login form and says 'wow, that was so beautiful'." It's always a door between where users are and where they want to be, inside your application, doing their job or scrolling cat pictures.

Perfect candidate for choosing a service, imo.


> In practice, almost all cross-origin API requests will require these preflight requests, notably including

At Clerk, we took the opposite approach, and restructured our API so it fits within the narrow window that does not require a preflight

I wrote a little about it here: https://clerk.dev/blog/skip-cors-options-preflight


Will edgedb ever launch frontend querying with JWTs like Supabase, Hasura, Fauna?


We're still working out the kinks, but some form of this will definitely be possible.

You can already hack this by defining access policies and writing an EdgeQL proxy server that authenticates incoming requests, sets the appropriate global, and forwards the query to the database. There's a Python/Flask implementation of this pattern here[0].

We also have a JavaScript example app demonstrating access policies to simplify authorization logic using Next.js/getServerSideProps[1] and a user management platform you may have heard of called Clerk[2] :)

[0] https://github.com/edgedb/edgedb-examples/tree/main/flask-pr...

[1] https://github.com/edgedb/edgedb-examples/blob/main/nextjs-a...

[2] https://clerk.dev/


Yes, we're building that capability. With 2.0 we made our protocol stateless and can tunnel it through HTTP now, allowing access to full APIs of our clients. (Although EdgeDB also exposes a REST endpoint that you can access with any HTTP client from any language).

We'll be working on tightening and adding the necessary security mechanisms to allow exposing the DB directly to web in 3.0 and onward.


This would be great. I'm a big fan of Hasura and not having to write crud apis. But would prefer having more or less the same query language on all clients.


Yeah, that's the dream. But there are lots of tiny details to figure out to make it really usable in prod and not gimmicky. Hasura is a great product indeed.


Nice, love that you launched with React components! I need to decide to show a button before I decide to allow a button's action :)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: