Security Architecture for Microservices

More Doors to Lock

A monolith has one entry point. ShopEase microservices have a gateway, 5+ services, Kafka, several databases and admin endpoints, all talking over a network. Each one is a door an attacker can try.

The modern approach is zero trust: do not trust a request just because it comes from "inside the cluster". Every service checks who is calling and what they may do.

Tip: This module shows how the pieces fit together across services. JWT basics, OAuth2/OIDC flows, resource servers and Spring Authorization Server are taught in depth in the Spring Security material.

The Big Picture

React / Android app
        |  1. login (OIDC Authorization Code + PKCE)
        v
   Keycloak / Auth0 / Okta  (Authorization Server) --- issues signed JWT access tokens
        |
        |  2. Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
        v
   API Gateway  -- validates JWT (signature, issuer, expiry), coarse rules, rate limits
        |  3. relays the SAME token
        v
   order-service  -- validates JWT again, checks role/scope (@PreAuthorize)
        |  4a. user calls: forward the user token
        |  4b. background jobs / Kafka: its OWN token (client credentials) or mTLS
        v
   payment-service -- trusts only tokens with aud=payment-service and scope payments:write

Threats and Defences

ThreatDefence
Stolen or forged tokenShort-lived JWTs (5–15 min) signed with RS256; every service verifies the signature via the JWKS endpoint
Attacker inside the network calls payment-service directlyServices validate tokens themselves; Kubernetes NetworkPolicy; mTLS
Token meant for one service used at anotherCheck the aud (audience) claim
Too many requests / credential stuffingRate limiting at the gateway (Redis rate limiter)
Leaked DB passwords in GitSecrets in Kubernetes Secrets / Vault / cloud secret manager, never in the repo
Sniffing trafficTLS at the edge (Ingress) and mTLS between services
Exposed actuator endpointsExpose only health/prometheus; separate management port; never public