question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Comparison to alternatives? Where does this solution fit in?

See original GitHub issue

Unlike Pomerium and Authelia, this project provides no UI. It is to be combined with an external auth provider(eg Keycloak for self-hosting) and a reverse proxy like Traefik or Nginx. It then upon successful authentication, forwards the credentials via headers(I’m not sure if this differs from others providing OAuth2/OIDC redirect flows with an auth subdomain and UI, or third-party SSO provider).

Is that all correct? I haven’t dug into the assertions feature or what I think you’ve called pipelined auth(mixing OAuth with JWT for example and reacting based on what was successfully used/discovered), putting those aside, what are similar projects and are those features what help set EAS apart?

While the project has support for LDAP and OAuth/OIDC, I assume it doesn’t help much with projects like BookStack which allow for third-party auth or LDAP to manage users/login accounts to their service. Is EAS able to be of value here? Do I need to request/contribute support to BookStack project to be compatible with the way EAS works? If so what is required?

For a service to work with EAS, if I understand correctly, it must support receiving user auth via header values? Grafana seems to refer to this as an Auth Proxy, as does the support with Discourse. So… Reverse Proxy(redirect) => EAS(forward auth headers on success from auth provider) => Service(autologin)? I think you have referred to this before as Auth Code Flow?(still not familiar with different auth flows yet)


In my case, I am looking at moving from services that manage their own individual accounts and each requiring separate login(or linking to a users preferred SSO provider), to a single auth gateway, where a user can link to an external SSO provider(assuming that’s compatible with what I’d like), or have all services share a self-hosted auth provider(eg Keycloak), which for services that support it can all share account data via LDAP?

A user joining the community should only have to signup/register at one location, and only link their account(eg to Google) once, not manually link each service to eventually get a single/seamless login experience across all services provided to the community. I’m not sure how achievable this is, or if EAS is suitable to achieve it. I’m still trying to grasp a good enough understanding about the auth and user management technologies available, and what is required of the third-party services to support this(Grafana and Discourse should be ok from the looks of it, but I’m uncertain about BookStack).

Single server with Docker containers for each service currently. nginx-proxy is used, but will need to be customized or switch to Traefik I think for forward auth support, as with nginx it seems to be a module required at build time(which the image nginx-proxy does not have).


EDIT: Seems I misunderstood the Discourse auth proxy, that’s the wrong direction I was asking about, as it’s redirecting users to login via Discourse SSO to the intended service url. I had thought originally that it was support for passing auth details to Discourse to login from an external auth service.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
travisghansencommented, Nov 24, 2019

@polarathene wow, great questions! I’ll do my best to explain and see if we can get you sorted out. A pretty big maxtrix of types of services exist which make the overall situation complicated and at times difficult to understand.

At it’s core, eas is not trying to be an identity provider. I felt like ldap and services providing oidc etc were doing a pretty good job of that. That’s probably the biggest difference with Authelia. It likely most closely resembles Pomerium in that context, however, a couple key differences exist even on that front:

  1. pomerium (from what I can tell) is strictly bound to oidc (you could of course use something like keycloak to expose oidc backed by ldap etc)
  2. pomerium configuration is more static, requiring different installations for housing vastly different configurations (ie: different oidc providers completely)

That’s not a knock against either project, both are great, just focused on different things. I’m fairly certain the pipeline idea in eas is fairly unique to this project but could exist out there elsewhere.

Now, regarding actual services, I would say they typically fall into categories based on the following:

  1. Do they understand authentication natively or not? (ie: many simple services simply have no notion of authentication and expect authentication to happen outside the app if at all)
  2. Do they have any real notion of users/accounts?
  3. Others?

If something natively understands authentication then I’d recommend using that (assuming it works with your backing store for unified accounts/credentials). After looking at BookStack it appears they understand oidc quite well, you may even be able to configure it to work with Keycloak using one of the existing providers (ie: ‘trick’ it into doing oidc with keycloak with the okta provider or the like).

If something does not natively understand/implement authentication then this project is great candidate…especially if they don’t have any real notion of users/accounts.

Then you have a relatively rare breed, which is something like grafana which does understand users/accounts and also has natively authentication (particularly the built-in DB), but can handle auth externally. In the vein of SSO this is also a prime candidate for eas (I and several others use this project for grafana).

You also have several other use-cases where a project doesn’t necessarily understand users/accounts (meaning, they have no meaning to the app) but optionally allow you to turn on some crude (usually basic auth with a static single user account/password) authentication mechanism. This is true of projects like sabnzbd, radarr, sonarr, lidarr, and about a million others. If you want true SSO you could put each of those behind eas.

Lastly, like the grafana situation, if you’re actually developing an app and want to use oidc, but don’t want to implement the whole workflow, then using a project like this makes sense (ie: you expect a valid jwt to reach your service in whatever fashion the client gets it).

In my case, I use ldap for users and configured keycloak backed by the same ldap store. This gives me unified set of credentials to use. Services that natively understand oidc/ldap I simply use their ocnfigurations. Services that don’t I generally put ‘behind’ eas. The eas configuration is setup with a pipeline that understands oidc and basic auth so I can handle end-user (oidc) clients and machine (ldap via basic auth) clients on the same endpoint with the same config.

Let me know if there’s anything else I can share to help out!

2reactions
travisghansencommented, Nov 25, 2019

Yeah, lots of good stuff here and great questions. I’m pretty pragmatic so ultimately use whatever best fits your needs for sure. Also note I don’t consider myself an ‘expert’ in the arena either…this whole project was more of a “I seem to always be fighting these solutions, I guess I’ll make my own that does what I need” situation. In that vein I was aware of several of the alternatives you’re digging into. A handful of criteria led me to my own:

  1. some tools were specific to certain proxies
  2. I’m not super excited to add another proxy (ie: oauth2_proxy, gatekeep, etc) for a couple reasons 1.1 operationally it can be a headache to deploy those ‘in front’ of whatever you’re actually deploying, for example (not sure if you use kubernetes) but deploying with a helm chart or the like it’s highly unlikely the chart supports injecting random proxies along with the service 1.2 requires you deploy new instances for each service and/or config variation (this project embeds config in the URL so a single deployment can service essentially unlimited number of services/providers/configurations)
  3. some solutions don’t let you pass down portions of a jwt (or even the whole jwt) to backing services
  4. some don’t actually refresh tokens, gather userinfo, or generally reup the auth data (ie: you authenticate, a cookie is created (sometime long living) and nothing is checked until the cookie expires and the whole process starts over)
  5. I wanted more than oidc to better handle machine to machine scenarios. This can be mitigated to some degree (ie: manually issue a long-lasting token and auth against that) but I generally didn’t love the options.
  6. re-iterate the dynamic config mentioned above but outside the context of proxies…I wanted the service to be essentially stateless. This proved challenging but outside a caching mechanism and optionally using server-side tokens I’ve achieved it. Even server-side tokens can be essentially stateless when served up via a ENV variable or simple json config file.
  7. I wanted ability to have complete control over the authorization process as well. At least in the context of allowing certain endpoints/routes/verbs to be allowed without authentication.
  8. Separation of duties. Many options probably support this but it’s good to note/consider. I wanted the ability to keep the holders of the secrets and issuers of the config separate from those running services which simply use the authentication server. For example deploying with a ‘proxy’ solution is unlikely to operate in this fashion. In the case of this project, the eas server itself can be managed by a security/identity team, and they simply create encrypted config_tokens and hand that off to operators wanting to use/add authentication. Because the config_token is encrypted, operators deploying services that use eas do not necessary need to know oidc details, or ldap server connection strings, etc.

Regarding a UI, it is conceivable to create one and I’ve considered it longer term. However given the attempt to be as stateless as possible, it UI doesn’t make a lot of sense. It basically could/would serve 2 purposes as I see it:

  1. Wizard for creating config_tokens to ease that configuration process. There is quite a lot of power involved with this project making this particular idea a pretty daunting task. However, for basic use-cases it’s probably pretty easy to knock out.
  2. If using server-side tokens (for example backed by a SQL DB) it could act as a management interface to those (including the wizard mentioned above). ie: “I want to issue a new config, step me through the wizard and store it in the DB…now let me see all the tokens I’ve issued and give me an option to revoke them etc”…by tokens here, I mean config_tokens, not authentication tokens for individual users.

Back to your addressing your specific questions/comments from above.

There are a couple ways of viewing SSO I suppose. There’s literal SSO where if I’ve already signed into the IDP (identity provider) I don’t have to a second time (even though I may be redirected there and immediately be redirected back to the desired service without the user even noticing). More broadly (and generally more important to me) is having a unified set of credentials…even if I have to login multiple times, I’m using the same account.

You certainly could achieve SSO with ‘social’ providers but then you have to question whether you want your users to have an account directly with you or not. This question is entirely subjective and there’s no blanket ‘right’ answer. Even using Keycloak you can actual federate your users via social IDP. For example you can deploy Keycload and set it up to authenticated via google OIDC (super confusing, I know). If I were wanting to run my own community I’d probably run with housing my own accounts in an LDAP server and using keycloak (or alternatives) to add oidc support but all backed by the same LDAP user/group store.

That would place EAS in the same category as other projects that protect services behind an SSO proxy/gateway right? With EAS being one of the few that supports a wider range of auth protocols?

If I use Keycloak as my auth provider, they also have Keycloak Gatekeeper, which seems to be capable of achieving the same functionality(along with a UI for login if you’re not deferring to an external auth provider like Google/Okta). Would EAS be serving the same purpose as Gatekeeper, or can it compliment it?

Yes it does. Yes, same purpose as gatekeeper. When used with something like keycloak you would be redirected to the exact same login screen keycloak provides as gatekeeper would do (see above for why I personally don’t love extra proxies in this context).

Is there a proper / common term for this type of auth? Seems unfortunate that it’s not as common. For BookStack I tried to look into the PHP Laravel libraries for auth, and they seem to be Laravel Socialite and Laravel Passport, but it’s not clear to me if either can provide the same auth functionality Grafana is able to offer.

I don’t know of a term for this. There could be one. Laravel using socialite and password are likely implementing much of what this kind of project does, but doing so natively. I would be highly surprised if you cannot make BookStack (ie: socialite/passport) point at a generic oidc provider. I mean, everything is there and clearly already understood for several of the bigger providers implementing the spec.

Basic auth as in the browser dialog pop-up using htpasswd? With EAS are you moving that to be handled by EAS instead of per service?(and thus able to use anything else like OAuth/OIDC providers or JWT?

Yeah, you could use eas to ‘front’ those with oauth/oidc…but this is a place where eas gets interesting. Basic auth doesn’t have to be htpasswd, in fact I serve up basic auth using ldap connection. In particular, these services are highly likely to have 2 kinds of users, end-users, and machine/api users. Since my keycloak is backed by the same LDAP users I can authenticate the same service using a unified set of users for both basic auth (back by LDAP) and oidc (backed by keycloak…back by the same LDAP). So if I want to configure something using the API I simply plugin the same username/password as I would type into the keycloak interface if sent there. I specifically handle this situation using the pcb functionality of eas and look for the Authorization header. If it’s present and has a value starting with Basic then I target the LDAP integration, if not, it’s assumed it’s not an api-style user and keycloak/oidc/sso stuff kicks in.

That sounds like a really good use-case! Sort of like Laravel Socialite/Passport, but language agnostic? I assume it’s like using Keycloak Gatekeeper, and optionally Keycloak or something else for user management if needed, but perhaps EAS is simpler to integrate with?

It’s for projects that may not have access to something like socialite/passport…or simply doesn’t want to integrate the workflow at all. You would use something like keycloak for IDP and the backing service simply expects a jwt as some header (usually the Authorization header with a strategy of Bearer).

Ah ok, I take it you were aware of Gatekeeper before building EAS, what was the motivations for such vs using an existing solution like Gatekeeper? Were there missing features, or did you need something lighter/simpler, what is the selling point here for choosing EAS?(nothing against it btw, it seems like a great option!)

See reasons above. Again, I’m pretty pragmatic so my feelings aren’t hurt if another project fits the needs better. Pomerium + Keycloak seem like a pretty good option for what I’m gathering you’re doing. While eas doesn’t have a fancy UI, it does have some advanced features that you may not find in Pomerium. In which case, eas + keycloak backed by LDAP would be highly recommended.

That’d work for personal use for me or a small team. I may have to go with that if it’s not feasible to pull them all under one SSO umbrella implicitly for users that register to the community.

There may be a disconnect here. You’ll likely have a mix of apps that do natively understand oidc, and some that don’t. When using eas + ‘those apps’ both configured to use the same keycloak instance would certainly provide an SSO experience across the board. Again, consider the meaning of ‘SSO’ as well.

Say you configured BookStack to natively communicate with a keycloak instance, and then fronted some generic service with eas pointed to the same keycloak instance. Let’s also assume that user1 tried to access BookStack, was redirected to login at keycloak, did so, and was returned to BookStack all authenticated etc. Now consider they attempt to access a service fronted by eas (or generally any of the options you’re looking at which support oidc). Presumably eas has not created a session for them yet, so they are redirected to keycloak to login, upon arrival at the keycloak login screen keycloak detects they are already logged in, so they are redirected back to the original service (ie: eas fronted service) without ever even seeing the login screen. Upon arrival back at the service eas checks to make sure all is in order and let’s them through. It’s a complicated series of redirects but most of them the user is probably completely unaware of as the browser does it so fast they don’t even notice. That’s SSO at work for both an app the ‘natively’ understands oidc and one that doesn’t.

Ultimately, you’re going to run into services (lots of management UIs for example expect authentication to happen outside) that don’t to authentication and don’t really care about users (meaning, needing to know the difference between userA and userB…they either are authenticated or they are not). Maybe these aren’t even things you want your broader community to access but internal admins. eas makes it so you can leverage your existing login/SSO for those sites as well. Giving you the ability for example to say, you can only access this service if you can login (SSO) and if you belong to group X (presumably LDAP groups sync to keycloak). Or even target specific users, so even if someone is ‘logged in’ it doesn’t necessarily mean you want them to access management interface X or Y.

Hopefully some of this babbling is helping 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to make effective decisions by comparing alternatives
One way to do this is by creating an alternatives comparison table: ... There is no better/worse solution, focus on why each alternative ......
Read more >
Masterful Decision-Making: Identifying the Right Alternatives
Meticulously researching the contexts of the problem, analyzing and comparing various alternatives, and consulting the findings will help ...
Read more >
Comparison to alternatives | Meilisearch Documentation v0.30
Deciding which search solution is the best fit for your project is very important, but also difficult. In this article, we'll go over...
Read more >
Building your Business Case - Analysis of Alternatives | CMS
The Alternatives Analysis gives us the opportunity to choose 3 or 4 options that seem reasonable, and build out some information so we...
Read more >
Traffic Analysis Toolbox Volume XII - Chapter 5
Benefit/Cost Analysis – This compares the sum of all costs with the sum of all benefits associated with an alternative. The benefit/cost ratio...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found