1- GOOD multi-tenant support.
Without extra weird hoops like with ORY.
How this must be? Just passing a subdomain is all necessary to route and it need to make easy to create/remove tenants as part of MY logic, not need to orchestrate stuff.
2- Use my own tables. (or allow to set FX/new fields)
I appreciate to have automated all the stuff but I have much logic around what is a "user" (and in a recent project, 2 kinds of user in 2 different tables: salesman/customers).
Ideally, this stuff only need to do "SELECT fields_for_auth FROM my_table"
Ideally long term we'll add regex support for usernames/groups in both path's and domains so that people can customize this further.
If managing data directly and personally is a requirement for you, then you probably don't want these tools. Part of the reason they exist is to manage user data (passwords, tokens, etc.) correctly and with minimal surprises.
ORY Kratos, as an example, will happily create different conceptual types of users and you can store arbitrary data in those user documents, but it is modified through an API and exposes to you stable IDs against which you can code the rest of your application.
The stable-ID solution was how I handled this when I wrote one of these as an internal tool (guess you'd call it a "microservice") for a startup I worked for back in like 2010. In hindsight I guess I should have pushed to pivot to selling that as our product since we ended up selling the company for barely-pay-back-the-investors money, but who knew? Hahaha.
Also identified permissionable-objects as UUIDs, which let me handle authorization in addition to authentication. Creating a new "permission" object meant asking for one from the service, then you'd receive a UUID, associate that with whatever thing you were applying the permissions to on your end, and tell the service to assign the desired permissions. Then you could just query the permissions for that UUID (which could, potentially, represent a bundle of items, a single item, or permissions to an entire service—how to interpret it was left up to the consuming service) and of course cache them as much as you felt was proper. IIRC there as also a concept of owning-objects so you could let permissions be inherited, then override on a case-by-case basis, plus it'd let you ask which objects belonged to a given collection. IIRC I used that to represent organizations, too, since they were basically the same thing as a permissionable-object container themselves needing to be permissionable.
Not a perfectly-flexible system (billions of items that all need distinct permissions might have eventually forced sharding or something, but luckily we didn't have to worry about that) but it was rock solid for our purposes and made spinning up new services or products sharing login with our main product super-easy.
That is a major complication.
In Django, this solve neatly, because I can point to my own table or easily integrate the ones of Django without much fuss. This turn all this in a non-issue.
What you are advocating is to collapse the service-oriented architecture into a "everybody parties on the database" architecture. These tools are very much invested in you not doing that. There already exist user-auth libraries for what you want and run inside your application itself.
Is this so you can easily private label the application? Or is there some other use case for which multi tenant support is critical?
> Use my own tables. (or allow to set FX/new fields)
I'm not sure what 'FX' is (maybe a typo for 'FK'?).
Do you mean the ability to store arbitrary data on the objects provided by the auth system (even if it is via API like a sibling comment mentions) or are you talking about the ability to create tables or have a foreign key directly into your application's database? Would stable GUIDs solve this for you?
To support multi tenants in software-as-services. I need to support "company1.app.com, company2.app.com" in my apps.
> Do you mean the ability to store arbitrary data on the objects provided by the auth system...
The thing is that a "user" have different means. I have salesman's, customers, operators, etc.
Them have fields, like email, is_active, personal info, that are critical for the logic of the app.
IDEALLY the auth server manage the security and read only the fields that are needed to operate this (like for send a password reset).
The other fields, triggers, indexes, etc are more important the rest of the time.
And I don't want to use a "will create corrupted integrity for sure, aka: micro services" because I work in the "sync data across dbs" and it ALWAYS will happened if data is not in single transaction.
The password and username are in the auth system, but everything else stays in control of the application, in one database.
I don't see why you couldn't use that pattern no matter which external auth provider you are using. You'd just give up things like self service registration, but that may be the right choice for your app.
Docker isn't always the right choice, but I personally feel a lot more empowered to run infrastructure pieces that are dockerized because the inputs and outputs are much more explicit and easier to manipulate and change in isolation (I don't have to remember 3 directories where config could be, I just mount the one volume for example).
I get a little intimidated by Ory's multi-app approach to all of it (who wants to deploy & manage 4 containers/VMs versus 1 with Keycloak?), but I know I need to give it a proper chance one of these days. Hydra seems to be a very polished entrant in the space.
Depending on your use case, for example if you only have one application, you might be better off running something embedded in your app, or independent but using the same runtime/deployment environment. Then, when you are ready to add another app or integration, you should be able to introduce a standalone auth system more easily if appropriate (because all your auth interactions should be relatively standardized). I'm a big fan of standalone auth systems as a way to simplify access control and give a single view of a user/customer, but you can also succeed using open source embedded libraries.
When the moment comes to introduce a standalone system, you should consider a few dimensions (this list pulled from a previous comment of mine: https://news.ycombinator.com/item?id=26360048 ):
* open source or not
* standalone application or library/framework you integrate
* self hosted or SaaS
* authentication, authorization, user management or all three?
* standards coverage
* SSO support
* integrations with other auth tech (LDAP)
* which OAuth grants are supported
* cost
* operational complexity/support for your deployment environment
* specific features if needed (for example, customization of the look and feel with themes, or customization of the login flow with something like Keycloak's plugin system)
* documentation and developer experience
These dimensions all matter to varying degrees depending on your team and needs.Disclosure: I work for https://fusionauth.io/ which has open source supporting libraries and docs, but which is itself not open source.
EDIT: added cost, operational complexity and customization to the list.
That said, here are some more in the space that I personally have earmarked:
- (all-in-one) jsso2[0]
- (all-in-one, embeddable) a12n-server[1]
- (embeddable) node-oidc-provider[2]
- (embeddable) node-oauth2-server[3]
- (all-in-one, embeddable) authboss[4]
- (proxy) vouch-proxy for NGINX[5]
- (proxy) Grant with support for over 200 provider (!!)[6]
[0]: https://github.com/jrockway/jsso2
[1]: https://github.com/curveball/a12n-server
[2]: https://github.com/panva/node-oidc-provider
[3]: https://github.com/oauthjs/node-oauth2-server
[4]: https://github.com/volatiletech/authboss
The only downside is that it seems to require a second DNS entry for the vouch portion of the process. Awkward configuration in some ways. But, the price is right, and the Nginx config is reasonably clean once you understand what it's doing.
> - Keycloak (you won't get fired for picking this)[0]
Curious what you mean with "you won't get fired for picking this". Do you mean that it's good and easy to run, or something else?
If you are looking for a commercial solution, I would say that the top competitors are Okta, Auth0, Azure AD, and Firebase (though the latter, from what I've heard, doesn't play nicely with standards).
I mean, it's yet to be determined how Okta and Auth0 are going to integrate. I have read that Okta has three sets of APIs, maybe Auth0 will be a fourth?
> an enterprise client is probably not going to use your product because it has Firebase login integration.
LOL. It might even be a negative signal.
But I hear Firebase is thinking about supporting standard OAuth, which would be great.
Okta bought Stormpath (and killed it) and now Auth0 because of this difference, and because there's a finite total addressable market for employees, but an almost infinite total addressable market for app users.
And as others have noted, this is probably the most enterprise-grade/production-hardened solution out there in the list that I made that represents my current list in the F/OSS space. If I were to think hard about it, there are probably lots of much older options (depends on where you put the scope of AuthN to be, is LDAP a competitor?), but Keycloak is probably the one you're going to find the most resources and scrutiny around.
A large financial institution I worked with two years ago was using Keycloak. I was annoyed with some UI bits and terminology that was very confusing but it was overall a great choice back then IMO, has probably mostly/only gotten better since.
https://github.com/i-core/werther
It's a bit of a mouthfull:
> Werther is an Identity Provider for ORY Hydra over LDAP. It implements Login And Consent Flow and provides basic UI.
So basically, turn your LDAP into OAuth2, if I'm reading the features right:
> Support Active Directory;
> Mapping LDAP attributes to OpenID Connect claims;
> Mapping LDAP groups to user roles;
> OAuth 2.0 scopes;
> Caching users roles;
> UI customization.
Unfortunately this doesn't really free you from maintaining an LDAP server, it just... let's you login using OAuth instead, by bringing pieces of the ORY ecosystem along.
Not having the time to implement that ourselves, we're stuck with LDAP as a backend as the common denominator.
This feels like it might exist so I went looking, looks like Auth0 had this[0][1]. I'm not sure there are any open source projects that actually do this ldap-in-the-front-something-else-in-the-back, but you can get very close:
- https://github.com/glauth/glauth (ldap in front, local file/s3/ldap in the back, extensible)
- https://github.com/kernel164/go389 (ldap in front, YAML file in the back)
Seems like this is quite the unsolved problem (unless you're using Auth0). Maybe it's worth using Auth0 only for this. If you're going with the F/OSS solutions then it feels like you could either add a plugin (DB, OAuth maybe?) to glauth, or hack together some sort of system that updates the YAML/S3 as accounts get added.
[EDIT] - Also looks like Joyent has put together a framework for LDAP clients and servers in JS... (http://ldapjs.org/server.html). The raw pieces are there but someone would really need to put them together to offer the facade.
[EDIT2] - Also in go: https://github.com/vjeantet/ldapserver
[EDIT3] - Original code listing for auth0's connector (https://github.com/auth0/auth0-ldap-endpoint), lib/routes/authenticate.js looks very easy to work around...
Maybe one of the awesome-<x> lists?
maybe just a gist with a markdown table? or maybe expanding on this:
https://en.wikipedia.org/wiki/List_of_single_sign-on_impleme...
... if you have the courage of dealing with Mediawiki tables (although the WYSIWYG editor has improved kind of enough to make that workable nowadays...)
A few more projects in this space:
- Keycloak (you won't get fired for picking this)[0]
- CloudFoundry's UAA[1]
- Gluu [2]
- ORY (Hydra + friends)[3]
- Keratin [4]
- OpenUnison [5]
- Dex[6]
- Netlify's GoTrue[7]
All of these solutions are a bit different but here are some of the axes:
- Whether or not they function as an OAuth provider
- Whether they're centered around application-user-login via mechanisms like email/password, application auth, or SSO
- Whether or not they serve as a proxy to another down-the-line OAuth provider (Dex, GoTrue)
- GUI availability
- F/OSS-ness (basically all of them have very permissive licenses)
[EDIT] More entries for this list in another comment @ https://news.ycombinator.com/item?id=26411457
[0]: https://www.keycloak.org/
[1]: https://github.com/cloudfoundry/uaa
[2]: https://gluu.org/docs/gluu-server/4.2/
[3]: https://github.com/ory/hydra#what-is-ory-hydra
[4]: https://keratin.github.io/authn-server/
[5]: https://github.com/tremolosecurity/openunison
[6]: https://github.com/dexidp/dex
[7]: https://github.com/netlify/gotrue