Authentication & Authorization - When API Gateway Carries the Team
Does each service check the token itself or do it in one place for all? How we set up security without overloading the code base.
Security in Microservices is like security checks at an airport. Do you want to check once at the entrance, or should guards ask for your passport at every duty-free shop?
The Problem: Who is the User?
In a Monolith application, you have user sessions in memory or a database. Every function easily knows the currentUser.
In a Microservice, a User's request might pass through 5 different services. How does service number 5 know this is User A and that User A has permission to perform this action?
1. The Naive Approach: Every Service Auths Itself
We started by implementing JWT authentication logic in every service. Consequences:
- Code duplication everywhere.
- Every time the encryption algorithm changes or a new permission type is added, I have to update 10 services.
- More importantly: Each service has to call the
AuthServiceor Database to check the user—creating a huge and useless amount of internal traffic.
2. API Gateway: The Powerful Gatekeeper
We switched to using an API Gateway (like Kong, Traefik, or a simple Next.js service) as the single point of entry for external requests.
Workflow:
- User sends a request with a JWT to the Gateway.
- The Gateway validates the JWT and checks if the token is still valid.
- The Gateway extracts user information from the token (User ID, Roles).
- The Gateway pushes this information into Internal Headers (e.g.,
X-User-ID,X-User-Roles) and forwards the request to the internal services.
Huge Benefit: Internal services are now extremely "naive." They don't need to know what a JWT is; they just say: "Ah, I have the X-User-ID header, I'll just do my job."
3. But What About Internal Security?
What if someone manages to break into the internal network and sends a request directly to a service (bypassing the Gateway) with a forged header?
Trade-offs for small teams: If you have the resources, use mTLS (Mutual TLS) between services. But for a 2-person team, managing certificates for mTLS is an enormous burden. Our practical solution: Only allow traffic into the services from the API Gateway's IP (Network isolation). Simple, effective, and secure enough for the early stages.
Lessons Learned
- JWT is Your Best Friend: Pack as much necessary (but non-sensitive) information into the JWT as possible to minimize database queries.
- Stateless is Key: Don't use Sessions. Microservices are built to scale, and Sessions will make scaling a nightmare.
- BFF (Backend for Frontend) can also do Auth: If you use Next.js, leverage it to handle Auth before calling down to the business microservices.
Security is not a thick wall, but a reasonable process. For small teams, prioritize centralization for easier management and maintenance.
Conclusion
Don't try to overcomplicate security issues with enterprise solutions from the start. A good Gatekeeper Gateway coordinated with Network Isolation is enough to protect against 99% of common risks for a startup project.
Series • Part 6 of 20