I was looking for turnkey AuthN/AuthZ using OIDC for closed networks and self hosting, turnkey as in being able to drop a configured container in place and hit the ground running, and not being dex with keycloak.
If you're looking for something but more production ready, Authelia seems like a good option. Vouch and oauth2-proxy are even simpler but more specific in what they do. If you can provide more details of what you're trying to accomplish I might be able to give more specific advice.
I'm looking for something that can federate identity, i.e. allow login with the @company microsoft identity provider, or support a users table, and ideally allows linking them. I just want to properly authenticate for internal tooling.
Thank you for the nice words you describe well what we try to achieve!
With ZITADEL we aspire to become the best of Auth0 and Keycloak in more modern package. Or in other words are a end-to-end open source identity infrastructure. I know this sounds a little unspecific but our goals are:
1) Have AuthN/AuthZ, Login, SSO as Turnkey features but also allow people to build their own UIs
2) Have an audit trail that allows people to see all changes ever made
3) Give devs the ability to extend zitadel with custom code (actions)
4) Support well given standards (OIDC/Oauth/SAML/LDAP) with certification if possible
5) Be ease to operate and scale
6) Provide APIs for everything ;-)
Btw. its always nice to see other projects to solve problems in the identity space. To me it feels like Obligator can, at the moment, be best compared to Dex since it feels a lot like a façade service that has little user management capabilities (not that this is a bad thing) but wraps them for easier usage in multiple services. But please take this observation with a lot of salt since I have not used or tinkered with Obligator.
Fair enough, but developers and sysadmins don't want to choose between two great options. They want one obvious best option and a second option that is good enough and can be made better if option one turns evil.
Gitlab is a great example of what I'm saying. Few use it today but that's probably where we would all go. You know, because we never actually learn the lessons of centralization.
I use keycloak, but it's Java and I need Go or better performance.
With the new UI mass admin tasks are no longer possible.
At least version upgrades are better now.
Keycloak has no ed25519 support. Louketo proxy or whatever it's called nowadays only supports RS256, so I had to write my own OIDC middleware.
At least they stopped generating UUIDv4 secrets.
Hydra is too complex.
Dex is too simple.
Identity Server lacks performance because C#.
Zitadel, heard but not tried yet. The keycloak vs zitadel page doesn't help. Is the Zitadel access token also jwt like in keycloak and included role membership?
I use a Vue client specifically for Keycloak.
The generic openid-connect-client is unmaintained.
The TS fork doesn't have a working, maintained, reactive implementation.
Why does OIDC have to be so complicated?
I know why... so you, like with k8s, trust external, paid for (expensively), companies with your work and data.
The old "make it complicated so people would rather pay for our services".
Remember the story about the oauth1 creator quitting the oauth2 project?
> Zitadel, heard but not tried yet. The keycloak vs zitadel page doesn't help. Is the Zitadel access token also jwt like in keycloak and included role membership?
By default Zitadel uses opaque tokens but you can switch to JWT and use an piece of JS code (actions) to insert whatever claim you want into the tokens
i think most people look at keycloak, and just feel overwhelmed, but that seems to be the case for OIDC in general, they always feel insanely heavy, something like this with a flatfile config and single file executable seems pretty amazing.
You might want to take a look at FusionAuth (I'm an employee).
It's not open source, which may be a deal breaker for some, but it is "free as in beer". If you use the community edition and run it yourself, it is free for however many users you want. Also supports SAML (I know, I know, but when you need it you need it).
I recently came across Caddy Security[1], and while it's not an OIDC IdP itself, it does serve as a good authentication gateway that's easy to get up and running and maintain.
Amazing. I was looking for something like this about a year ago. Looks very promising and may be a good drop in replacement for some simple Auth0 use-cases as well as homelab setups.
I was not able to get past „ redirect_uri must be on the same domain as client_id“. Maybe you can give an example of a valid client id for your demo instance.
Sorry, this is indeed not very clear. Others already answered well, but if you look at the example[0] config you can see how you would use your own instance of obligator as a client to the instance running at lastlogin.io. This is a bit meta, but applies equally to any client application.
This looks great! I will definitely be taking a close look. Only thing I noticed with a quick try is that portier allows both a magic link and code for passwordless email login. Magic links are much more vulnerable to attack than codes because the email providers and anyone who may have access to your email can hijack your login from any location. I think it's fine to provide magic links but that choice should be the user's option when they enter their email, after warning them of the security implications.
EDIT: They actually address this in their non-goals document[0] but disagree with the decision, since many users may not realize the tradeoffs.
Thanks for pointing that out! Maybe we can improve on that, even if we keep it as a non-goal.
Right away, a partial mitigation for current versions of Portier is to modify the `email_*.mustache` templates to remove the link. But a second piece of information Portier leaks is simply which sites you're logging into. That's right in the subject for Portier, and not something you can customize for current versions.
I think it's worthy to try and harden against this type of attack, but I'm worried the effect is limited. There's often nothing stopping someone from simply starting the login process / creating a new session, so an attacker just has to know where, and there are a bunch of ways to find out.
Ohh, looks extremely promising, I've been after something with a bit more flexibility than Dex while not being Keycloak/Java etc, an LDAP backend would be awesome as well though (another thing thats lacking is a simple ldap server, perhaps with sql as db, openldap is excessive and glauth isn't there)
I think I did and when I couldn't find useful installation details I gave up, I don't use docker or kubernetes, so if projects can't be bothered to make information available for a generic install, I immediately lose interest.
I do plenty of native installs, and I find Docker based instructions to be a pretty nice universal codex for how things work.
Docker entryscripts sometimes have significant magic baked in (alas), but quite often Docker is a distribution mechanism more than anything else. The Docker guides are - 9 times out of 10 - more than informative enough to show how to DIY in any other of the dozens if not hundreds of other system types you might have.
If you want to resist using the easy thing, I personally think it behooves you to not bounce so quick. You don't have to use it, and it's good nearly universal documentation as to how to operate the thing.
It means I have to sit and read through the Dockerfile (or compose, in many cases, which is even worse) and figure out what its doing and what magic variables I need to provide etc, when just providing a binary download url and an example (or reference) config does just fine, not everyone uses docker
Easy != Simple. Not everyone wants to play around with Dockerfiles, docker compose and what not. Sometimes a plain binary is preferred. I say this as someone who likes docker for certain use cases but docker is not my solution for everything.
Rootless Podman uses slirp4netns by default. The default will soon change to pasta. Pasta has better performance than slirp4netns. For best performance if your container supports it, use systemd socket activation because the traffic over the activated socket will have native network performance.
Probably for user containers, but I've only ran it as root generally to avoid those sorts of limitations so haven't noticed any issues - I rarely use docker and only use for quick testing and then switch to non-docker installs
Disclosure, I'm an employee of FusionAuth, which is another auth server in this space.
Interesting that this project supports features you'd need for an internal network setup (trusted headers, forward auth) and an external facing network (support for Google/other identity providers, anonymous clients based on domain name).
I'd be careful mixing those two feature sets myself. Maybe I'm missing something.
I also loved the comparison of OSS identity providers[0]. Putting it into a google sheet for easy sharing and commenting is a great idea!
> Interesting that this project supports features you'd need for an internal network setup (trusted headers, forward auth) and an external facing network (support for Google/other identity providers, anonymous clients based on domain name).
Yep. There are two primary schools of thought on self-hosting, with echos of the VPN vs BeyondCorps tradeoffs.
The VPN approach is to keep everything locked down on a private network, likely a virtual network using WireGuard, and likely provided by Tailscale. The main tradeoff here for self-hosting is that everyone you want to share with needs access to your network, and unless no one has any private data you're still going to need account management of some sort. Also if one of your trusted devices gets compromised, the attacker can get access to the "soft squishy" inside of your network. If you're doing single user instance (SUI) hosting, this is likely what you want.
The BeyondCorps approach raises security to the application level, and exposes services directly to the internet. The main tradeoff here is that each app represents a potential attack vector. Since I host websites and file servers, obligator was built to facilitate this use case.
Question about this indie auth thing, or anonymous clients, mentioned at the linked page.
Wouldn't that effectively grant access to your user data to everyone, regardless of their intentions?
Meta, for instance, has very strict TOS and privacy policy checks before approving a client_id. And those checks are on-going.
One problem with comparing to social login providers is that their OAuth2 APIs tend to provide a lot more access than just OIDC, which greatly increases the risk of phishing and other attacks. Since a simple OIDC server like obligator only deals with identity, the worst case scenario of a phishing attack is that the user's email address is exposed to the attacker.
You can think of obligator as a server that responds to client app requests with a response of "I have verified that the user running this OIDC session has control of X email address as of Y time".
Right, I wasn't sure if you were referring specifically to the user's profile information on the OIDC server, the other user data stored by the same entity which runs the OIDC server (which is common but not the case for obligator because it's identity-only), or the user's data on the app that they're trying to log into.
Can someone explain which services this is supposed to be an IdP for? As far as I know, services need to have the OIDC service registered (ie I can't just auth with this to Google or whatever).
Not sure I'm reading your question correctly, but if you want to use obligator as an IdP for other apps/services, they don't need to be registered as long as they set the client_id properly. That's the "anonymous client" auth described. However, in the simplest case you would have to verify any email addresses by having a confirmation email sent. To make this more streamlined, obligator can also act as an OIDC client for upstream OIDC providers such as Google, GitHub, etc. Once obligator has used an upstream provider to verify an email address, that address is treated exactly as if obligator had verified it itself. In this case you are correct in that registration is required with each upstream provider.
Ahh that makes sense. And you are essentially correct. Generally speaking clients expect to be aware of who their IdP is, and currently Google/Facebook/Apple/Microsoft have a stranglehold on the "approved login IdP", with a few dark horses like GitHub.
The original vision of OpenID (ie pre-OpenID Connect) was for applications to support any IdP, and you just tell the app what your IdP is when you create your account. You could also imagine browsers filling this in automatically. This didn't pan out in practice, primarily because no one used it[0].
However, it's becoming more realistic to run your own IdP, both by self-hosting and by using services such as Okta.
Tailscale actually let's you bring your own OIDC IdP. It uses WebFinger to prove an IdP has authority over a specific identity (email address). This is even more streamlined than entering your IdP directly. You just give Tailscale your email and they automatically send your to your IdP to authenticate.
But I wouldn't hold your breath for the major email providers to implement WebFinger so users can choose their own IdP. Which is one of many reasons I'm a big advocate of people using their own domain for email, even if the email itself is hosted by someone else (I use and love Fastmail).
Thanks, this is very informative. I was really hoping OIDC+WebFinger would catch on, it was a more or less equivalent experience to Mozilla's Persona, which I was a big fan of.
Thank you for mentioning Persona. I sadly missed that train when it was a thing, but it's always sounded cool. I think it's basically what I want. Comparing to it in the docs would actually probably be a good way to explain the purpose of obligator.
Persona was the best way to do identity management. Using your email address to authenticate was genius, and it worked with any email provider that would accept your email address. Even if you self-hosted, with things like name_of_site@yourdomain.com, it would still work (unlike logging in with Google, where the site gets your main email address).
The readme links to another blog which explains the use case in more detail, but this quote sums it up I think “In a world where everyone's own website is its own OAuth server, it's obviously not practical to have an app developer register API keys at each.”
So, I build some app for Wordpress sites and self-hosters want to use my app against their WP site that they also made into an IDP. Then we get the issue of the app needing to be (pre)registered with the IDP, and set client_id and client_secret in its config.
Okay. I get that. But why on earth are we assuming that a self-hoster who can setup her own IDP cannot also create this app registration herself, and add a client_id/secret to a configfile before starting my app?
> why on earth are we assuming that a self-hoster who can setup her own IDP cannot also create this app registration herself, and add a client_id/secret to a configfile before starting my app?
Excellent question, and it gets into the meat of why I made this in the first place. obligator is the first piece of the puzzle I'm trying to solve to make self-hosting as easy and secure as running an app on your phone. In that world users cannot be expected to pre-register OAuth2 applications. But above and beyond that, registration creates friction that I feel is unnecessary and doesn't add enough additional security (and as mentioned can even reduce security when implemented poorly) for me to want to bother with it myself, so I built a server that doesn't require it.
IndieAuth is super super cool and a vital component to get back control of the internet to users, but I can't shake up the security concerns.
Also, near the end of the article. Using a security nightmare such as Wordpress as your identity provider, what could go wrong? It only takes one single rogue plugin.
Someone breaking into a Wordpress install due to a plugin's 0-day for example, and then being able to log into all the accounts managed by that WP's openID server.
Cool, but I looks like the creator didn't really look deep in the competition. Many of the question marks in the comparison table can be replaced by a checkmark.
I looked more closely at the simpler ones, since simplicity was a baseline requirement for me when I went looking for a server to meet my needs. If the docs for something were too complicated to even determine if it supported the features I need then I tended not to spend much time digging through them.
Indeed. It is slightly misleading at first glance. But the author has stated that it is incomplete. ZITADEL(https://zitadel.com/), for example, pretty much checks almost all the boxes.
> ZITADEL doesn't support anonymous clients. Honestly, it's not the best practice anyway.
How would you accomplish the same thing using best practices? The closest is dynamic client registration without requiring an initial access token, but that still requires clients to support the protocol, and I know at least the Jellyfin and Discourse OIDC plugins do not. And even if they did what do you gain over anonymous auth?
Authentik is one of the ones I actually searched more closely through the docs, as it's a popular choice for self-hosting. Can you point out specific inaccuracies so I can fix them?
It's tricky to figure out if some features are supported across different servers because the features have different names, and the more features a server has the harder it is to dig through.
> I believe it does offer trusted header auth, although I haven’t used it for any of my apps to test out
Fixed, thanks. Do you know if custom headers are returned when using forward auth, or only when Authentik is acting as a proxy?
> It doesn’t offer “Passwordless email login”, but offers “passwordless login” in the form of passkeys (with a tiny bit of setup).
In the case of obligator, email support specifically is important. Passkeys are really cool, but unless I'm mistaken there's no way for me to say "give the owner of this passkey access to this data" even if they've never yet logged in to your system. This is a critical use case which works great with email, even having a built-in way to notify them of their new access. I would love to see passkeys extended with some sort of proof that the passkey is tied to a specific email address (or other global ID), so you can login without talking to an IdP but also get the benefits mentioned above.
> Definitely offers upstream OIDC, I have my instance set up to be able to sign in through AAD or locally
Already had that one. Were you maybe looking at Authelia? Though I believe I read somewhere that they are working on support too.
> I would love to see passkeys extended with some sort of proof that the passkey is tied to a specific email address (or other global ID), so you can login without talking to an IdP but also get the benefits mentioned above.
"Passkeys" (FIDO2 Authenticators) support this. The CTAP2.1 protocol contains "enterprise attestation", which allows an Authenticator to identify itself uniquely to a particular Relying Party.
An explicit design goal of the FIDO standards is to prevent the server from knowing that two different FIDO credentials originated from the same Authenticator (in other words, treaing a new user as non-anonymous). In order to preserve that property, Authenticators need to be explicitly coded with the RPs for which they'll support Enterprise Attestation.
If you have such an authenticator, the server can say "give the owner of a passkey presenting a valid Enterprise Attestation for bob@example.com access to this account".
But, again, FIDO isn't supposed to let random web sites on the Internet notice that two "different" users are actually using the same passkey (tracking users between web sites!), so you can't get the property you're looking for without Enterprise Attestation.
I'm fairly sure you can set custom headers with the forward auth (although I have never used it), you just have to configure it in the reverse proxy as well.
I believe you could setup email login by using the email TOTP 2FA much like I use my yubikey for passwordless authentication. You can modify the flows quite extensively... if you know what you are doing
> Already had that one. Were you maybe looking at Authelia? Though I believe I read somewhere that they are working on support too.
Very well might’ve been, the mobile view of the table isn’t fantastic so it was quite a bit of scrolling; definitely could have messed that up.
> In the case of obligator, email support specifically is important. Passkeys are really cool, but unless I'm mistaken there's no way for me to say "give the owner of this passkey access to this data" even if they've never yet logged in to your system.
No, the user would need to enroll it. They could use a social login (upstream OIDC) without logging in through customizations, you can pre-create their user or create it on demand and give it appropriate access based on the upstream response. I don’t think you could implement magic links, even as customizable as it is.
I think I looked at the wrong column on mobile. While we're here though. Authentik has basic multitenancy support. I wonder if that qualifies as multi domain auth. Sorry about the mistake by the way.
Just to be clear I was not the one to come up with anonymous client auth. This comes from the IndieAuth/IndieWeb community, and I link to Aaron Parecki's article[0] describing it in the repo.
That said, IndieAuth isn't OIDC and obligator may be the first OIDC implementation that uses these concepts.
Using email magic links as authentication mechanism is not a great choice in my opinion as email is not a very secure protocol if you think about the default smtp security guarantees and man-in-the-middle interception, either on the smtp or on the network level if servers communicate unencrypted.
If you believe email to be the weakest link in the chain, then you have to get rid of email password resets too and use reset codes instead. Lose your codes, lose your account.
With these servers/services you can usually chain to another identity source (e.g. ldap directory+kerberos) so that would fall to the origin identity service. But even if you don't chain it the owner of OIDC provider will usually provide an administrator role and integration system accounts that can be used as an out of band sort of user account recovery mechanism.
There is one difference here - email reset would lock the legitimate user out of the account, whereas email magic links would not. I think that's an advantage for the former.
On the surface yes. In practice, it's more like email + whatever kind of security system your email provider has set up to verify its really you.
I.e. try to log into a gmail account from a new machine in an unfamiliar location, even if you know the password and can receive SMS codes.
So right now, I'm more worried about getting locked out of a mail account than that someone else could take it over.
As for unencrypted SMPT, there is SMTPS [1]. I'm not sure if this seever supports it, but I'd assume it would be a basic requirement if you want to communicate with real-world mailboxes and not instantly flagged as spam.
just because email is often the defacto identity on the internet doesn't make it a good idea (bandwagon fallacy). i don't consider email tokens to be a serious form of authentication. unless you send the user their authentication secret with data encrypted by the user's public key, i strongly recommend against any use of email-based authentication.
* there are a huge number of middlemen in emailing that you have to trust. the sending email provider, the receiving email provider, ISP, email client, the device the client resides on. and everyone else in between.
* unless you're just hosting an email server on your local network, starting up an email server that can successfully get its messages across the internet to your intended recipient is an extremely high barrier.
email is an extremely error-prone protocol. there's lots of reasons that government/health organizations don't send you personal private information by email and instead send you an email that says to come log into their secure platform to view the private information.
There are mitigations for these security issues. The most important is that you only email the user a random code which is bound to the browser login attempt session. The user is required to enter the code they received in that session. This removes the need to trust any of the parties you listed.
you still have to trust the client device. but i guess if someone else is there you're screwed anyway.
also, email has a potential for a big delay. a lot of times people need to log in quickly. email doesn't always reach the destination in a timely manner.
The UX challenges are real, no doubt about that. That's actually one of the main reasons I started down the OIDC rabbit hole. I was using only passwordless email logins on my services, and wanted to provide my users with the UX of social login without forcing them to give up their privacy to ad companies.
Huh, I honestly didn't know it was that big. Forgive my ignorance, I've never really used Whatsapp. Can you send a message to someone that hasn't added you as a contact? If so I would seriously consider implementing this as an alternative to email.
The main problem is that it's not federated and completely under Facebook's control. Also, identity based on WhatsApp is still vulnerable to simjacking, correct?
> The main problem is that it's not federated and completely under Facebook's control. Also, identity based on WhatsApp is still vulnerable to simjacking, correct?
I was going to comment „but I can already do a lot of that with Authelia and it is very simple to configure“, but then I found your very good comparison page - good comparison!
I know the Authelia team is hard at working supporting some of the use cases that are currently not supported, so I will probably wait until some things are implemented there instead of switching.
Regardless, with something like mod_auth_openidc or another Relying Party implementation, all of the sudden authn/authz becomes easier to manage (you can literally get user information including roles in headers that are passed from your gateway/relying party to apps behind the reverse proxy), regardless of what you have actually running your APIs: https://github.com/OpenIDC/mod_auth_openidc (there are other options, of course, but I went with that because I already use mod_md).
It's actually cool that there are plentiful options in the space, since OIDC is pretty complex in of itself and attempts at creating something pleasant to actually use are always welcome, I've also heard good things about Authentik: https://goauthentik.io/
Obviously this is subjective, but I actually disagree somewhat. Once you get down to actually writing the code to implement OIDC, it's rather simple. But I feel like the specs make it look pretty scary.
I think the confusing part for me was understanding why some parts of it seemed to have so much song and dance (ie the three legged authorization code flow, PKCE, etc). I find the best way to understand the complexity is by having it explained in the context of what attacks are mitigated by specific steps. For that, documents like https://datatracker.ietf.org/doc/html/draft-ietf-oauth-secur... are much more useful.
Must admit I've treated all my selfhosting like an coconut: Hard shell on the perimeter (firewall & wireguard)...but inside the home net its all just wide open.
The comparison with simply just Hydra is rather unfair too as the strength with Ory products is when they work in tandem (e.g. oathkeeper & hydra). Hydra is as barebones as you can get for a OAuth2 provider - that’s all it does & is meant to do. Stack it with Oathkeeper and you have a dynamic way of enforcing endpoint authentication that can entirely be managed using Kubernetes custom resources. Nothing I’ve found comes even close to touching the Ory stack in that regard.
The Ory stack looks to be very high quality for sure. But so far in this thread there's been mentioned Hydra, Kratos, and Oathkeeper in order to run an OIDC server. You say Hydra is as barebones as you can get, but by itself it has 58 direct dependencies. I'm sorry, it just seems to be targeted at a completely different demographic.
When has the number of dependencies ever directly correlated with the feature set of an application? Have you ever looked at a node_modules folder? More over, how is that relevant in any way? This argument against dependencies has always felt like weird NIH-ism spawned out of the same crowd who still thinks that C is a good programming language. Have fun reinventing the wheel, but I’ll take my dependencies to go.
Additionally, you’re conflating an OIDC server with a full IdP, which Hydra explicitly is not. I don’t need a full identity provider with support for user profile pictures and a pretty UI if all I’m doing is controlling access to API endpoints via OAuth2 client credentials. I already have an identity provider, and I’m not foolish enough to think that I should host one myself.
You’re completely correct in that you are not the intended demographic if you don’t understand the utility of the Ory stack, and that’s okay.
Dependencies are correlated with complexity in my mind. This is based on my experience, which may be different from yours. My experience with node_modules is actually where I started to become wary of dependencies and try to minimize them in my code. You definitely to be careful of NIH. I find sometimes a better approach is just to cut features.
I think I understand the utilty of the Ory stack. Looks like some excellent kit doing excellent work for a lot of people. But it didn't solve my problems.
> By forcing the user to decide whether they trust the actual domain where the ID token will be sent, and not displaying any sort of logo which can be faked, security is improved.
Hilarious.
Look, security UI is hard. Like, stumps experts hard. Like, they've been working at it for decades, trying to educate the population, hard.
I appreciate the will and the effort (as someone looking for their goldilocks OIDC proxy,) but this claim is a bit strong.
I was looking for turnkey AuthN/AuthZ using OIDC for closed networks and self hosting, turnkey as in being able to drop a configured container in place and hit the ground running, and not being dex with keycloak.