
Ask HN: How many of you are rolling your own auth? - xhrpost
There&#x27;s several auth-as-a-service providers on the market right now (Auth0,Firebase,etc). (By auth I mean, all the systems that facilitate password hashing and user authentication, along with SSO integrations.) Their common marketing argument, don&#x27;t reinvent the wheel, and if you try, you&#x27;ll probably get it wrong. This is pretty compelling as getting auth &quot;perfect&quot; seems to require some decent research and understanding. However, when viewing the customer pages of some of these providers, I don&#x27;t see a ton of companies that I&#x27;m familiar with. Out of all the sites and tech tools I use, are they rolling their own auth, all of them? Once a site gets big, does it just get too hard to scale or adapt to the third-party provider?
======
spikeham
Tried Firebase for an app I'm building. Just took it back out after a few
months. Why?

1\. Not all users are comfortable with trusting a third party in order to use
my app. Some people actively mistrust and avoid megacorps like Google and FB.
They should only have to trust you, not a chain of companies.

2\. Writing code to integrate numerous external API calls is a comparable
effort to just doing it all custom.

3\. The UX of jumping to a third party dialog to log in and then back in to
the original app is jarring. "What just happened?"

4\. It introduces more potential points of failure with less control over
being able to deal with such issues. If the third party services or APIs fail,
or a user can't access those domains for some reason, tough luck.

5\. Someone else owning your app's user records is troublesome. You still need
to have your own user records for things like session state, roles and
authorization. You have to keep your user records synchronized with theirs.

6\. Users sometimes do not want to link their accounts on other services to
your app - they prefer separate identities. When your Google account's avatar
appears in an app that has nothing to do with Google it can be annoying, or
even perceived as a privacy violation.

7\. User authentication involves a standardized, conventional set of practices
and code that are well known and not hard to implement.

8\. If the third party service you put at the core of your architecture
decided to shut you down or compete with you, or they shut down themselves,
you'd be in big trouble.

9\. Sooner or later you will pay for this service. The more successful your
app is, the more you will pay. If you do it yourself, there's no cost beyond
your regular hosting costs.

10\. KISS - Keep It Simple, Silly. Don't add unnecessary dependencies and
complexity.

~~~
rekabis
Oh god yes, everything here 100%. This is why I don’t have a PushBullet
account - because they don’t offer the option of non-3rd party auth. I have no
problem snubbing any other service out there for the exact same reason, no
matter how compelling the service itself might be.

------
wowwhoknew
Is the question just "How many of you are rolling your own auth?" Because, if
that's simply the extent of the question....

Well, I use npm's bcrypt + postgres DB of users (on an expressjs server, where
I use knexjs for easy DB connection & use of JS logic in DB work).

1\. Simply salt their PW when they create their account (which is simply a
record in the DB) and store the salted version in the DB.

2\. When they log in, salt the pw they entered during login and compare it
with the salted one in the DB.

It's not tough.

Is it insanely secure? Nah, I am sure I am missing pieces involved in server
and app security. But insanely stringent security doesn't matter for my
purposes and use cases.

Password salting... About 4 lines of code:
[https://www.npmjs.com/package/bcrypt](https://www.npmjs.com/package/bcrypt)

Storing salted password in DB... another few more lines of code depending on
what you use.

I'd say you can do this in under 10 lines of code.

However, that is of course excluding the underlying system and other logic
which hosts this process of salting, storing, and then on login, comparing.

...However, if the question is really more like "How many of you are rolling
your own auth which works in a high traffic, highly exposed situation, where
expert levels of security are necessary?" then you'll likely encounter a
different pattern of answers.

~~~
Kkoala
What about things like, password reset and email verification?

~~~
Scooty
Not op, but I've written several apps with a similar setup to what was
described. Both email verification and password resets are pretty simple to
implement yourself.

For password reset, you just create a record with a unique token and send an
email that links back to the app with the unique token in the url.

Email verification is basically the same: send an email with a link that
identifies the user and hit the server with the unique token when that page
loads.

~~~
squiggleblaz
The hardest thing is probably making sure you're appropriately using an
appropriate api for generating unpredictable tokens. Generating random tokens
is a trade off between speed and unpredictability and some easy-to-find random
number apis make the wrong trade off.

~~~
jjeaff
Most any language's built in psuedorandom number generator is going to be
sufficiently random that you will have no trouble.

I mean, you could take something as facile as the sha1 of the current
microtime, and a random concatenation of the user's data from the user table
and that would already require so much access that figuring out the token
wouldn't even be your biggest problem.

~~~
robbya
> Most any language's built in psuedorandom number generator is going to be
> sufficiently random that you will have no trouble.

I once collected a $3k bug bounty over this. Python's use of Mersenne Twister
in the lib/random module should not be used for token generation. Mersenne
twister uses a relatively small state space and is fully deterministic (it
never re-seeds or mixes in new entropy). If you get a couple sequential random
values you can reconstruct that state space and predict all future values.
I.E. request a password reset 10x in a row and examine the tokens in the
emails.

Please only use secure random number generators when creating security related
tokens.

Example blog post: [https://know.bishopfox.com/blog/2014/08/untwisting-
mersenne-...](https://know.bishopfox.com/blog/2014/08/untwisting-mersenne-
twister-killed-prng)

~~~
jammygit
Is /udev/random considered secure?

Edit: never mind, your article named it as a good choice

------
jgimenez
I try to use libraries because I do not like my software depending on a third
party service, especially on such a central thing as authentication. Beware of
the vendor lock-in: if you choose to externalize this function, keep in mind
you might eventually want to switch vendors or implement this functionality on
your side. At least choose a vendor that lets export (ALL) your users data.

That said, those services (the good ones) tend to offer much more than a
simple user database, for example:

* Login with Google/Facebook/Twitter/Github/...

* Login with IAM services like OpenID Connect / SAML (mostly for big companies)

* Two factor authentication, maybe with several token types (TOTP, SMS messages, recovery codes,...)

* Password recovery flow

* Rate limit the pace of password attempts, in order to prevent brute forcing

* Monitor incoming network traffic and block unusual behaviors

* Maybe implement a CAPTCHA or similar challenge for users with unusual behavior

* Make sure the storage of all secrets is actually properly protected (password hash, password recovery auth tokens, issued OAuth tokens, etc.)

* Audit logs

If you implement auth(z) by yourself, most likely if you're going to have to
sacrifice on some of these points, otherwise you would spend all your time
here and never work on your project!

------
codegeek
I don't write it from scratch obviously but I roll my own using well known
libraries or frameworks. Sorry but Auth-As-a-Service products are too
expensive for smaller companies and putting the auth in someone's hand gives
me the creeps. I don't mind an open source self installable model though if
something like that existed.

~~~
agustif
This isn't either a known library or framework or an Auth-as-a -Service. But
I've enjoyed it in the past (if you like TypeScript/Node) and don't want to
use passportjs for everything: [https://github.com/accounts-
js/accounts](https://github.com/accounts-js/accounts)

------
mharroun
I would NOT recommend using a 3rd party auth platform unless its opensource or
able to self run (fusionauth). I nearly never regret buy over build but I
picked auth0 at a startup and in around 1 year it went from free to over 4k a
month, said platform was replaced within a week with passportjs.

~~~
scarface74
On the other side.

I’m a lot more likely to use an app where I can use my existing log in

But more practically, I work for a B2B company where we integrate with their
IDP (Okta, Active Directory, etc.) a third party service/app makes that a lot
more feasible.

------
adamfeldman
On the open-source authN/authZ front, I am aware of a few different projects.
Would love feedback from anyone who has used or evaluated these (or others).

Edit: These tools can be self-hosted and integrated to provide out-of-the-box
auth functionality to your application.

* The ORY ecosystem of tools [1]

* Gluu [2]

* Keycloak [3]

[1]:
[https://www.ory.sh/docs/next/ecosystem/overview](https://www.ory.sh/docs/next/ecosystem/overview)

[2]: [https://www.gluu.org](https://www.gluu.org)

[3]: [https://www.keycloak.org](https://www.keycloak.org)

~~~
agustif
I liked ory using it brevely from inside reactioncommerce, but I don't have
any production experience with it, also like AccountsJS which is in TS and
uses graphql-modules Docs [https://accounts-js.netlify.com/](https://accounts-
js.netlify.com/) Repo [https://github.com/accounts-
js/accounts](https://github.com/accounts-js/accounts)

------
madhadron
> Once a site gets big, does it just get too hard to scale or adapt to the
> third-party provider?

Or too expensive compared to doing it yourself.

There's also a difference between rolling your own crypto and rolling your own
auth. Leave the actual hash to experts and use NaCL's argon2 implementation.
The salt+hash are just more user metadata that aren't super sensitive given
modern password hashing algorithms.

~~~
rococode
Yeah, the cost gets super important.

Once upon a time, our company considered using Auth0.

Then we noticed that you have to pay nearly 25 cents per active user per
month. I can _possibly_ see the value for B2B, but if you're B2C good luck
dealing with an extra 25 cents cut from your margins for every single user you
have, paying or not.

------
aitchnyu
Tangential, but are magic links safe for all purposes? Slack mails you a link
that logs you in. It seems as safe as services that use password reset or
oauth.

~~~
WorldMaker
One Time Password (OTP) via email is at least as secure as any service that
provides password reset as degenerate cases of those services resembles OTP
via email anyway. (There are a lot of users out there using such a degenerate
case already today. It's amazing how many users have fallen into a "reset
password only" workflow to login to things.)

Magic links that embed the OTP inside of a clickable URL have a couple added
threat scenarios, mostly revolving around the tenuous connection between app
launching URL custom schema and OS/App Store/User Permissions. In some, but
not all cases, OS/App Stores make it hard or unlikely for a third party to
intercept those URLs, but not always impossible. There's no real central
registry for the custom schema between App Stores, for one example.

The successor to custom schemas "Universal Links" (pushed by PWA standards
among other things) have an interesting mitigation in requiring the links to
be HTTPS, with TLS-verifiable metadata that promises that link is to a domain
that the App author clearly controls before passing things on to the App. It's
not a perfect mitigation, but a useful one as part of a larger defense in
depth, depending on your application/site's threat model.

------
dustingetz
Integrating with auth0 required so much code that I don't quite understand the
point or what value they're adding. Maybe they are! It's just not obvious.
What is obvious is they didn't make it easy.

~~~
WorldMaker
It's basically the same amount of code that you would add for any one other
OAuth/OpenID Connect provider. The value they add, at the most superficial
level is that you only have to do that once, as opposed to N times for
Facebook, Google, Apple, Microsoft, etc. Admittedly, when you are doing it N
times there is a lot more code you can share so its more O(log N) additional
code.

Also, at this point I think haveibeenpwned makes it very clear that having a
password database in 2020 is a huge liability, and any options that move
passwords out of your own databases and into someone else's problem seems like
the smart idea.

(I'm not affiliated with Auth0, but I have used them for projects where Azure
AD didn't make sense, as I do fear owning passwords in my database in 2020.)

------
anderspitman
I've been experimenting with rolling my own simple auth systems with some of
my services. patchbay pro[0] uses emauth.io for authentication behind the
scenes, then returns simple session tokens. I recently modified emauth.io
(based on HN feedback) to return signed JWTs, so I'll probably change patchbay
to use those in the future.

My instincts and experience tell me that oauth is more complicated than it
needs to be, but I'm still too inexperienced to say for sure. I'm in the early
stages of a deep dive of web auth. The frustrating part of learning oauth is
most of the articles/videos explain the steps of the flows, but they don't
explain _why_ each step exists. ie what are all the security holes that would
exist if we skipped this step?

Anyone know any good oauth books/resources that build rationale from first
principles?

[0] [https://patchbay.pub/pro.html](https://patchbay.pub/pro.html)

~~~
blyat
I went on a similar journey but for OpenID Connect. While the spec is
fantastic [https://openid.net/specs/openid-connect-
core-1_0.html#Overvi...](https://openid.net/specs/openid-connect-
core-1_0.html#Overview), I found the same thing to be true - very little
explanation of _why_. For example, it's very clear how each flow works and
therefore how to implement, but not clear why there are _so many_ of them.
While researching and building my own implementation I eventually ran into
IdentityServer3
[https://identityserver.github.io/Documentation/](https://identityserver.github.io/Documentation/)
which had a nice intro video explaining things clearly. I also quit building
my own at that point, since their offering is very well done and using the
same stack as the rest of our software. I wouldn't say the docs are a _good_
resource, but they helped a bit. There's also a version 4 now, though the
documentation looks about the same.

Also not a _good_ resource, but acceptable: Pluralsight. There is one straight
up OAuth course to go over all the basics and then quite a few
language/framework specific ones, e.g. how to implement OAuth in
Node/ASP.NET/etc. The OAuth course was dry but had some decent information -
but I did quit halfway through it because of IdentityServer, so take that with
a grain of salt.

And yes, it sure does feel more complicated than it has any right to be.
There's a good read here [https://hueniverse.com/oauth-2-0-and-the-road-to-
hell-8eec45...](https://hueniverse.com/oauth-2-0-and-the-road-to-
hell-8eec45921529?gi=84094c5b3f24) by the once-lead-author.

I really do recommend checking out IdentityServer4 though, unless you're
implementing this specifically to learn / have fun / etc. And if you don't
care for the Microsoft ecosystem, I've heard nice things about Hydra
[https://github.com/ory/hydra](https://github.com/ory/hydra) which is a
similar Go offering.

~~~
anderspitman
Awesome, thanks for this. I think I've read the Road to Hell article 3/4 times
at this point. It makes a little more sense each time as I learn more.

I totally agree there are so many resources about implementation, and honestly
it's pretty straight forward. My guess is that because of this people don't
think to question it and simply assume it's all necessary. And maybe it is,
but in my experience necessity is often tied to specific assumptions that may
not be true for a specific use case.

With oauth in particular I suspect a lot of the details are tied to the
assumption that you have to do a full redirect in order to authenticate. But
my emauth.io service uses email over a back-channel to authenticate, so the
user can stay on the app page while they verify their identity. So at the very
least you don't have to worry about redirect hijacking.

------
ChikkaChiChi
If authorization or security is a primary selling attribute of your service,
and you have the professional capacity to do so, then by all means roll your
own. If it is a means to an end, abstract the problem away to a service that
will spend more time caring about the safety of your users.

------
erinaceousjones
I've a similar question about auth[orization]!

On an internal work project, we outsource our authentication to Auth0, but
stuff like user permissions handling and locking down our APIs has been
something we keep pushing back on. We have this worry that, because it's
security related, we'll "get it wrong" somehow if we do the authorization
stuff ourselves. I've found it nigh on possible to find a nice third-party
generic user-permissions web service though. Do such things exist? Libraries
that don't have super tight integration with frameworks like Django and Flask?
Stuff oriented towards a microservices architecture?

~~~
anderspitman
> I've found it nigh on possible to find a nice third-party generic user-
> permissions web service though. Do such things exist?

I've been thinking about building something along these lines. It would be
path based, with 4 roles: Reader, Writer, Manager, Owner. So readers for
example could GET, writers could POST/PATCH/DELETE/etc, managers could modify
readers/writers, and owners can modify managers.

So for example you could call auth-server.com/add-reader/path/of/interest with
a manager token.

Verification of credentials could be done with JWTs that contain a list of
paths the user has access to. So any particular app could be completely
decoupled from the auth server.

Is this at all the type of thing you're talking about?

~~~
lsiebert
I wouldn't be a fan of adding that kind of permissions to JWTs. Permission
authorization should be stored in the server. JWTs should be for
authentication.

Plus for some things you want to invalidate based on how recently they have
interacted (IE bank logs you out if you haven't clicked/typed anything for 5
minutes) and you can't represent that without server state.

~~~
anderspitman
> I wouldn't be a fan of adding that kind of permissions to JWTs. Permission
> authorization should be stored in the server. JWTs should be for
> authentication.

I don't necessarily disagree, but I'm going to push back a bit for the sake of
discussion. I think it's worth questioning _why_ JWTs should only be for
authentication. Size is the only compelling argument I'm aware of, and I think
there's a lot of cases where it wouldn't be a problem in practice. Would have
to be measured.

What would you think of providing 2 interfaces to the auth server. You could
return an authorized token like I mentioned, or you could return a token which
is only authenticated. Then the app server ("client" in oauth parlance) would
make a request directly to the auth server to get the actual authorization
token.

So app developers could choose whether to accept authorized tokens, or only
authenticated tokens if they want more control over security/token size.

> Plus for some things you want to invalidate based on how recently they have
> interacted (IE bank logs you out if you haven't clicked/typed anything for 5
> minutes) and you can't represent that without server state.

I don't see a problem here. I'm fine with the app server having state. In this
case it would simply mark that token as invalid.

~~~
lsiebert
But what's the benefit of authorized tokens over authorization being server
side?

I think it's best practice not to trust client data. It seems like a potential
fail point that might even allow privilege escalation depending on developer
configuration (and we are talking about rolling your own auth, so that's a
possible concern). You have to store it on the server anyway (so the system
can change it asynchronously without the client being online or display a
user's permissions to an admin, etc), why duplicate it when you can check it
on the server?

It also seems like a source of increased bandwidth costs, which is maybe what
you meant by size. Even if it doesn't cost you, increasing the bandwidth a
client needs for an app isn't user friendly, especially for mobile.

~~~
anderspitman
The benefit is decoupling the app server from the auth server. If all of the
authorization privileges are tracked by the auth server, it becomes the single
source of truth. It also makes it easier to switch your app to a different
auth server provider (or even accept auth from a list of different ones). If
you have a whitelist of auth providers for your app, your users could all pick
a different one, and you'd only have to implement a single auth protocol. You
could even imagine allowing users to host their own auth server, and providing
a way for them to register it with your app.

------
stockkid
While using third party services for Auth can save time at the beginning,
outsourcing such a fundamental part of the system to someone else's business
seems to me a risky option.

------
StandardFuture
Every serious software engineer that plans on developing public APIs at some
point in their career needs to have an understanding of and some basic
practice with implementing auth.

"Don't reinvent the wheel" is easily bypassed by just reading auth code from
prominent open-source projects to see real-world auth that is secure and
works. You don't need a service and using a service doesn't negate an engineer
from being competent to implement their own if necessary.

------
nik736
I am using Devise for everything :-)

~~~
SkyPuncher
Devise on Ruby or Passport on Node is all I've ever needed.

------
andrei_says_
No way. Even for email/password I use a library (sorcery) which takes care of
encryption, protects from timed attacks and is easily expandable to oauth
services.

------
seanwilson
> don't reinvent the wheel, and if you try, you'll probably get it wrong

This should apply x100 for security related matters. I feel people only seem
to bring this up with regards to hash functions and encryption but I think
this should always encompass auth as well.

I use Firebase for auth. It saves development time, there's no user limit on
the free tier even and it's battle tested.

~~~
Kkoala
I think this is a common misconception that there are no limits for Firebase
for auth.

There are limits
[https://firebase.google.com/docs/auth/limits](https://firebase.google.com/docs/auth/limits)
on free tier and on paid tiers too.

~~~
seanwilson
Which limits do you think are a problem? A lot of them seem to be about
avoiding abuse e.g. New account creation, 100 accounts/IP address/hour

~~~
Kkoala
For example, if you want to do email verification the limit is 1000
emails/day. Though for paid tiers the limits seem reasonably high.

~~~
seanwilson
The Blaze plan is one of the paid tiers that has the higher limit. It's pay as
you go so it's free if you have low usage.

------
chayesfss
Okta has a free tier for 1000 active users/month (not 1000 logins but 1000
separate users logging in as many times as you'd like). After 1000 it's cheap
as heck.
[https://developer.okta.com/pricing](https://developer.okta.com/pricing)

~~~
qorrect
Who knows how long they will support that, I've seen ploys like these before
where in a couple years they'll reduce that free tier to nothing and jack up
the price of the entry level.

~~~
g82918
This seems like super unnecessary FUD. I don't use them, but considered it for
my current Blazor project since they have some nice open source libs for other
third party authentication. Anyone anywhere can raise prices. Why be so
negative about them. Is there any actual reason to?

Edit: Equivalently any SAAS sucks since they may in the future raise their
prices is your argument.

~~~
whorleater
>Edit: Equivalently any SAAS sucks since they may in the future raise their
prices is your argument.

This is a very real argument though? Reliance of a core part of your saas on
another company, who is liable to change prices at any time, is a real
business risk. The Google Maps API pricing change is a big example.

------
medhir
FusionAuth is great for those who want a solid self-hosted auth solution. It's
open source & has many of the same features as much more expensive Auth-as-a-
service providers. -> [https://fusionauth.io/](https://fusionauth.io/)

~~~
ricketycricket
Second time I have seen FusionAuth mentioned, so I figured I'd take a look.

Can you provide a link to the source? I can't seem to find it on their GitHub.
They only appear to provide install scripts that grab the compiled java
application off Google Storage.

Also, you can self-host, but you must agree to a somewhat restrictive
license[1] upon install. As I read it, you can only self-host on equipment you
own or operate (I don't own or operate EC2), can't deploy for anyone else (no
use in consulting), are agreeing to random audits with 30-day notice, and can
only use for "Licensee's internal business purposes" (so only auth for
internal applications, not public-facing?). Even if these things aren't true,
I don't feel comfortable that I understand what I can actually use this for
with their current license.

[1]: [https://fusionauth.io/license](https://fusionauth.io/license)

~~~
guu
You’re right, it is not open source:
[https://github.com/FusionAuth/fusionauth-
issues/issues/266#i...](https://github.com/FusionAuth/fusionauth-
issues/issues/266#issuecomment-520843273)

------
zelly
It's literally built in to most databases. If that's rolling my own, I also
roll my own for loops.

------
eb0la
Manning is going to publish a book on this subject soon:
[https://www.manning.com/books/self-sovereign-
identity](https://www.manning.com/books/self-sovereign-identity)

------
SnowingXIV
I throw everything at devise. Open source, still being maintained actively,
you run it on your own servers, and have had very minimal issues if any. Have
had a hard time finding a better solution. Need payments? Slap on stripe.

------
tomwilson
Every time I've had a client ask to use one of these services it has ended up
being more work and worse UX, with more bugs on the edge cases, than just
doing it yourself.

I've implemented Gigya, Janrain, Auth0, Firebase and Amazon Cognito.

The only time I've seen them make sense is internal tools. The company I work
at has a policy where any enterprise tool must auth with Okta which means
logging into everything is a piece of cake for employees.

------
nitwit005
Our main apps are internally facing and need to remain usable during an
internet outage. That makes most of these products unusable.

Some of these products also seem designed and priced around more complex use
cases, such as SSO across a bunch of unrelated apps with different supported
protocols. Not everyone has that sort of problem.

------
ab_testing
I use flask-user. It does login, logout, roles, password reset, email or
username login and many more features.

------
smt88
You can use a library instead of a third-party service, which I assume is what
most people do.

------
true_religion
I am. I don’t see how Django is getting it wrong, so I continue to use the
auth provided there.

------
wprapido
Using Okta and Auth0 mostly

------
t312227
LDAP

:)

------
throwGuardian
I don't know the disconnect between HN and the real world. Auth0,Okta, AWS
Cognito, ... are all making good money, so clearly real costumers are paying
them real money.

I'd recommend using something like Fireabase as the front end, that issues
JWTs etc., but the actual user database to still yours. Firebase calls this
custom-auth. That way, you benefit from their client libraries in multiple
languages (Js, Swift, Kotlin, ...), and also from the reliability and security
of their server side, but since the actual DB is yours, you have the option of
moving to another provider, like Cognito, if need be

