Preface |
|
xvii | |
Acknowledgments |
|
xix | |
About this book |
|
xxi | |
About the authors |
|
xxv | |
About the cover illustration |
|
xxvi | |
|
|
1 | (54) |
|
1 Microservices security landscape |
|
|
3 | (29) |
|
1.1 How security works in a monolithic application |
|
|
5 | (2) |
|
1.2 Challenges of securing microservices |
|
|
7 | (5) |
|
The broader the attack surface, the higher the risk of attack |
|
|
7 | (1) |
|
Distributed security screening may result in poor performance |
|
|
8 | (1) |
|
Deployment complexities make bootstrapping trust among microservices a nightmare |
|
|
8 | (1) |
|
Requests spanning multiple microservices are harder to trace |
|
|
9 | (1) |
|
Immutability of containers challenges how you maintain service credentials and access-control policies |
|
|
10 | (1) |
|
The distributed nature of microservices makes sharing user context harder |
|
|
11 | (1) |
|
Polyglot architecture demands more security expertise on each development team |
|
|
11 | (1) |
|
1.3 Key security fundamentals |
|
|
12 | (6) |
|
Authentication protects your system against spoofing |
|
|
12 | (1) |
|
Integrity protects your system from data tampering |
|
|
13 | (1) |
|
Nonrepudiation: Do it once, and you own it forever |
|
|
14 | (1) |
|
Confidentiality protects your systems from unintended information disclosure |
|
|
14 | (2) |
|
Availability: Keep the system running, no matter what |
|
|
16 | (2) |
|
Authorization: Nothing more than you're supposed to do |
|
|
18 | (1) |
|
|
18 | (4) |
|
The role of an API gateway in a microservices deployment |
|
|
19 | (1) |
|
Authentication at the edge |
|
|
20 | (2) |
|
Authorization at the edge |
|
|
22 | (1) |
|
Passing client/end-user context to upstream microservices |
|
|
22 | (1) |
|
1.5 Securing service-to-service communication |
|
|
22 | (10) |
|
Service-to-service authentication |
|
|
23 | (3) |
|
Service-level authorization |
|
|
26 | (1) |
|
Propagating user context among microservices |
|
|
27 | (1) |
|
Crossing trust boundaries |
|
|
28 | (4) |
|
2 First steps in securing microservices |
|
|
32 | (23) |
|
2.1 Building your first microservice |
|
|
33 | (6) |
|
Downloading and installing the required software |
|
|
34 | (1) |
|
|
34 | (1) |
|
Compiling the Order Processing microservice |
|
|
35 | (1) |
|
Accessing the Order Processing microservice |
|
|
36 | (1) |
|
What is inside the source code directory? |
|
|
37 | (1) |
|
Understanding the source code of the microservice |
|
|
38 | (1) |
|
2.2 Setting up an OAuth 2.0 server |
|
|
39 | (6) |
|
The interactions with an authorization server |
|
|
39 | (3) |
|
Running the OAuth 2.0 authorization server |
|
|
42 | (1) |
|
Getting an access token from the OAuth 2.0 authorization server |
|
|
43 | (1) |
|
Understanding the access token response |
|
|
44 | (1) |
|
2.3 Securing a microservice with OAuth 2.0 |
|
|
45 | (3) |
|
Security based on OAuth 2.0 |
|
|
45 | (1) |
|
|
46 | (2) |
|
2.4 Invoking a secured microservice from a client application |
|
|
48 | (2) |
|
2.5 Performing service-level authorization with OAuth 2.0 scopes |
|
|
50 | (5) |
|
Obtaining a scoped access token from the authorization server |
|
|
50 | (2) |
|
Protecting access to a microservice with OAuth 2.0 scopes |
|
|
52 | (3) |
|
|
55 | (80) |
|
3 Securing north/south traffic with an API gateway |
|
|
57 | (26) |
|
3.1 The need for an API gateway in a microservices deployment |
|
|
58 | (6) |
|
Decoupling security from the microservice |
|
|
59 | (3) |
|
The inherent complexities of microservice deployments make them harder to consume |
|
|
62 | (1) |
|
The rawness of microservices does not make them ideal for external exposure |
|
|
63 | (1) |
|
|
64 | (4) |
|
Understanding the consumer landscape of your microservices |
|
|
64 | (1) |
|
|
65 | (1) |
|
Why not basic authentication to secure APIs? |
|
|
66 | (1) |
|
Why not mutual TLS to secure APIs? |
|
|
66 | (1) |
|
|
67 | (1) |
|
3.3 Setting up an API gateway with Zuul |
|
|
68 | (11) |
|
Compiling and running the Order Processing microservice |
|
|
68 | (1) |
|
Compiling and running the Zuul proxy |
|
|
69 | (2) |
|
Enforcing OAuth 2.0-based security at the Zuul gateway |
|
|
71 | (8) |
|
3.4 Securing communication between Zuul and the microservice |
|
|
79 | (4) |
|
Preventing access through the firewall |
|
|
79 | (1) |
|
Securing the communication between the API gateway and microservices by using mutual TLS |
|
|
80 | (3) |
|
4 Accessing a secured microservice via a single-page application |
|
|
83 | (26) |
|
4.1 Running a single-page application with Angular |
|
|
84 | (5) |
|
Building and running an Angular application from the source code |
|
|
84 | (1) |
|
Looking behind the scenes of a single-page application |
|
|
85 | (4) |
|
4.2 Setting up cross-origin resource sharing |
|
|
89 | (6) |
|
Using the same-origin policy |
|
|
89 | (2) |
|
Using cross-origin resource sharing |
|
|
91 | (1) |
|
Inspecting the source that allows cross-origin requests |
|
|
92 | (1) |
|
Proxying the resource server with an API gateway |
|
|
93 | (2) |
|
4.3 Securing a SPA with OpenID Connect |
|
|
95 | (9) |
|
Understanding the OpenID Connect login flow |
|
|
96 | (4) |
|
Inspecting the code of the applications |
|
|
100 | (4) |
|
4.4 Using federated authentication |
|
|
104 | (5) |
|
|
105 | (1) |
|
Building trust between domains |
|
|
106 | (3) |
|
5 Engaging throttling, monitoring, and access control |
|
|
109 | (26) |
|
5.1 Throttling at the API gateway with Zuul |
|
|
110 | (12) |
|
Quota-based throttling for applications |
|
|
111 | (2) |
|
Fair usage policy for users |
|
|
113 | (1) |
|
Applying quota-based throttling to the Order Processing microservice |
|
|
114 | (4) |
|
Maximum handling capacity of a microservice |
|
|
118 | (2) |
|
Operation-level throttling |
|
|
120 | (1) |
|
Throttling the OAuth 2.0 token and authorize endpoints |
|
|
121 | (1) |
|
Privilege-based throttling |
|
|
121 | (1) |
|
5.2 Monitoring and analytics with Prometheus and Grafana |
|
|
122 | (7) |
|
Monitoring the Order Processing microservice |
|
|
123 | (4) |
|
Behind the scenes of using Prometheus for monitoring |
|
|
127 | (2) |
|
5.3 Enforcing access-control policies at the API gateway with Open Policy Agent |
|
|
129 | (6) |
|
Running OP A as a Docker container |
|
|
130 | (1) |
|
Feeding the OPA engine with data |
|
|
130 | (1) |
|
Feeding the OPA engine with access-control policies |
|
|
131 | (1) |
|
|
132 | (1) |
|
|
133 | (2) |
|
PART 3 SERVICE-TO-SERVICE COMMUNICATIONS |
|
|
135 | (92) |
|
6 Securing east/west traffic with certificates |
|
|
137 | (24) |
|
|
138 | (2) |
|
Building trust between a client and a server with a certificate authority |
|
|
138 | (1) |
|
Mutual TLS helps the client and the server to identify each other |
|
|
138 | (2) |
|
|
140 | (1) |
|
6.2 Creating certificates to secure access to microservices |
|
|
140 | (2) |
|
Creating a certificate authority |
|
|
140 | (1) |
|
Generating keys for the Order Processing microservice |
|
|
141 | (1) |
|
Generating keys for the Inventory microservice |
|
|
141 | (1) |
|
Using a single script to generate all the keys |
|
|
141 | (1) |
|
6.3 Securing microservices with TLS |
|
|
142 | (7) |
|
Running the Order Processing microservice over TLS |
|
|
143 | (2) |
|
Running the Inventory microservice over TLS |
|
|
145 | (1) |
|
Securing communications between two microservices with TLS |
|
|
146 | (3) |
|
|
149 | (2) |
|
6.5 Challenges in key management |
|
|
151 | (8) |
|
Key provisioning and bootstrapping trust |
|
|
151 | (2) |
|
|
153 | (6) |
|
|
159 | (1) |
|
|
159 | (2) |
|
7 Securing east/west traffic with JWT |
|
|
161 | (18) |
|
7.1 Use cases for securing microservices with JWT |
|
|
162 | (6) |
|
Sharing user context between microservices with a shared JWT |
|
|
162 | (1) |
|
Sharing user context with a new JWT for each service-to-service interaction |
|
|
163 | (2) |
|
Sharing user context between microservices in different trust domains |
|
|
165 | (1) |
|
|
166 | (1) |
|
|
167 | (1) |
|
7.2 Setting up an STS to issue a JWT |
|
|
168 | (2) |
|
7.3 Securing microservices with JWT |
|
|
170 | (2) |
|
7.4 Using JWT as a data source for access control |
|
|
172 | (1) |
|
7.5 Securing service-to-service communications with JWT |
|
|
173 | (2) |
|
7.6 Exchanging a JWT for a new one with a new audience |
|
|
175 | (4) |
|
8 Securing east/west traffic over gRPC |
|
|
179 | (17) |
|
8.1 Service-to-service communications over gRPC |
|
|
180 | (5) |
|
8.2 Securing gRPC service-to-service communications with mTLS |
|
|
185 | (5) |
|
8.3 Securing gRPC service-to-service communications with JWT |
|
|
190 | (6) |
|
9 Securing reactive microservices |
|
|
196 | (31) |
|
9.1 Why reactive microservices? |
|
|
197 | (5) |
|
9.2 Setting up Kafka as a message broker |
|
|
202 | (3) |
|
9.3 Developing a microservice to push events to a Kafka topic |
|
|
205 | (2) |
|
9.4 Developing a microservice to read events from a Kafka topic |
|
|
207 | (3) |
|
9.5 Using TLS to protect data in transit |
|
|
210 | (4) |
|
Creating and signing the TLS keys and certificates for Kafka |
|
|
210 | (2) |
|
Configuring TLS on the Kafka server |
|
|
212 | (1) |
|
Configuring TLS on the microservices |
|
|
212 | (2) |
|
9.6 Using mTLS for authentication |
|
|
214 | (3) |
|
9.7 Controlling access to Kafka topics with ACLs |
|
|
217 | (5) |
|
Enabling ACLs on Kafka and identifying the clients |
|
|
219 | (1) |
|
|
220 | (2) |
|
9.8 Setting up NATS as a message broker |
|
|
222 | (5) |
|
|
227 | (112) |
|
10 Conquering container security with Docker |
|
|
229 | (33) |
|
10.1 Running the security token service on Docker |
|
|
230 | (1) |
|
10.2 Managing secrets in a Docker container |
|
|
231 | (6) |
|
Externalizing secrets from Docker images |
|
|
233 | (2) |
|
Passing secrets as environment variables |
|
|
235 | (2) |
|
Managing secrets in a Docker production deployment |
|
|
237 | (1) |
|
10.3 Using Docker Content Trust to sign and verify Docker images |
|
|
237 | (7) |
|
|
237 | (1) |
|
|
238 | (1) |
|
|
238 | (2) |
|
|
240 | (1) |
|
Signature verification with DCT |
|
|
241 | (1) |
|
Types of keys used in DCT |
|
|
241 | (2) |
|
How DCT protects the client application from replay attacks |
|
|
243 | (1) |
|
10.4 Running the Order Processing microservice on Docker |
|
|
244 | (3) |
|
10.5 Running containers with limited privileges |
|
|
247 | (4) |
|
Running a container with a nonroot user |
|
|
248 | (2) |
|
Dropping capabilities from the root user |
|
|
250 | (1) |
|
10.6 Running Docker Bench for security |
|
|
251 | (2) |
|
10.7 Securing access to the Docker host |
|
|
253 | (7) |
|
Enabling remote access to the Docker daemon |
|
|
254 | (2) |
|
Enabling mTLS at the NGLNX server to secure access to Docker APIs |
|
|
256 | (4) |
|
10.8 Considering security beyond containers |
|
|
260 | (2) |
|
11 Securing microservices on Kubernetes |
|
|
262 | (34) |
|
11.1 Running an STS on Kubernetes |
|
|
263 | (4) |
|
Defining a Kubernetes Deployment for the STS in YAML |
|
|
263 | (1) |
|
Creating the STS Deployment in Kubernetes |
|
|
263 | (1) |
|
Troubleshooting the Deployment |
|
|
264 | (1) |
|
Exposing the STS outside the Kubernetes cluster |
|
|
265 | (2) |
|
11.2 Managing secrets in a Kubernetes environment |
|
|
267 | (7) |
|
Using ConfigMap to externalize configurations in Kubernetes |
|
|
268 | (1) |
|
Defining a ConfigMap for application.properties file |
|
|
268 | (1) |
|
Defining ConfigMaps for keystore.jks andjwt.jks files |
|
|
269 | (1) |
|
Defining a ConfigMap for key store credentials |
|
|
270 | (1) |
|
Creating ConfigMaps by using the kubectl client |
|
|
270 | (1) |
|
Consuming ConfigMaps from a Kubernetes Deployment |
|
|
271 | (1) |
|
Loading keystores with an init container |
|
|
272 | (2) |
|
11.3 Using Kubernetes Secrets |
|
|
274 | (4) |
|
Exploring the default token secret in every container |
|
|
275 | (1) |
|
Updating the STS to use Secrets |
|
|
276 | (2) |
|
Understanding how Kubernetes stores Secrets |
|
|
278 | (1) |
|
11.4 Running the Order Processing microservice in Kubernetes |
|
|
278 | (6) |
|
Creating ConfigMaps/Secrets for the Order Processing microservice |
|
|
280 | (1) |
|
Creating a Deployment for the Order Processing microservice |
|
|
281 | (1) |
|
Creating a Service for the Order Processing microservice |
|
|
282 | (1) |
|
Testing the end-to-end flow |
|
|
282 | (2) |
|
11.5 Running the Inventory microservice in Kubernetes |
|
|
284 | (3) |
|
11.6 Using Kubernetes service accounts |
|
|
287 | (3) |
|
Creating a service account and associating it with a Pod |
|
|
288 | (1) |
|
Benefits of running a Pod under a custom service account |
|
|
289 | (1) |
|
11.7 Using role-based access control in Kubernetes |
|
|
290 | (6) |
|
Talking to the Kubernetes API server from the STS |
|
|
292 | (1) |
|
Associating a service account with a ClusterRole |
|
|
293 | (3) |
|
12 Securing microservices with Istio service mesh |
|
|
296 | (43) |
|
12.1 Setting up the Kubernetes deployment |
|
|
297 | (5) |
|
Enabling Istio autoinjection |
|
|
298 | (1) |
|
Clean up any previous work |
|
|
299 | (1) |
|
|
299 | (1) |
|
Redeploying Order Processing and STS as NodePort Services |
|
|
300 | (1) |
|
|
301 | (1) |
|
12.2 Enabling TLS termination at the Istio Ingress gateway |
|
|
302 | (12) |
|
Deploying TLS certificates to the Istio Ingress gateway |
|
|
303 | (5) |
|
Deploying VirtualServices |
|
|
308 | (2) |
|
Defining a permissive authentication policy |
|
|
310 | (1) |
|
|
311 | (3) |
|
12.3 Securing service-to-service communications with mTLS |
|
|
314 | (3) |
|
12.4 Securing service-to-service communications with JWT |
|
|
317 | (7) |
|
Enforcing JWT authentication |
|
|
317 | (1) |
|
Testing end-to-end flow with JWT authentication |
|
|
318 | (3) |
|
Peer authentication and request authentication |
|
|
321 | (2) |
|
How to use JWT in service-to-service communications |
|
|
323 | (1) |
|
A closer look at JSON Web Key |
|
|
324 | (1) |
|
12.5 Enforcing authorization |
|
|
324 | (9) |
|
|
324 | (1) |
|
Enforcing role-based access control |
|
|
325 | (3) |
|
Testing end-to-end flow with RBAC |
|
|
328 | (3) |
|
Improvements to role-based access control since Istio 1.4.0 |
|
|
331 | (2) |
|
12.6 Managing keys in Istio |
|
|
333 | (6) |
|
Key provisioning and rotation via volume mounts |
|
|
333 | (2) |
|
Limitations in key provisioning and rotation via volume mounts |
|
|
335 | (1) |
|
Key provisioning and rotation with SDS |
|
|
335 | (4) |
|
PART 5 SECURE DEVELOPMENT |
|
|
339 | (28) |
|
13 Secure coding practices and automation |
|
|
341 | (26) |
|
13.1 OWASP API security top 10 |
|
|
342 | (7) |
|
Broken object-level authorization |
|
|
342 | (2) |
|
|
344 | (1) |
|
|
345 | (1) |
|
Lack of resources and rate limiting |
|
|
345 | (1) |
|
Broken function-level authorization |
|
|
346 | (1) |
|
|
346 | (1) |
|
Security misconfiguration |
|
|
347 | (1) |
|
|
347 | (1) |
|
Improper asset management |
|
|
348 | (1) |
|
Insufficient logging and monitoring |
|
|
348 | (1) |
|
13.2 Running static code analysis |
|
|
349 | (3) |
|
13.3 Integrating security testing with Jenkins |
|
|
352 | (7) |
|
Setting up and running Jenkins |
|
|
353 | (2) |
|
Setting up a build pipeline with Jenkins |
|
|
355 | (4) |
|
13.4 Running dynamic analysis with OWASP ZAP |
|
|
359 | (8) |
|
Passive scanning vs. active scanning |
|
|
359 | (1) |
|
Performing penetration tests with ZAP |
|
|
360 | (7) |
Appendix A OAuth 2.0 and OpenID Connect |
|
367 | (19) |
Appendix B JSON Web Token |
|
386 | (11) |
Appendix C Single-page application architecture |
|
397 | (4) |
Appendix D Observability in a microservices deployment |
|
401 | (8) |
Appendix E Docker fundamentals |
|
409 | (39) |
Appendix F Open Policy Agent |
|
448 | (22) |
Appendix G Creating a certificate authority and related keys with OpenSSL |
|
470 | (4) |
Appendix H Secure Production Identity Framework for Everyone |
|
474 | (14) |
Appendix I gRPC fundamentals |
|
488 | (11) |
Appendix J Kubernetes fundamentals |
|
499 | (37) |
Appendix K Service mesh and Istio fundamentals |
|
536 | (33) |
Index |
|
569 | |