1. 2

    Folks building new software (and not using hosted auth services like auth0 or Google accounts): are you still building your own auth system from scratch or are you using an existing open source system like keycloak or kanidm?

    1. 9

      As the main back-end guy at my company, I decided to use Keycloak for our system’s authentication. It has pluses and minuses.

      The minuses: Up-front development and setup cost was MUCH higher than a simple username/hashed-password table. I spent a fair bit of time fussing with Java OAuth libraries and Spring Security before I got it working the way I wanted. Stuff like “let users manage their own API keys for non-interactive clients” turns into a minor ordeal involving multiple OAuth tokens and fake Keycloak user identities. Customizing the registration flow is a hassle compared to implementing it as a couple extra pages in our main web app. The admin UI is a little clunky (though, it must be said, still far nicer than any of the other auth packages I evaluated). Its role-based access control setup is not flexible enough for our application and I ended up building my own authorization layer.

      On the plus side, adding a working “log in with Google” button to our app took me all of 5 minutes. Adding “log in with Apple” took longer but was still pretty quick (and most of the blame for it taking longer is on Apple, not on Keycloak). When we wanted to set up a Grafana instance and let employees log in with the same credentials they use for our web app, I just configured Grafana to use our Keycloak server as its OAuth provider, configured Keycloak to only allow access to users with our “employee” role, and it was done. Other internal tools sit behind an oauth2-proxy instance that uses Keycloak for login, and the tools don’t need to know anything about where the user data lives. My expectation is that we’ll be adding other such services over time, some end-user-facing and some not.

      On balance, I think it was the right choice for us, and the advantages will grow over time. But the minuses are significant enough that I can’t say that with absolute confidence; I could envision an alternate reality where it took me less time to do all the “easy in Keycloak” stuff from scratch than it took to mess with Keycloak.

      1. 1

        Thanks for the details!

        Up-front development and setup cost was MUCH higher than a simple username/hashed-password table.

        I think this is always the case with every separate auth system to be fair.

        The admin UI is a little clunky (though, it must be said, still far nicer than any of the other auth packages I evaluated).

        Since you mentioned you evaluated others… any info to share on specifically which other auth systems you ended up not going with?

        1. 2

          I think this is always the case with every separate auth system to be fair.

          Definitely, and going into it I expected it to take longer than a simpler system. I just didn’t appreciate how much more work it was going to be. There were lots of little fussy details that weren’t apparent when I did my initial proof-of-concept implementation as part of the evaluation process.

          Others I seriously evaluated were CAS (which seemed capable but just getting it up and running at all was a nigh-impenetrable configuration nightmare and it didn’t look like it’d get any easier afterwards), OpenAM (seemed okay-ish, but it seems like they started off with a commercial package, half-converted it to a community project, then got bored and released their work in progress, which didn’t give me lots of confidence about its long-term viability), and WSO2 (my second choice after Keycloak, but quite resource-hungry and forces you to muck around with XML to configure permissions).

          Those aren’t the only auth packages out there by a long shot, but they were the only ones I found that met our specific product requirements. Definitely worth figuring out what you really need out of such a system before looking for candidates.

      2. 4

        Building from scratch every time. But I do reuse code from project to project so it’s not entirely “from scratch” as that wouldn’t make any sense. Much auth code can be reused as it’s the same basic functionality with only minor things that change from project to project.

        1. 2

          the second

          1. 1

            Which one are you using?

            1. 3

              Keycloak. Sorry for the dry reply back there.

              Lead the IdP/IAM implementation (customer facing both B2B and B2C type of UX) in my last gig and used Keycloak as its core. Has a fairly impressive out-of-the-box completeness and extensibility is achievable albeit awkward IMO.

              In my current gig I found a Keycloak already in place. Honestly I would rather try something a bit less bulky and have been looking to Ory but haven’t done anything noteworthy yet.

              My main issues with Keycloak have been mostly around extending it. Has that old-school enterprisy Java coding experience going, as it runs on JBoss and does a poor job in hiding that. Clustering on K8S was more hassle than it should too. I think they’re “rewriting” it under Keycloak X, which is both a good and a bad thing. Good because it is targeting a more lightweight “cloud-native” runtime but breakage is sure to happen. Gave me zero issues in production for 3 years with low traffic (dozens TPS tops) but very high criticality (all user and all “microservices” used it for auth)

              I understand it depends on context but rolling out a “user/pass” form like it’s the 00’s really rubs me the wrong way. OIDC comes with a lot of value and I find it frustrating when I use something that doesn’t support auth federation: thinking on self hostable open source stuff but also commercial products

              It’s a lot of work to implement something like Keycloak from the ground up… even if you’re using some framework for it, registration/login/recovery/sso/browser support/email/mfa/“social login”/… in a profissional, product development setting, I would default against that.

        1. 3

          I was really uncomfortable while reading this. This lack of accountability some developers tend to have regarding the work they do… no one else here sees this as a problem too? (honestly curious, I might be over reacting) If I am to consider the author both a professional and a law abiding adult citizen, this just read as a straight-up criminal confession. :/

          Is this seemingly ok because it’s just computers? Is this the whole “software engineering is not real engineering” topic?

          1. 2

            It’s a big mistake to equate actions that harm corporations with actions that harm humans.

          1. 1

            Have you considered support for remote+dynamic config? I’ve a co-developed such a thing for Java (https://github.com/irenical/jindy) but we never found a Node equivalent. In the Java ecosystem a lot of the pieces were already there, so this is basically an API and glue. If one would want to centralise configuration using Consul, etcd or what have you, what would you suggest? What about if you need to react to runtime config changes? Do you see these features as something that would make sense in HConfig? I’m really trying to avoid having to write a “jindy.js” from scratch.

            1. 1

              Hmm, I don’t know if that would make sense in HConfig. It’s more supposed to just be a parser for a language. However, it would totally be possible to build something on top of that which uses HConfig as a configuration language. Reacting to runtime config changes would probably also be up to the application or another language to implement; just parse the file again whenever you want to reload it, and do whatever application logic is necessary to incorporate the updated configuration.

              1. 1

                We use HOCON, which, used with the typesafe config jars, has wonderful support for overriding values. The idea is that each jar can have it’s own reference.conf, and then you can add a new config file with a fallback to the default. So you can read config from consul or etcd and then use it to override the default values, We use typesafe config a lot and it makes our lives a lot easier. We use a single object which contains all of the config values which we care about. This is immutable and typed. If we need to re-read (because of changes in consul), then we re-read and we have a new immutable object.

              1. 7

                Poor framework choices cause a bad development experience in any language. This is particularly prone to happen in Java because most of the “de facto standard” frameworks are rubbish. To make elegant Java projects, you have to ignore 90% of the internet. Hopefully not this comment.

                1. 10

                  In my experience, to write elegant Java:

                  • Learn SML, Haskell, Lisp, or at least Python. By no means should you learn idiomatic Java. If you already know it, unlearn as much as you can.
                  • Use Java 8+.
                  • Never use any dependency with more than a handful of public classes.
                  • Never use anything which uses reflection, annotations or inversion of control.

                  At this point, you’ve basically got a very verbose Python that’s screaming fast and has basic static typechecking. I honestly prefer it.

                  Also, for what it’s worth, I think (though I’m sure as hell not going to trawl through Spring’s garbage fire of “documentation” to confirm) that the author didn’t have to write as much boilerplate as they actually did; there are magic annotations to autogenerate at least some of that, like the mapper and probably the DAO as well. Note that this has absolutely no impact on their point (because none of this is discoverable without dealing with the pain yourself, cf. aforementioned garbage fire).

                  1. 2

                    Learn SML, Haskell, Lisp, or at least Python. By no means should you learn idiomatic Java. If you already know it, unlearn as much as you can.

                    This gave me pause. So you’re advocating for people writing code that will be all but unmaintainable by the rest of the team in the name of elegance?

                    I agree that learning other programming languages can make you a stronger programmer in your language of choice, but this strikes me as really unfortunate hyperbole.

                    1. 9

                      Given the specific list “SML, Haskell, Lisp, or at least Python”, I think what whbboyd’s actually going for here is “get comfortable writing simple programs that mostly pass values around, preferring simple uses of generics (i.e. parametric polymorphism¹) or interfaces (i.e. duck typing²) over doing unpleasant stuff with deep inheritance hierarchies, and not being scared of lambdas”, because that’s roughly the intersection (not union) of those PLs’ feature sets.

                      (¹ fancy word for “when you put a thing into a list-of-Ducks, the thing you put in is a Duck, not an arbitrary Object” and “when you take a thing out of a list-of-Ducks, you get a Duck back, not a mysterious Object reference that has to be cast to Duck and which might throw an exception when you do that.)

                      (² non-fancy word for typeclasses ^_~)

                      This is an argument for writing less-complicated Java. I’d expect the resulting programs to be more comprehensible, not less, and they might actually look simplistic.

                      This is not an argument for rewriting all your Java programs with the control flow implemented as Church-encoded data structures. That would be wildly incomprehensible.

                      1. 4

                        Precisely this. Java’s typical idioms are not conducive to writing elegant code, so learning better idioms instead will put you in a better place, and shouldn’t significantly affect the ability of competent teammates to understand and maintain your code.

                      2. 4

                        I agree that there is some hyperbole here, but I also do think the above commenter has a point. Java can be nice if you subtract the cultural gunk that has built up around “patterns”. The jOOQ blog covered it well, I think.

                  1. 4

                    Seeing as I’m up this late only because I’m dealing with mitigating Kafka queue lag due to our big data team performing excessive complex queries on our OpenTSDB, this post couldn’t come across my screen at a better time, thanks! I’ll be interested in stress testing this soon. Has anyone here used this in a high-scale high-availability production environment yet?

                    1. 2

                      Probably not as this seems to be in development still. You can read at the end of the document: “A clustered version is in private beta with select customers.” Doesn’t sound like production-ready. I would also like to have read something about cluster resizing and resilience to node failure, which are usually giant pain points in sharded data systems. Either way this seems interesting and I’ll be looking for excuses to try it out.

                      1. 2

                        Yep, Hadoop node failure and replication lag is what caused our problem last night.