Chapter 16 of 27 ยท Part 8: Cross-cutting concerns

Security, configuration and the chassis

Production-ready basics every service needs: security, externalized configuration and a microservice chassis.

key idea / coordinatorservice / good pathin progress / watch outproblem / failureneutral

Beyond working code

Before production a service must also be secure, configurable and observable.

Three quality attributesProduction-ready servicemore than working codeSecurewho can do whatConfigurablesettings at runtimeObservablesee what it does

Security

In a monolith one session holds the user. With services the gateway authenticates and passes a token.

Security in a monolithClientLogin handlerInterceptorRequest handlerPOST /loginJSESSIONID cookieGET + cookieload session โ†’ contextcheck roles, handleThe session and the in-memory security context do not carry over to separate services.
Who checks whatAuthenticationAPI gatewayone place to get it rightAuthorizationGatewayrole-based URL accessEach serviceroles + per-record rules
Access token patternOpaque tokenRandom id like a UUIDService must call to check itAdds latency, lowers availabilityTransparent token (JWT)Signed: identity, roles, expiryService checks it locallyCannot be revoked: keep it short-lived
Login with OAuth 2.0ClientAPI gatewayAuth serverOrder svcPOST /login + credspassword grantaccess + refresh tokentokens as cookiesGET /orders + cookieBearer access tokenExpired? Gateway uses the refresh token to get a new one.
OAuth 2.0 vocabularyOAuth 2.0 termIn FTGOAuthorization serverissues tokens (Spring OAuth)Access tokenshort-lived JWTRefresh tokenlong-lived, revocableResource servereach serviceClientthe API gateway

Defense in depth and the five functions

Tokens and TLS are only part of security. Two older principles come first. Least privilege: give a party the minimum access it needs, for the shortest time, so a stolen read-only credential is worth little. Defense in depth: never rely on one barrier, like a castle with a hill and two walls. From Building Microservices, ch. 11.

Layers of protectionNetwork: segments and firewallsHost or container: patched, least privilegeService: authenticate, authorize, validate inputDataencrypted in transit and at rest
Five functions of cybersecurityIdentifywho attacks?Protectguard assetsDetectspot attacksRespondlimit damageRecoverrebuild/learnNIST model. Teams often stop at Protect and forget the other four.

Start with threat modeling: think like an attacker and look at the whole system. Securing one or two services leaves a strong front door and an open window. Weave security into delivery, for example by scanning dependencies on every CI build.

Credentials, patching and data protection

Services multiply credentials: more machines, databases and service accounts. Treat them as a design topic. From Building Microservices, ch. 11.

Sharing one credential versus one per instanceOne shared passwordEvery instance uses itRotating means redeployingHard to trace a leakCredential per instanceEach instance has its ownRevoke just oneA secret store (Vault) issues themFine-grained credentials only work with automation.
FoundationWhat to do
PatchingThe 2017 Equifax breach used an unpatched library. Scan dependencies (Snyk, GitHub code scanning) and fail the build on known holes.
BackupsRestore them regularly: an untested backup is a "Schrödinger backup". Keep them isolated, such as a separate cloud account, and encrypted.
RebuildAutomate so you can rebuild a compromised system on demand.
Four concerns for data in transitServer identityTLS certwho is server?Client identitymTLS or keywho is calling?VisibilityHTTPSno eavesdroppingManipulationHTTPS or HMACno tamperingHMAC signs a request so the receiver can detect changes, even if the data is not hidden.

Data at rest: use well-known, reviewed encryption and never invent your own. Hash passwords with salt. Encrypt data when you first see it, decrypt only on demand, and encrypt backups. Be frugal: data you do not store cannot be stolen. Keep sensitive values out of logs.

From Bootstrapping Microservices: keep secrets out of code and scripts. The CD workflow reads them from GitHub secrets (even the Base64 kubeconfig). Avoid Terraform outputs for sensitive values, because they end up in plain text in the state file.

Trust between services

Implicit trust versus zero trustImplicit trustInside the network is safeServices accept internal callsOne breach exposes allZero trustAssume attackers are insideCheck every inbound callEncrypt all trafficIt is a spectrum, and zero trust is a mindset, not a product.
Mutual TLS between two servicesOrder svcPayment svchello + client certificateserver certificateencrypted requestencrypted replyBoth sides prove who they are: service-to-service authentication. API keys also work.
The confused deputy problemAttackerWeb shopOrder svcshow orders of user Borders of B (shop is trusted)B's ordersB's ordersOrder svc trusted the shop, not the user. Fix: pass a signed token (JWT) with the user.
Where to authorizeIdeaCatch
Upstream (gateway)Check once, trust everything downstreamImplicit trust; the gateway must know every service
In each serviceService decides using claims in the JWTServices need the user identity and roles

Keep roles coarse-grained and shaped like your organization. Roles such as CALL_CENTER_50_DOLLAR_REFUND push one service's rules into the directory and tie its life cycle to another team.

Configuration

Build once, deploy to many environments. Supply settings at runtime.

Externalized configurationPush modelEnv vars, config fileset at deploy timeHard to change laterspread across servicesPull modelConfig serverservice asks at startupCentral, dynamicdecrypts secretsConfig servers: Git, Spring Cloud Config, HashiCorp Vault, AWS Parameter Store.
Pull-based configurationDeploy infrasets CONFIG_URLService startsreads env varConfig serverreturns settingsService runsKafka, DynamoDB setSame build, many environments: only the settings change.

Microservice chassis

Do not rebuild these cross-cutting concerns in every service.

Chassis versus service meshMicroservice chassisExternalized configHealth checksMetricsTracing headersService meshService discoveryCircuit breakers, load balancingTraffic routingTLS between servicesThe chassis (Spring Boot + Spring Cloud) is a library. A mesh (Istio, Linkerd) works outside the code.

Recap

Quick check

Why pass a JWT instead of an opaque token, and what is the catch?
Show answer

A JWT carries signed identity and roles, so services check it without calling a security service. It cannot be revoked, so it is short-lived and renewed with a refresh token.