Oathkeeper is a useful open source tool that can be integrated with Auth0 to create an elegant solution for decoupling user authentication and application logic. This approach allows you to quickly build additional services sharing the user authentication setup. Consider this method when building your next application!
Company Mentioned
Coin Mentioned
Building a user management solution using ORY Oathkeeper and Auth0
What are we doing?
I’m part of a team-building platform that requires login and user management functions.
We’re using a combination of Auth0, widely used for user management, and ORY Oathkeeper, an open-source solution.
The combination of Oathkeeper and Auth0 is not a common use case, but it’s an elegant configuration-driven setup. It enables us to decouple our business logic from our user sign-in logic. That’s beneficial for microservice architecture scenarios — as our application scales, we can reuse our user authentication logic across all our services.
Moving away from monolith login features
We started out with a single service that handles the register, login, authentication, authorization, routing, and business logic. As the application and needs grow, we want to add more features and move our services to a more micro-service-friendly setup. We also want to decouple the business logic from the user authentication.
From the application developer's point of view, it’s also a clean and easy-to-use solution, as it puts all the auth responsibility on Oathkeeper. The application doesn’t need to verify any credentials, it just receives a header added by the proxy. If it exists, the user is logged in. If it doesn’t, they are not.
Using existing solutions
Using existing tools can give us feature-rich solutions that have been vetted in production and refined over time. Often we don’t realize how many components are in a seemingly simple feature such as login and logout until we start scoping out requirements or even building it. For example, for user-management and surrounding features, you need CSRF protection, password hashing, email verification, securely storing user credentials, social sign-in, token signing, security compliance, and the list goes on.
Requirements for auth solution
Stateless API and session store
A solution to keep our backend services all stateless, and keep the user session state outside of the application logic.
Login
Users logging into the application would get a signed JWT token and return to the frontend, saved in a cookie (or localStorage) and passed upstream.
Ongoing requests
Once a user is logged in, the frontend application passes down the token via header/cookie on every subsequent request, then upstream services would verify and authenticate the request using the JWT token passed along with the requests.
User management
Our tool of choice was . It’s not open-source software, but there are a plethora of features and great tooling for it. Auth0 is “user-management as a service” software. It has wild adoption and great community support and resources, providing us with many features, such as:
Login and sign-up interface and functionality
Login via OIDC-compatible social login via OAuth2
Login via username and password
Email verification and password resets
OpenID compliant support with token signing
Upon sign in we get a JWT token from Auth0 with customizable expiry and metadata
Built in security compliance
And much more (web GUI to handle users, webhooks, analytics, user roles, multi-factor authentication, etc.)
Oathkeeper
Oathkeeper is a proxy that supports many authentication and authorization features. It has many features to support sessions and allow us to authenticate, mutate, and route requests before reaching the business logic:
Configuration driven proxy
Authenticators (JWT support, fetching cookies from another service, oauth2 introspection)
Authorizers (route-based, or remote service-based access-control rules)
Mutators (setting headers or cookies based on session info, or updating the session with a remote service)
Error handling
Routing (proxying requests to microservices)
Native Kubernetes support through their controller and custom resources
High-level setup overview
A brief explanation of the setup from the ground up:
Cloud Infrastructure on Kubernetes
Ingress
Routing proxy (Oathkeeper allows requests to be routed to the authentication endpoints while safeguarding the rest of the endpoints, keeping the request on the same domain to make cookie management and CORS easier)
Auth0 (user-identity service and storage)
Session handling(Oathkeeper uses to manage and verify the sessions)
Auth endpoints to handle token exchange
Backend application
Frontend application
Topology of the setup is as follows:
Login Flow and Request flow
Setting up Auth0
In our case, we have configured Auth0 following the . While submitting the authorization request, we must include the scope openId. Then Auth0 will return an ID token when obtaining userInfo, which in this example is the user’s token. This way we don’t need to maintain, rotate or deploy a set of private or public keys, implement code to sign or verify JWT tokens, or figure out how to secure user credentials or sessions in your database.
Proxy (Oathkeeper) setup
In the proxy we need to set up three parts:
Routing
Here we want to split up the authenticated routes, and routes to Login via `Rules` in Oathkeeper. The Oathkeeper controller (oathkeeper-maester) will pick up `Rules` applied to kubernetes then apply it to Oathkeeper’s config automatically.
Session creation (JWT authenticator)
Conveniently, Oathkeeper has a suite of plugins to handle common authentication methods. We’re using the id_token from Auth0 as the token and verifying it using the , configuring the JWT plugin as follows:
Request mutation
Oathkeeper also provides other middleware, such as mutation plugins, which can access the session data and then inject metadata into the request downstream. In this case, we want to remove authentication from the application logic while keeping the authorization and user lookup in the application, so we can pass the user-id and email to the application. This means that by the time the request gets to the application, it can check for the existence of the X-User-Id header. If it exists, the specified user is logged in. If a user isn’t logged in, the request won’t even reach the application.
Deployment
We’re deploying Oathkeeper onto our infrastructure using via , but you can also deploy it via normal kubernetes manifest files.
Where `files/oathkeeper-valuesyml` will follow .
Auth service
You will need to implement a few endpoints to handle the interactions with Auth0. Note that you can also implement these in your backend application and route them to the same place, but for clarity the logic is represented as its own service:
Login []
Exchange token []
Logout []
Upon success, all three of these methods will redirect the user back to your frontend application.
Backend service
To let the frontend determine whether a user is logged in or not, we can implement an endpoint like /whoami that checks the headers injected by Oathkeeper and returns the user info. Then you can create stateless API calls that check the user’s logged-in status on the frontend and leverage Auth0 as your logged-in state controller.
Here’s an example in node.js. You could have a middleware to look up the user, such as:
Frontend
Login: To log in, you can simply redirect the user to the `<ingress>/auth0/login` and it will redirect you to the Auth0 login page, then bring you back to your application with the cookie set.
Check user status: With the endpoint in the backend implemented, in the frontend, you can easily have a function as follows to determine if a user is signed in.
Conclusion
Oathkeeper is a useful open-source tool that can be integrated with Auth0 to create an elegant solution for decoupling user authentication and application logic. This approach allows you to quickly build additional services sharing the user authentication setup. Consider this method when building your next application!
is an Engineering Partner at Commit. He has been in software development for over a decade honing his expertise in full-stack development, and is passionate about open source projects.