Securing service-to-service calls

Microservices · lesson 19 of 33 · 4 min read

Authenticate every hop instead of trusting the network your services happen to share.

Open this lesson in the learning hub

Key points

  • A private network is not authentication. Anything that gets inside the cluster can call every service you run.
  • Users are authenticated at the gateway. For its own calls a service asks the auth server for a client credentials token.
  • Do not blindly forward the user token inwards. It is minted for the gateway audience and it carries user rights into every hop.
  • Verify on the receiving side: signature, issuer, aud and expiry. A Spring Security resource server checks all four for you.
  • mTLS proves which service is calling; the token says what that call may do. You want both, and a mesh can supply the first.

Example

# --- caller (orders): fetch a token minted for the inventory audience ---
spring:
  security:
    oauth2:
      client:
        registration:
          inventory:
            client-id: orders-svc
            client-secret: injected-from-a-secret   # never committed
            authorization-grant-type: client_credentials
            scope: stock.read
        provider:
          inventory:
            token-uri: https://auth.internal/oauth2/token

---
# --- callee (inventory): reject anything that is not for it ---
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.internal
          audiences: inventory        # a gateway token is refused here

# The caller side then needs no header code at all: register the
# OAuth2ClientHttpRequestInterceptor on the RestClient.Builder and the
# Authorization header is attached and refreshed for you.

Trust the token and the certificate; never trust the network.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Microservices course, and every lesson in it is listed on the Microservices contents page.