There is a common recommendation that one should not start projects with a microservices approach. And this is often true. However, if you look closely, it often makes sense to immediately separate several layers:
- Main application code
- Databases (such as Postgres or MongoDB)
- File storage (S3 API)
- Cache (Redis)
- API Gateway (Caddy or NGINX)
- Authentication providers (more details below)
- Part of the application that works with users, organizations, tariff plans, accesses (let’s call it a client microservice)
Why is it beneficial to separate the client microservice right from the start?
- Most likely, you have several projects. And such a microservice will have the same (or very similar) code. In other words – efficient reuse.
- Since this is the foundation of security, it’s better to update it less frequently and more sensibly.
What are Auth-providers and why do they need them?
In our client microservice, we don’t fully implement auth protocols; rather, we use ready-made third-party microservices for this. After all, we don’t implement a database in our application, so why should we handle auth ourselves?
At the same time, headers come to our main application that we can trust. If additional information about the user is needed, then we ask the client microservice via http (luckily we know how to generate http clients).
Interaction scheme:
- APIGW (Caddy/NGINX) accepts the request, works with https and statics
- Auth proxy – authorizes and adds headers
- Identity provider – actually authorizes (and stores passwords). It can be Google. Or it could be internal. For Google, we are an external application in their settings.
- User service – some internal microservice that provides additional information about a user based on the user id (profile).
Options
For administrators:
- https://oauth2-proxy.github.io/oauth2-proxy/ – add authentication through OAuth2 providers (Yandex, VK and others) to your application. As a result, if everything is set up correctly, the application will receive headers with data about the authorized user in each request (for example X-Auth-Request-User, X-Auth-Request-Groups, X-Auth-Request-Email, X-Auth-Request-Preferred-Username). The main use case is to protect internal applications. It’s not suitable for SAAS as it doesn’t allow choosing different OAuth2 providers.
- https://github.com/lyang/saml-proxy – Same as previous one, but SAML (for
PingId
,Okta
,OneLogin
, etc.) - https://www.authelia.com/ – connect LDAP and a second factor
- https://www.keycloak.org/ – quite powerful, but also heavy
For developers of their own solutions:
Proxy:
- https://github.com/ory/hydra – Compared to other OAuth2 and OpenID Connect Providers, it does not implement its own user database and management (for user login, user registration, password reset, 2fa, …), but uses the Login and Consent Flow to delegate rendering the Login UI (“Please enter your email and password”) and Consent UI (“Should application MyDropboxDownload be allowed to access all your private Dropbox Documents?”) to an external application.
Identity provider:
- https://docs.goauthentik.io/docs/ – a custom OAuth2 provider
- https://github.com/ory/kratos – more suitable for SaaS applications
Miscellaneous (disliked for various reasons, but these are just my current opinions):
- https://github.com/authorizerdev/authorizer
- https://github.com/Permify
- https://github.com/logto-io/logto – alternative to Auth0, but still commercial
- https://goauthentik.io/
- https://zitadel.com/
Cloud options:
- Auth0 – this is good, but expensive
- Firebase – quite popular for mobile applications
In the end, I liked https://casdoor.org/ & https://casbin.org/ :
- open source
- from a large company that it’s not their product
- all the functionality you can imagine
- drawbacks: communication using JWT tokens within the application itself, instead of checking and issuing headers on API GW, can be resolved using https://github.com/CSU-OSA/Akashic-auth (the project has a ticket opened – https://github.com/casdoor/casdoor/issues/2972 )