Self Hosting and OIDC: hello from the rabbithole #6244
NoArmyKnife
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Prologue
After spending some days trying to self host Netbird with proper SSO (emphasis is important), I started to browse through the different Issues and Discussions of the project's Github page when I found other fellow self-hosters in distress: #5143
This discussion is my modest attempt at giving back to the community by summarizing the information I've gathered along my journey.
Before diving in, please note a few things:
That being said (coconuts in Barbados), it's time to go for a ride !
TOC
Testing setup
What works and what does not
Suggestions
3.1. Workarounds for a quick setup
3.2. Quick-win fixes
3.3. Long-term fixes for ensured stability
Closing thoughts
1. Testing Setup
For this investigation, I tested both the "legacy" (5-container stack) setup as well as the combined one, using a mix of IdPs and authentication flows:
2. What Works and What Does Not
The biggest pain points revolve around the interaction between the Embedded IdP, group synchronization, and Single LogOut (SLO).
Major Issues Found
Group Syncing: Netbird trying to synchronize groups from the "groups" claim in the ID token makes the feature unreliable because the
groupsclaim is not a stable ID Token claim and therefore should not be blindly expected to be present. The solution would be to perform a request to the userinfo endpoint, but even then it would still be an issue as-is because thegroupsclaim is not an OIDC Standard Claim.Single LogOut (SLO): In combined mode (with the Dex Embedded IdP), the logout process is flawed. The IdP seen by Netbird is effectively the embedded one, so it looks like the logout only happens from the Embedded IdP and not the "actual" upstream IdP. The "proof" of this is that when I clicked "Logout" in Netbird, I was redirected to Netbird's home page but:
I'm walking on eggshells here, but this might be the reason why (from the Dex Source code):
Note: SLO works fine in the legacy "split" mode, provided RP-initiated logout is enabled in the IdP. I tested it myself with Authentik (make sure you follow the instructions here).
What Worked (and how to improve it)
idp/dex/connector.go):Personal note: I believe it is a fairly sensible default to set the "getUserInfo" Dex config to true for every provider type since the claims wanted by Netbird (
nameandgroupsfor now, but could be others in the future) are not default stable ID Token claims, and therefore should not be systematically expected by an OIDC Client.Legacy Mode: provided the
management.jsoncontains all the necessary information, and if we only talk about Authorization/Authentication, the legacy deployment mode works with both Authelia and Authentik. However, if you decide to go this route, please consider the following caveats:For Authelia
groupsclaim in the idToken. This is done with a claim policyFor Authentik
groupsclaim in the idToken. See this Authentik documentation pageI will try to provide minimal configuration snippets for those willing to test this.
3. Suggestions
Workaround for a Quick Setup
For those who want a setup that just works (i.e. no fixes/tweaks needed in the Netbird source code) with:
Then I should recommend using the "legacy" 5-container stack deployment mode with Authentik (remember to follow the instructions here).
For those who really want to use Authelia, I would recommend the "combined" mode deployment but you would need to choose the
OktaorPocketidtype (instead ofOIDC Generic) in the Identity Provider creation modal.In order to improve the project toward more strict adoption of the OIDC protocol (which needs more strict respect of the OIDC specification), I propose the following fixes:
Quick-Win Fixes
/#callbackand/#silent-callback) to be RFC compliant by removing the fragment (#).idp/dex/connector.go#L230).Long-Term Fixes for Ensured Stability
Alllowing to disable the Embedded IdP: For people who start their self hosting journey with Netbird, the embedded IdP is a formidable idea. Netbird provides them with what they came for (a network mesh) and a turnkey IdP. This is wonderful. However, from what I could see, there are also lots of users coming to Netbird with an already working OIDC-compliant IdP. For those users, having to go through the hassle of making Dex work with their Idp (and in the worse cases, having to tweak it for that sole purpose) is a huge point of friction. This is why I would recommend this feature, implemented with a proper fallback mechanism. If the Embedded IdP is disabled, the configuration should gracefully fall back to reading relevant settings from the legacy files (e.g.
management.json), or better yet, bring those settings up to the combinedconfig.yaml.Note: it is an even more important topic knowing that the Dex OIDC connector is a beta feature
User information source: in order to take a step forward towards OIDC compliance, the profile information (name, email, groups, etc.) should be fetched from the userinfo endpoint, instead of the ID Token as currently done (https://github.com/netbirdio/netbird/blob/main/shared/auth/jwt/extractor.go#L93)
SLO Fix: The SLO mechanism needs a complete overhaul to ensure the user is logged out from all connected services, not just the Embedded IdP (beware this might not be possible if Dex does not relay the logout request through front/back-chanel logout ; I don't know for sure)
4. Closing Thoughts
Overall, the current authentication implementation is already pretty solid, and OIDC is a really complex standard with lots of specifications so props to you for initiating the work. I still believe that we - the OSS community - should do our best to implement it as close as possible to the specification when we decide to go this route. It ensures both stability and security, as well as increased confidence from the users to see that things are done according to established standards.
For those interested, an Authelia core member wrote a very interesting blog article on this topic: https://www.authelia.com/blog/technical-openid-connect-1.0-nuances/
Whatever the main development team decides to do with these observations, I'd be more than happy to perform tests and/or small code fixes that have limited impact (remember, not a golang developer, even though I'm a fast learner).
In any case thank you for developing Netbird !
Beta Was this translation helpful? Give feedback.
All reactions