Zero Trust, mTLS & OAuth — Bảo mật microservices hiện đại (BMS)

Phong

Mở đầu

Sau chapter về monitoring, cuốn sách chuyển sang một chủ đề mà nhiều đội ngũ chỉ nghĩ tới khi đã muộn: bảo mật. Monolith chỉ cần bảo vệ một cửa ngõ duy nhất, còn microservices thì mỗi đường giao tiếp giữa các service đều là một bề mặt tấn công tiềm năng. Chapter 11 của Building Microservices đưa ra tư duy zero trust, cơ chế xác thực như mTLS, OAuth 2.0, cùng cách mã hoá dữ liệu ở mọi lớp — những thứ quyết định hệ thống có đủ an toàn để chạy production hay không.

Ảnh: Nathan Thomas — Pexels

Zero Trust — không tin bất kỳ ai, kể cả mạng nội bộ

Cách bảo mật truyền thống dựa trên perimeter: tin tưởng toàn bộ mạng nội bộ, chặn mọi thứ từ bên ngoài bằng firewall, và hễ ai vào được office network hay VPN thì coi như hợp lệ. Vấn đề của mô hình này là một khi attacker đã lọt vào trong — qua phishing, insider, hay supply chain — thì việc di chuyển ngang (lateral movement) gần như tự do, vì mọi traffic nội bộ đều mặc định được tin.

Zero trust đảo ngược giả định đó: không tin bất kỳ request nào chỉ vì nó đến từ mạng nội bộ. Mỗi request, dù đến từ đâu, đều phải trải qua xác thực (authentication) và phân quyền (authorization). Nguyên tắc gói gọn trong câu nổi tiếng: never trust, always verify. Trong microservices, điều này có nghĩa là kiểm soát ở riêng API gateway là chưa đủ — nếu một service bị chiếm quyền, attacker sẽ dùng nó làm bàn đạp gọi thẳng vào các service khác. Nên mỗi service phải tự xác minh danh tính người gọi, cấp quyền tối thiểu đủ dùng (least privilege), và giám sát hành vi bất thường — kết nối tự nhiên với chủ đề observability ở bài trước.

Ảnh: Ann H — Pexels

mTLS — bắt tay hai chiều giữa các service

TLS thông thường chỉ xác thực một chiều: client kiểm tra chứng chỉ của server, còn server không biết client là ai. Mutual TLS (mTLS) nâng cấp lên cả hai chiều — cả hai bên đều trình chứng chỉ và đều xác minh lẫn nhau, giống như hẹn gặp mà cả hai phía đều xuất trình giấy tờ tuỳ thân trước khi bắt đầu nói chuyện.

mTLS là lựa chọn phổ biến cho giao tiếp service-to-service, đặc biệt trong môi trường không tin cậy như cloud. Nó khắc phục điểm yếu của API key đặt trong header: key là shared secret dễ bị lộ qua log, config hay repo, còn mTLS dựa trên danh tính mật mã gắn với chính service. Triển khai thủ công thì khá cực — phải tự quản lý CA, cấp phát và rotate chứng chỉ trước khi hết hạn — nhưng service mesh (Istio, Linkerd) tự động hoá gần hết phần này bằng sidecar proxy: code ứng dụng gần như không đổi, chứng chỉ được cấp và gia hạn tự động. Lưu ý quan trọng: mTLS lo chuyện xác thực danh tính, không thay thế phân quyền — biết được "bạn là ai" rồi vẫn phải kiểm tra "bạn được làm gì".

OAuth 2.0 & OpenID Connect — nền tảng phân quyền

Cần phân biệt hai khái niệm dễ nhầm: authentication là xác minh bạn là ai, authorization là kiểm tra bạn được làm gì. OAuth 2.0 là framework phân quyền — cho phép một client truy cập tài nguyên thay mặt user mà không cần biết mật khẩu của họ. OpenID Connect (OIDC) là lớp định danh xây trên OAuth 2.0, bổ sung ID token chứa thông tin user, dùng cho authentication và single sign-on.

Các vai trò trong OAuth gồm resource owner (user), client (ứng dụng hoặc service), authorization server (nhà cấp danh tính, IdP) và resource server (service giữ dữ liệu). Flow phổ biến: authorization code cho ứng dụng có giao diện người dùng, còn client credentials cho giao tiếp service-to-service. Token trả về thường là JWT — token ký số tự chứa claims, service có thể verify stateless mà không cần gọi lại IdP mỗi request. Cái giá của JWT là khó thu hồi: token còn hạn là còn dùng được, nên phải để thời gian sống ngắn và xoay vòng khoá công khai (JWKS) cẩn thận. Lời khuyên xuyên suốt chapter này: đừng tự phát minh hệ thống identity — dùng chuẩn mở và IdP có sẵn như Keycloak, Auth0, Okta, bởi tự làm OAuth sai cách là một trong những lỗ hổng phổ biến nhất thực tế.

Data in transit & data at rest — mã hoá ở mọi lớp

Data in transit là dữ liệu đang di chuyển trên mạng. Nhiều hệ thống chỉ bật TLS ở biên — terminate tại load balancer rồi gửi plaintext HTTP vào bên trong — nhưng trong môi trường cloud, mạng nội bộ không tự nhiên an toàn. Hướng dẫn trong sách là bật TLS cho mọi hop, hoặc ít nhất giữa các thành phần quan trọng như database, message broker và giữa các service với nhau, thay vì chỉ dựa vào lớp mạng.

Data at rest là dữ liệu lưu trữ: database, backup, disk. Mã hoá ở lớp này quan trọng không kém, nhưng điểm mấu chốt nằm ở quản lý khoá — khoá nằm ở đâu, ai được quyền truy cập, xoay vòng thế nào (KMS, Vault). Mã hoá mà khoá đặt chung máy với dữ liệu thì chỉ là hình thức. Nhìn chung, tinh thần của chapter là defense in depth: bảo mật là nhiều lớp chồng lên nhau, mỗi lớp chặn một kiểu tấn công — nếu một lớp bị xuyên thủng thì các lớp sau vẫn còn đó, đừng đặt hết niềm tin vào một cơ chế duy nhất.

Ảnh: Markus Winkler — Pexels

Key Takeaways

  • Zero trust là tư duy nền tảng: không tin vào vị trí mạng, mọi request đều phải xác thực và phân quyền — kể cả request đến từ service nội bộ.
  • mTLS xác thực hai chiều cho giao tiếp service-to-service; service mesh giúp tự động hoá việc cấp phát và xoay vòng chứng chỉ.
  • OAuth 2.0 lo chuyện phân quyền, OIDC thêm lớp định danh; nên dùng chuẩn mở và IdP có sẵn thay vì tự phát minh.
  • Mã hoá cả data in transit lẫn data at rest, và quản lý khoá cẩn thận — khoá để chung với dữ liệu thì mã hoá vô nghĩa.
  • Defense in depth: bảo mật nhiều lớp chồng nhau, không đặt hết niềm tin vào một cơ chế duy nhất.

Glossary

Thuật ngữÝ nghĩa
Zero trustMô hình bảo mật "never trust, always verify": không tin request nào chỉ vì nó đến từ mạng nội bộ
mTLS (Mutual TLS)Giao thức TLS hai chiều, cả client lẫn server đều xác thực bằng chứng chỉ
OAuth 2.0Framework phân quyền (authorization), cho phép client truy cập tài nguyên thay mặt user
OpenID ConnectLớp định danh xây trên OAuth 2.0, cung cấp ID token cho authentication và SSO
JWTJSON Web Token: token ký số chứa claims, verify stateless không cần gọi lại IdP
IdPIdentity Provider — hệ thống cấp và quản lý danh tính (Keycloak, Auth0, Okta...)
Service meshLớp hạ tầng dùng sidecar proxy, tự động hoá mTLS, routing và observability
Least privilegeNguyên tắc cấp cho mỗi service quyền tối thiểu đủ dùng
Data at restDữ liệu lưu trữ (database, backup, disk) cần được mã hoá
Defense in depthChiến lược bảo mật nhiều lớp chồng nhau để chặn các kiểu tấn công khác nhau

Kết

Bảo mật microservices không bắt đầu từ việc mua công cụ đắt tiền, mà từ việc đổi cách nghĩ: không tin tưởng mù quáng vào ranh giới mạng, xác thực mọi request, mã hoá dữ liệu ở mọi lớp và dùng các chuẩn đã được kiểm chứng. Làm đúng những điều cơ bản này còn giá trị hơn nhiều so với việc chạy theo từng buzzword bảo mật. Và dù bảo mật có tốt đến đâu, lỗi vẫn sẽ xảy ra — chapter tiếp theo của series nói về resiliency, cách để hệ thống sống sót và phục hồi khi sự cố thực sự diễn ra.