Trước khi giao chìa khóa cho AI, hãy khai sinh cho nó
Một đứa trẻ vừa sinh ra.
Việc đầu tiên người lớn làm không phải dạy nó toán.
Cũng không phải mở tài khoản ngân hàng.
Càng không phải đưa cho nó chìa khóa kho hàng rồi bảo:
Con cứ tự nhiên lấy những gì con thấy cần thiết.
Việc đầu tiên là làm giấy khai sinh.
Đứa trẻ cần có tên.
Có ngày sinh.
Có cha mẹ.
Có một mã định danh để sau này người ta biết nó là ai.
Sau đó mới tới chuyện đi học, đi làm, mở tài khoản, ký hợp đồng hay sở hữu tài sản.
AI Agent cũng nên như vậy.
Trước khi cho nó quyền đọc email, sửa dữ liệu, tạo đơn hàng, gọi hệ thống thanh toán hay deploy code lên production, ta cần trả lời một câu hỏi cực kỳ căn bản:
Agent này là ai?
Nghe thì có vẻ đơn giản.
Ta đặt cho nó một cái tên.
1oncall-agent
Xong.
Nhưng cái tên chỉ là một dòng chữ.
Bất kỳ chương trình nào cũng có thể tự xưng là oncall-agent.
Giống như một người đi vào ngân hàng, đeo tờ giấy trước ngực ghi:
1Tôi là giám đốc
Rồi yêu cầu mở két sắt.
Bác bảo vệ có thể rất quý sự tự tin.
Nhưng chắc chắn vẫn phải hỏi giấy tờ.
Đây là điều khiến mình tâm đắc khi đọc bài “Solving the Identity Crisis for AI Agents” của Uber Engineering.
Uber không chỉ hỏi làm sao để Agent gọi được nhiều công cụ hơn.
Họ hỏi một câu khó hơn:
Khi một hành động đi qua nhiều Agent, nhiều hệ thống và nhiều bước suy luận, làm thế nào để biết chính xác ai đã khởi đầu nó, Agent nào đã tham gia và vì sao hành động cuối cùng được phép xảy ra?
Uber gọi đây là cuộc khủng hoảng danh tính của AI Agent.
Theo mình, cái tên này rất đúng.
AI không thiếu một cái username.
Nó thiếu cả một hệ thống để chứng minh mình là ai, đang thay mặt ai và đã đi qua con đường nào trước khi chạm vào dữ liệu thật.
Khi AI chỉ nói chuyện, danh tính chưa đáng sợ lắm
Ngày trước, một chatbot thường hoạt động như thế này:
1Người dùng
2 │
3 ▼
4 LLM
5 │
6 ▼
7Câu trả lời
Bạn hỏi:
Viết giúp tôi một email xin nghỉ phép.
AI viết.
Bạn đọc lại.
Bạn tự bấm gửi.
Trong mô hình này, AI chỉ tạo nội dung.
Nó chưa trực tiếp hành động lên hệ thống.
Nếu câu trả lời sai, con người vẫn còn đứng ở giữa để kiểm tra.
Nhưng Agent ngày nay có thể đi xa hơn:
1Người dùng
2 │
3 ▼
4Agent lập kế hoạch
5 │
6 ├── Đọc tài liệu
7 ├── Truy vấn database
8 ├── Gọi Agent khác
9 ├── Tạo Pull Request
10 ├── Gửi email
11 └── Thay đổi cấu hình
AI không còn chỉ nói.
Nó bắt đầu làm.
Và ngay khi một chương trình có khả năng tác động lên thế giới bên ngoài, danh tính không còn là chi tiết kỹ thuật nằm phía sau màn hình đăng nhập.
Nó trở thành nền móng của trách nhiệm.
Một Agent sửa đúng lỗi, nhưng không ai biết ai chịu trách nhiệm
Uber đưa ra một ví dụ rất thực tế.
Một kỹ sư đang trực hệ thống nhận được cảnh báo.
Người này giao nhiệm vụ cho một On-call Agent điều tra.
On-call Agent gọi Investigation Agent để kiểm tra log và metric.
Investigation Agent kết luận hệ thống vẫn hoạt động bình thường, nhưng ngưỡng cảnh báo đang được cấu hình sai.
Sau đó, Monitoring Agent được gọi để thay đổi ngưỡng và tạo một Pull Request.
Cuối cùng, trong lịch sử source code chỉ hiện:
1Monitoring Agent đã tạo thay đổi.
Nhưng ai đã khởi đầu công việc này?
Kỹ sư nào yêu cầu?
On-call Agent đã đưa ra quyết định gì?
Investigation Agent dựa trên dữ liệu nào để kết luận cảnh báo bị sai?
Monitoring Agent đang tự hành động hay đang làm thay một con người cụ thể?
Nếu chỉ nhìn hệ thống cuối cùng, những thông tin đó đã biến mất.
Downstream chỉ thấy:
Có một service vừa gọi API.
Uber cho biết họ gặp lại kiểu mất dấu này trong nhiều workflow: Agent hoàn thành công việc qua nhiều bước, nhưng mỗi hệ thống phía sau chỉ nhìn thấy một service identity chung chung, thay vì nhận được đầy đủ danh tính người khởi tạo và chuỗi Agent đã tham gia. (Uber)
Đây là một loại mất trí nhớ khá nguy hiểm.
Cỗ máy vẫn nhớ việc gì đã xảy ra.
Nhưng quên mất câu chuyện dẫn tới hành động đó.
Một chiếc camera chỉ quay được cái búa
Giả sử camera trong kho ghi lại cảnh một chiếc búa tự bay lên rồi đập vỡ cửa.
Camera chỉ báo:
1Công cụ được sử dụng: búa
2Thời gian: 02:15
3Hành động: phá cửa
Nhưng camera không biết:
- Ai cầm búa?
- Người đó được ai sai đi?
- Họ định sửa ổ khóa hay muốn trộm đồ?
- Trước đó chuyện gì đã xảy ra?
- Ai đã cho phép mở cửa?
Log của nhiều hệ thống Agent hiện nay cũng tương tự.
Nó ghi lại Agent cuối cùng gọi API.
Nhưng không giữ được provenance, tức nguồn gốc và con đường của hành động.
Trong một workflow đơn giản, chuyện này đã khó chịu.
Trong một hệ thống có hàng chục Agent gọi qua gọi lại, nó trở thành một mê cung.
1User
2 ↓
3Planning Agent
4 ↓
5On-call Agent
6 ↓
7Investigation Agent
8 ↓
9Monitoring Agent
10 ↓
11MCP Gateway
12 ↓
13Source Control
Nếu Source Control chỉ biết Monitoring Agent, phần lớn câu chuyện đã bị bỏ lại ở những đoạn trước.
Khi có sự cố, đội vận hành phải ghép log từ nhiều hệ thống lại như nhặt từng mảnh kính vỡ trên sàn.
Danh tính, xác thực và phân quyền không phải một thứ
Ba khái niệm này thường bị trộn chung với nhau.
Identity: Bạn là ai?
Ví dụ:
1Agent ID: monitoring-agent
2Owner: Observability Team
3Version: 2.3
4Workload: monitoring-agent-prod
Đây là thông tin mô tả một thực thể.
Authentication: Bạn chứng minh điều đó bằng cách nào?
Agent không thể chỉ tự khai:
Tôi là Monitoring Agent.
Nó cần một bằng chứng có thể kiểm tra bằng mật mã.
Chẳng hạn một chứng thư hoặc token được ký bởi hệ thống đáng tin cậy.
Authorization: Bạn được phép làm gì?
Ngay cả khi đúng là Monitoring Agent, nó chưa chắc được phép:
- Xóa toàn bộ alert.
- Truy cập dữ liệu nhân sự.
- Sửa source code của hệ thống thanh toán.
- Tự phê duyệt Pull Request của chính mình.
Authentication chứng minh danh tính.
Authorization giới hạn quyền lực.
Một người có căn cước công dân thật không có nghĩa họ được quyền đi vào kho tiền của ngân hàng.
Agent không hoàn toàn giống con người, cũng không hoàn toàn giống service
Hệ thống IAM truyền thống thường quen với hai nhóm danh tính.
1Con người
và:
1Workload / Service
Con người đăng nhập bằng tài khoản cá nhân.
Service chạy bằng service account, certificate hoặc API key.
Nhưng Agent đứng ở giữa hai thế giới này.
Nó chạy bên trong một workload giống service.
Nhưng nó thường hành động thay mặt con người.
Nó có thể tự lập kế hoạch.
Có thể gọi Agent khác.
Có thể thay đổi hướng đi dựa trên kết quả trung gian.
Có thể sử dụng nhiều công cụ trong cùng một phiên.
Uber tóm tắt ba đặc điểm làm Agent khác automation truyền thống:
- Agent mặc định hoạt động theo cơ chế ủy quyền.
- Workflow có tính kết hợp, Agent có thể gọi Agent và công cụ khác.
- Kế hoạch có thể thay đổi động trong quá trình thực thi. (Uber)
Một cron job thường biết trước mình sẽ làm gì.
Ba giờ sáng chạy query.
Xuất báo cáo.
Gửi email.
Xong.
Một Agent thì có thể bắt đầu bằng nhiệm vụ:
Tìm nguyên nhân hệ thống chậm và đề xuất cách khắc phục.
Nó chưa biết trước sẽ gọi log, metric, source code hay ticket.
Con đường được hình thành trong lúc nó làm việc.
Bởi vậy, chỉ gắn danh tính vào tiến trình đang chạy là chưa đủ.
Ta còn phải giữ được chuỗi ủy quyền xuyên suốt hành trình.
API Key dùng chung giống chìa khóa tổng của cả công ty
Cách nhanh nhất để một Agent gọi công cụ là đưa cho nó API key.
1Agent
2 │
3 │ API_KEY=abc123
4 ▼
5Internal API
Demo chạy được.
Mọi người vui.
Sau đó Agent thứ hai xuất hiện.
Rồi Agent thứ ba.
Vì một lý do nào đó mà tác giả chưa nghĩ ra, cả ba tiếp tục dùng chung chiếc khóa abc123.
Một năm sau, công ty có một trăm Agent.
Ai cũng cầm cùng một chìa khóa.
Chìa đó mở được:
- Kho hàng.
- Phòng kế toán.
- Phòng giám đốc.
- Tủ điện.
- Cửa sau.
- Và có thể cả két sắt.
Đến lúc xảy ra sự cố, log chỉ ghi:
1API key abc123 đã thực hiện hành động.
Không biết Agent nào.
Không biết người nào.
Không biết phiên làm việc nào.
Không biết mục đích gì.
API key dài hạn còn có một đặc điểm đáng yêu khác: nếu bị lộ, nó có thể tiếp tục sống lâu hơn cả người tạo ra nó.
Một Agent production không nên được xây trên niềm tin rằng bí mật sẽ không bao giờ rơi khỏi túi.
Không nên đưa thẻ căn cước của người dùng cho Agent giữ
Một cách khác là cho Agent dùng trực tiếp token của người dùng.
1User Token
2 │
3 ▼
4Agent
5 │
6 ▼
7Downstream System
Cách này giúp hệ thống phía sau thấy danh tính con người.
Nhưng lại nảy sinh nhiều vấn đề.
Agent có thể mang token đi xa hơn phạm vi ban đầu.
Token có thể được tái sử dụng cho hệ thống khác.
Downstream chỉ thấy con người, không thấy Agent nào đang hành động.
Nếu nhiều Agent chuyền nhau cùng một credential, toàn bộ hành động trông như do người dùng trực tiếp thực hiện.
Giống bạn đưa căn cước và chữ ký cho một nhân viên rồi bảo:
Em cứ thay anh làm việc.
Nhân viên đó tiếp tục photocopy giấy tờ rồi đưa cho ba người khác.
Cuối ngày, mọi hợp đồng đều mang tên bạn.
Nhưng bạn không biết ai đã viết từng dòng.
Trong kiến trúc của Uber, Agent không tái sử dụng credential thô của người dùng để gọi hệ thống phía sau. Mỗi bước sẽ xin một token mới, dành riêng cho bước tiếp theo, trong khi vẫn giữ lại thông tin về người khởi tạo. (Uber)
Đây là khác biệt giữa giả danh và được ủy quyền.
Agent không trở thành người dùng.
Agent vẫn là chính nó.
Nhưng hệ thống biết nó đang hành động thay mặt ai.
Kiến trúc của Uber: Một phòng cấp giấy tờ cho Agent
Uber mở rộng kiến trúc Zero Trust hiện có để hỗ trợ Agent.
Thay vì tin một Agent chỉ vì nó đang chạy trong mạng nội bộ, mỗi Agent phải có danh tính có thể kiểm chứng, xin token đúng mục đích và đi qua các điểm thực thi chính sách trước khi gọi hệ thống phía sau. (Uber)
Kiến trúc có thể hình dung như sau:
1 CONTROL PLANE
2
3 ┌────────────────────┐
4 │ Agent Registry │
5 └─────────┬──────────┘
6 │ xác minh đăng ký
7 ▼
8 ┌────────────────────┐
9 │ Security Token │
10 │ Service - STS │
11 └─────────┬──────────┘
12 │ phát JWT ngắn hạn
13 ▼
14
15 DATA PLANE
16
17User → Agent A → Agent B → MCP Gateway → Downstream
18 │ │ │
19 └──── JWT theo từng bước ────┘
Các thành phần chính gồm:
- Agent Registry
- AI Agent Mesh
- Security Token Service
- MCP Gateway
- AI Gateway
- Downstream Systems
Mỗi thành phần giống một bộ phận trong tòa nhà.
Agent Registry: Sổ hộ khẩu của các Agent
Agent Registry là nguồn thông tin trung tâm cho biết:
- Agent nào tồn tại.
- Agent ID là gì.
- Agent được phép chạy trên workload nào.
- Ai sở hữu Agent.
- Cấu hình nào gắn với Agent.
- Trạng thái hiện tại ra sao.
Tại Uber, Agent thường được triển khai như workload trên Kubernetes. Nền tảng Michelangelo liên kết Agent với workload, sau đó lưu mối quan hệ này trong Agent Registry để Security Token Service có thể kiểm tra khi Agent xin danh tính. (Uber)
Điều này giải quyết một lỗ hổng rất cơ bản.
Giả sử workload của Weather Agent gửi yêu cầu:
Tôi là Payment Agent. Hãy cấp token cho tôi chuyển tiền.
STS sẽ hỏi Registry:
Workload này có thực sự được đăng ký để chạy Payment Agent không?
Nếu không, yêu cầu bị từ chối.
Chỉ biết agent_id chưa đủ.
Ta phải chứng minh Agent đó đang chạy đúng trên môi trường được phép chứa nó.
Giống một bác sĩ có bằng thật nhưng đang dùng thẻ bệnh viện của người khác.
Danh tính phải gắn với nơi thực thể đang hoạt động.
SPIFFE và SPIRE: Căn cước của workload
Trước khi chứng minh Agent, Uber cần xác minh workload đang chạy Agent đó.
Mỗi workload lấy một SPIFFE Verifiable Identity Document, thường gọi là SVID, được ký bằng mật mã bởi SPIRE.
SPIFFE và SPIRE được thiết kế để cung cấp danh tính mật mã đã được kiểm chứng cho workload trong các môi trường phân tán. (Spiffe)
Có thể hình dung:
1Workload:
2“Tôi đang chạy trong Kubernetes cluster production,
3thuộc namespace này,
4service account này,
5và đây là giấy tờ được hệ thống hạ tầng ký.”
SVID chứng minh chiếc máy hoặc workload đứng trước cửa là hợp lệ.
Nhưng nó chưa tự động chứng minh Agent cụ thể đang chạy bên trong.
Đó là lý do còn cần Agent Registry.
Quy trình được ghép lại như sau:
1Workload identity
2 +
3Agent registration
4 +
5Inbound user context
6 +
7Destination
8 ↓
9Security Token Service
10 ↓
11JWT cho Agent
Uber mô tả bốn bước chính:
- Workload lấy SVID được ký bởi SPIRE.
- Agent SDK dùng SVID cùng metadata của Agent, token đầu vào và hệ thống đích để xin JWT từ STS.
- STS hỏi Agent Registry xem Agent có được phép chạy trên workload đó hay không.
- Nếu hợp lệ, STS phát JWT cho bước gọi tiếp theo. (Uber)
Không phải một tờ giấy.
Mà là nhiều lớp giấy tờ kiểm tra lẫn nhau.
Nghe hơi rắc rối.
Nhưng nếu Agent có quyền sửa production, sự rắc rối này khá rẻ so với việc họp khẩn lúc hai giờ sáng.
Security Token Service: Bác bảo vệ không phát chìa khóa vĩnh viễn
STS là nơi phát token cho Agent.
Điểm quan trọng là Uber không dùng credential rộng và sống lâu.
STS phát token:
- Chỉ dùng cho một bước gọi.
- Có thời gian sống ngắn, thường tính bằng phút.
- Có
audiencecụ thể. - Có thông tin về Agent.
- Có chuỗi thực thể đã tham gia.
Cơ chế này có ý tưởng gần với OAuth 2.0 Token Exchange trong RFC 8693, tiêu chuẩn cho phép đổi một token hiện có lấy token mới phù hợp với một ngữ cảnh, đối tượng nhận hoặc hình thức ủy quyền khác. Uber cho biết họ tùy biến cách trao đổi này để phù hợp với yêu cầu audit và hiệu năng nội bộ. (RFC Editor)
Nói theo cách dễ hiểu hơn:
Một người cầm giấy giới thiệu tới cổng tòa nhà.
Bác bảo vệ không đưa chìa khóa tổng.
Bác phát một thẻ tạm:
1Chỉ được vào phòng Monitoring.
2Có hiệu lực trong 5 phút.
3Không mở được phòng Database.
4Không dùng lại vào ngày mai.
Khi cần sang phòng khác, người đó quay lại xin thẻ mới.
Hơi mất công.
Nhưng một chiếc thẻ bị rơi cũng không mở được cả tòa nhà.
Audience: Vé đi Đà Nẵng không dùng để lên máy bay đi Hà Nội
Trong JWT, audience xác định token được phát cho hệ thống nào.
Ví dụ:
1{
2 "aud": "investigation-agent"
3}
Token này chỉ hợp lệ khi gọi Investigation Agent.
Không được đem nó tới MCP Gateway.
Không được dùng để gọi database.
Không được trình cho hệ thống thanh toán.
Uber phát token theo từng bước với audience riêng, vì vậy token bị lấy cắp ở một bước không thể dễ dàng được phát lại cho một đích khác. (Uber)
Đây là nguyên tắc rất quan trọng.
Nhiều hệ thống tạo một token kiểu:
1Đã đăng nhập.
Sau đó token đó được chấp nhận ở mọi nơi.
Nó giống một tấm vé chỉ ghi:
1Được phép đi đâu đó.
Không hãng hàng không nào vận hành như vậy.
Vé cần ghi chuyến bay, ngày giờ và hành khách.
Token cũng cần ghi rõ nó được sinh ra để làm gì và được trình cho ai.
Token ngắn hạn: Chìa khóa tự tan sau vài phút
Credential sống càng lâu, hậu quả khi bị lộ càng lớn.
Một API key có tuổi thọ hai năm có thể bị sao chép vào:
- Source code.
- File cấu hình.
- Log.
- Ticket.
- Email.
- Laptop cũ.
- Một server đã quên tắt.
Token vài phút không làm rủi ro biến mất.
Nhưng nó thu nhỏ cửa sổ tấn công.
Giống một chìa khóa bằng nước đá.
Nó vẫn có thể mở cửa.
Nhưng nếu rơi ngoài đường, vài phút sau nó không còn dùng được.
Uber sử dụng JWT ngắn hạn theo từng hop và để STS là thành phần duy nhất được phép cấp Agent token, từ đó tập trung việc kiểm tra, audit và thu hồi niềm tin. (Uber)
Actor chain: Ghi lại cả đoàn người, không chỉ người cuối hàng
Phần mình thích nhất trong kiến trúc là actor chain.
Giả sử workflow:
1Tùng
2 ↓
3On-call Agent
4 ↓
5Investigation Agent
6 ↓
7MCP Gateway
Khi Investigation Agent gọi MCP Gateway, token không chỉ ghi:
1Caller: Investigation Agent
Nó giữ lại chuỗi:
1Tùng
2→ On-call Agent
3→ Investigation Agent
Một payload minh họa có thể trông như sau:
1{
2 "iss": "security-token-service",
3 "sub": "investigation-agent",
4 "aud": "mcp-gateway",
5 "exp": 1780000300,
6 "agent_id": "investigation-agent",
7 "actor_chain": [
8 {
9 "type": "human",
10 "id": "phamduytung"
11 },
12 {
13 "type": "agent",
14 "id": "oncall-agent"
15 },
16 {
17 "type": "agent",
18 "id": "investigation-agent"
19 }
20 ]
21}
Đây chỉ là ví dụ đơn giản hóa, không phải payload chính xác của Uber.
Ý tưởng quan trọng là downstream nhìn được cả dòng họ của request.
Uber cho biết STS thực hiện token exchange ở mỗi bước và đưa chuỗi actor đã được xác thực vào token, nhờ đó Gateway hoặc hệ thống cuối có thể thấy người khởi tạo cùng các Agent trung gian, thay vì chỉ nhìn thấy caller gần nhất. (Uber)
Điều này biến log từ:
1investigation-agent gọi read_logs
thành:
1phamduytung
2ủy quyền cho oncall-agent
3oncall-agent gọi investigation-agent
4investigation-agent gọi read_logs
5trong session X
6để điều tra alert Y
Bỗng nhiên, log không chỉ là biên lai.
Nó trở thành một câu chuyện.
Vì sao không ký một token từ đầu rồi dùng tới cuối?
Có thể đặt câu hỏi:
Tại sao không tạo một token chứa toàn bộ quyền ngay từ đầu, rồi truyền qua tất cả Agent?
Vấn đề là tại thời điểm bắt đầu, workflow có thể chưa biết mình sẽ đi đâu.
Agent lập kế hoạch động.
Kết quả của bước trước quyết định bước sau.
Nếu phát một token quá rộng từ đầu, ta phải đoán và cấp sẵn nhiều quyền hơn mức cần thiết.
Token exchange theo từng hop cho phép quyền được thu hẹp theo con đường thực tế.
1User → On-call Agent
Token đầu chỉ dành cho On-call Agent.
1On-call Agent → Investigation Agent
Token tiếp theo chỉ dành cho Investigation Agent.
1Investigation Agent → MCP Gateway
Token mới chỉ dành cho MCP Gateway.
Mỗi bước là một lần hệ thống hỏi lại:
Anh là ai?
Anh đang thay mặt ai?
Anh muốn đi đâu?
Anh có được phép đi không?
Đây chính là tinh thần Zero Trust.
Không có vùng “đã ở trong mạng nội bộ thì cứ tự nhiên”.
MCP Gateway: Bác bảo vệ đứng trước kho công cụ
MCP giúp Agent kết nối tới công cụ và tài nguyên thông qua một giao thức chung.
Điều đó làm Agent mạnh hơn.
Cũng làm hậu quả của việc cấp quyền sai lớn hơn.
Nếu một Agent có thể gọi:
1read_customer
2create_order
3refund_payment
4delete_alert
5merge_pull_request
thì MCP Gateway không nên chỉ là người chuyển tiếp request.
Nó phải là điểm thực thi chính sách.
Uber sử dụng MCP Gateway để:
- Xác thực token.
- Kiểm tra quyền truy cập tool.
- Áp dụng policy dựa trên mức rủi ro.
- Redact dữ liệu nhạy cảm khi cần.
- Proxy request tới downstream system. (Uber)
Có thể hình dung MCP Gateway là bác thủ kho.
Agent tới và nói:
Cho tôi mượn máy khoan.
Bác không chỉ kiểm tra thẻ nhân viên.
Bác còn hỏi:
Anh thuộc đội nào?
Ai cử anh tới?
Đang sửa khu vực nào?
Có được phép dùng máy khoan công suất lớn không?
Có cần che thông tin nhạy cảm trước khi đưa tài liệu không?
Một Gateway chỉ kiểm tra “đã đăng nhập” là chưa đủ.
Nó phải hiểu cả người khởi tạo lẫn Agent đang hành động.
Một hành động cần hai danh tính
Trong workflow Agent, authorization có thể phải đánh giá đồng thời:
1Danh tính con người
2 +
3Danh tính Agent
Ví dụ:
- Người dùng có quyền xem dữ liệu tài chính.
- Agent được phép tổng hợp báo cáo tài chính.
- Nhưng Agent không được phép chuyển tiền.
Hoặc:
- Monitoring Agent được phép sửa alert.
- Người dùng hiện tại chỉ là nhân viên đọc dashboard.
- Vì vậy yêu cầu sửa alert vẫn phải bị từ chối.
Ta không thể chỉ nhìn con người.
Cũng không thể chỉ nhìn Agent.
Quyền cuối cùng phụ thuộc vào sự giao nhau:
$$ Permission_{effective}
Permission_{user} \cap Permission_{agent} \cap Policy_{context} $$
Đây là công thức trực giác, không phải công thức Uber công bố.
Ý nghĩa của nó là quyền thực tế không nên lớn hơn quyền của bất kỳ mắt xích nào.
Người có quyền cao không được biến mọi Agent thành quản trị viên.
Agent có quyền mạnh cũng không được nâng quyền cho người không đủ thẩm quyền.
Một quản lý có chìa khóa két sắt không có nghĩa robot hút bụi của ông ấy cũng được mở két.
Ý định cũng có thể trở thành một phần của quyền
Danh tính trả lời:
Ai?
Nhưng Agent còn tạo ra một câu hỏi khác:
Để làm gì?
Cùng một tool read_logs, nhưng mục đích có thể khác nhau.
1Điều tra alert đang xảy ra
khác với:
1Thu thập toàn bộ log khách hàng để lưu vào file cá nhân
Uber thiết kế JWT theo hướng có thể mở rộng thêm các claim như session ID và request intent, để chính sách trong tương lai có thể đánh giá không chỉ caller cuối cùng mà cả ngữ cảnh đã được xác thực của workflow. (Uber)
Đây là bước chuyển từ phân quyền tĩnh sang phân quyền theo ngữ cảnh.
Ngày xưa policy có thể là:
1Agent A được gọi Tool B.
Ngày mai policy có thể trở thành:
1Agent A được gọi Tool B
2khi đang thay mặt người thuộc đội On-call,
3trong một incident đang mở,
4chỉ để đọc log của service liên quan,
5và phải yêu cầu con người xác nhận trước khi sửa cấu hình.
Policy dài hơn.
Nhưng cuộc đời vốn không đơn giản như bảng RBAC ba cột.
AI Gateway và MCP Gateway làm hai công việc khác nhau
Trong kiến trúc Uber, AI Gateway đứng giữa Agent và các mô hình AI bên ngoài hoặc nội bộ.
MCP Gateway đứng giữa Agent và công cụ nghiệp vụ.
1Agent
2 ├── AI Gateway → LLM
3 └── MCP Gateway → Tools / Services / Datastores
AI Gateway có thể xử lý:
- Prompt injection.
- Jailbreak.
- Content safety.
- PII redaction.
- Kiểm soát nhà cung cấp model.
MCP Gateway tập trung vào:
- Tool authorization.
- Data access.
- Policy enforcement.
- Downstream proxy.
- Audit hành động.
Uber mô tả AI Gateway là điểm tích hợp trung tâm cho các lời gọi tới model, kết hợp với AI Guard để phát hiện prompt injection, jailbreak, nội dung không an toàn và xử lý dữ liệu định danh cá nhân. (Uber)
Hai Gateway đều quan trọng.
Một bên bảo vệ thứ Agent nghĩ và đọc.
Một bên bảo vệ thứ Agent làm.
Con đường an toàn phải là con đường dễ đi nhất
Một kiến trúc bảo mật có thể rất đẹp trên PowerPoint.
Nhưng nếu mỗi lập trình viên phải tự:
- Gọi STS.
- Kiểm tra token.
- Truyền actor chain.
- Chọn audience.
- Refresh credential.
- Ghi audit.
- Xử lý retry.
- Kiểm tra expiry.
thì sớm muộn cũng có người bỏ qua vài bước.
Không hẳn vì họ xấu.
Có thể chỉ vì deadline vào chiều thứ Sáu.
Uber gọi hướng giải quyết là xây paved path, tức con đường đã được lát sẵn.
Họ phát triển A2A client chuẩn trên giao thức Agent-to-Agent, tự động thực hiện STS token exchange và truyền actor chain, để cách triển khai an toàn cũng trở thành cách triển khai dễ nhất. Các Agent cũ được chuyển đổi dần sang client chuẩn này. (Uber)
A2A là giao thức mở cho phép các Agent độc lập khám phá khả năng, giao nhiệm vụ và phối hợp với nhau; nó bổ sung cho MCP, vốn tập trung nhiều hơn vào kết nối Agent với công cụ. (A2A Protocol)
Đây là một bài học bảo mật rất thực tế:
Đừng chỉ viết quy định yêu cầu mọi người đi đúng đường. Hãy lát đường đúng rộng hơn, sáng hơn và dễ đi hơn đường tắt.
Nếu đường an toàn cần 50 dòng code, còn đường không an toàn chỉ cần một requests.post(), ta đang kỳ vọng đạo đức chiến thắng sự lười biếng mỗi ngày.
Đó là một chiến lược khá lạc quan.
Observability: Xem lại cả hành trình của Agent
Khi đã giữ được actor chain, hệ thống observability có thể hiển thị cả workflow:
1User: phamduytung
2 │
3 ├── On-call Agent
4 │ └── đọc alert
5 │
6 ├── Investigation Agent
7 │ ├── đọc log
8 │ └── đọc metric
9 │
10 └── Monitoring Agent
11 └── tạo Pull Request
Mỗi bước có thể đi kèm:
- Thời gian.
- Agent identity.
- User identity.
- Tool được gọi.
- Policy decision.
- Kết quả
ALLOWEDhoặcDENIED. - Security context.
- Session.
- Request intent.
Uber xây hệ thống observability để theo dõi actor chain từ người khởi tạo qua nhiều Agent đến các tool invocation, giúp quy trách nhiệm và xem lại quyết định authorization theo thời gian thực. (Uber)
Đây là điểm rất quan trọng khi xử lý sự cố.
Không chỉ hỏi:
API nào bị gọi?
Mà còn:
Chuỗi suy luận và ủy quyền nào đưa request tới đó?
Khi Agent tự lập kế hoạch, trace không còn chỉ là công cụ đo latency.
Nó trở thành bản ghi trách nhiệm.
Bảo mật thêm từng bước có làm Agent chậm đi không?
Có.
Mỗi lần token exchange đều cần:
- Gọi STS.
- Xác thực workload.
- Kiểm tra Agent Registry.
- Ký token.
- Trả token.
- Xác minh token ở bên nhận.
Nếu một workflow có hàng chục Agent và tool call, vài mili giây ở mỗi bước có thể cộng lại.
Uber cho biết kiến trúc đã được hàng nghìn Agent nội bộ sử dụng, và P99 latency của API token exchange trong số liệu họ công bố duy trì dưới 40 mili giây ở mức tải hiện tại. (Uber)
Con số này không nên được xem là lời hứa cho mọi hệ thống.
Hạ tầng, topology mạng, thuật toán ký, cache và mức tải của mỗi doanh nghiệp khác nhau.
Điều đáng học là Uber đo chi phí bảo mật như một phần của sản phẩm.
Bảo mật không miễn phí.
Nhưng thiếu bảo mật cũng không miễn phí.
Một hệ thống tốt không giả vờ trade-off không tồn tại.
Nó đo và quản lý trade-off đó.
Ba tầng bảo mật cho thế giới Agent
Uber định hướng hệ thống Agent IAM theo ba tầng.
Tầng 1: Identity and Trust Foundation
Tạo danh tính mật mã cho mỗi Agent.
Giữ chuỗi ủy quyền từ con người tới Agent và tool.
Đây là móng nhà.
Chưa biết ai đang hành động thì chưa thể viết policy tốt.
Tầng 2: Dynamic Access Control
Quyền truy cập thay đổi theo:
- Người khởi tạo.
- Agent.
- Tool.
- Session.
- Mức rủi ro.
- Ý định.
- Kết quả trung gian.
- Human-in-the-loop.
Thay vì cấp một quyền cố định rồi để đó ba năm.
Tầng 3: Unified Enforcement Plane
Một mặt phẳng chính sách thống nhất cho:
- Quan sát.
- Audit.
- Governance.
- Policy decision.
- Tool enforcement.
- Nhiều giao thức và workflow.
Uber cho rằng mô hình permission tĩnh do con người quản lý và các điểm thực thi rời rạc sẽ khó mở rộng trong một thế giới có nhiều Agent hoạt động với tốc độ máy. (Uber)
Theo mình, cách chia này rất hợp lý.
Không thể bắt đầu bằng policy AI cực kỳ thông minh khi Agent còn chưa có giấy tờ.
Đầu tiên phải biết ai.
Sau đó mới quyết định được làm gì.
Cuối cùng mới thống nhất cách giám sát và thực thi trên toàn hệ thống.
Nếu tự xây cho doanh nghiệp, mình sẽ bắt đầu như thế nào?
Không cần ngày đầu tiên xây một hệ thống phức tạp ngang Uber.
Nhưng có thể bắt đầu bằng các lớp rõ ràng.
1Human Identity Provider
2 │
3 ▼
4 Agent Platform
5 │
6 ├── Agent Registry
7 ├── Workload Identity
8 ├── STS / Token Exchange
9 └── Session Context
10 │
11 ▼
12 Agent Runtime
13 │
14 ├── A2A Client
15 ├── AI Gateway
16 └── MCP Gateway
17 │
18 ▼
19 Internal Services / Data
1. Mỗi Agent phải có một Agent ID riêng
Không dùng tên workload thay Agent ID.
Một workload có thể chạy nhiều Agent.
Một Agent cũng có thể được triển khai trên nhiều instance.
Cần phân biệt:
1workload_id
2agent_id
3agent_version
4owner
5environment
2. Gắn Agent với workload đáng tin cậy
Agent không được tự khai nơi mình đang chạy.
Có thể dùng workload identity như SPIFFE/SPIRE hoặc cơ chế tương đương của nền tảng cloud.
Mục tiêu là loại bỏ credential được hardcode càng nhiều càng tốt.
3. Dùng token ngắn hạn theo audience
Không phát một token mở được mọi service.
Mỗi request quan trọng nên nhận token phù hợp với đích và scope cụ thể.
4. Giữ cả user identity lẫn agent identity
Log tối thiểu nên trả lời được:
1Human: ai khởi tạo?
2Agent: logic nào hành động?
3Workload: chạy ở đâu?
4Tool: gọi cái gì?
5Session: thuộc công việc nào?
6Decision: vì sao được phép?
5. Đặt policy ở Gateway
MCP Gateway không chỉ route request.
Nó cần:
- Authenticate.
- Authorize.
- Redact.
- Rate limit.
- Audit.
- Yêu cầu approval khi cần.
6. Chuẩn hóa SDK
Không bắt từng đội tự phát minh cơ chế truyền token.
Đưa token exchange, trace và actor chain vào thư viện mặc định.
7. Bắt đầu từ tool rủi ro cao
Không cần bảo vệ mọi tool bằng cùng một quy trình từ ngày đầu.
Ưu tiên:
- Write database.
- Payment.
- Source control.
- Production configuration.
- Customer data.
- Email hàng loạt.
- Quyền quản trị.
Những tool chỉ đọc tài liệu công khai có thể dùng policy nhẹ hơn.
Những sai lầm rất dễ gặp
Dùng chung service account cho mọi Agent
Log không còn ý nghĩa.
Thu hồi quyền một Agent cũng kéo theo tất cả Agent khác.
Tin agent_id do client tự gửi
Một header:
1X-Agent-ID: payment-agent
không phải bằng chứng danh tính.
Nó chỉ là một câu tự giới thiệu.
Truyền token người dùng xuyên suốt workflow
Downstream không phân biệt được người dùng trực tiếp hành động hay Agent đang đại diện.
Phạm vi credential cũng dễ bị mở rộng ngoài dự kiến.
Token không có audience
Token bị lấy ở Agent A có thể được phát lại cho service B.
Token sống quá lâu
Sự cố nhỏ biến thành cửa hậu dài hạn.
Chỉ log Agent cuối cùng
Khi cần điều tra, toàn bộ provenance trước đó biến mất.
Đưa mọi thứ vào JWT
JWT không nên trở thành vali chứa toàn bộ prompt, dữ liệu khách hàng và lịch sử suy luận.
Token cần đủ ngữ cảnh cho policy, nhưng không nên phình thành kho dữ liệu nhạy cảm di động.
Gateway chỉ làm reverse proxy
Đổi tên Nginx thành MCP Gateway không tự tạo ra bảo mật Agent.
Cấp quyền dựa trên danh tính nhưng bỏ qua hành động
Agent được phép gọi một tool không có nghĩa mọi tham số truyền vào tool đều an toàn.
1read_file("/public/manual.pdf")
khác rất xa:
1read_file("/payroll/salary.xlsx")
Authorization cần nhìn tới resource và action cụ thể.
Không có human-in-the-loop
Một số hành động nên dừng trước cửa cuối cùng để con người xác nhận:
- Chuyển tiền.
- Xóa dữ liệu.
- Gửi email hàng loạt.
- Merge code quan trọng.
- Thay đổi production.
- Thu hồi quyền người dùng.
AI có thể chuẩn bị.
Không nhất thiết phải tự bấm nút.
Điều mình tâm đắc nhất: Danh tính thực ra là ký ức của trách nhiệm
Ban đầu, mình nghĩ bài viết này nói về JWT.
SPIFFE.
STS.
MCP Gateway.
Token Exchange.
Nhưng đọc kỹ hơn, mình thấy nhân vật chính không phải một giao thức nào.
Nó là ký ức.
Một hệ thống có trách nhiệm phải nhớ:
- Ai đã bắt đầu?
- Ai được giao việc?
- Công việc đã đi qua những Agent nào?
- Mỗi Agent quyết định gì?
- Tool nào được gọi?
- Policy nào cho phép?
- Hành động cuối cùng phục vụ mục đích gì?
Nếu những thông tin đó bị rơi rụng sau mỗi bước, hệ thống càng tự động hóa thì càng mất trí nhớ.
Và một cỗ máy có quyền lực nhưng không có ký ức là thứ khá đáng sợ.
Nó có thể làm đúng 999 lần.
Đến lần thứ 1.000 làm sai, không ai biết phải bắt đầu điều tra từ đâu.
Identity không chỉ là cách đăng nhập.
Nó là sợi chỉ buộc các hành động lại thành một câu chuyện có người chịu trách nhiệm.
Agent càng thông minh, quyền càng phải nhỏ và rõ
Có một nghịch lý.
Khi Agent còn ngu, ta ít dám giao quyền.
Khi Agent thông minh hơn, ta bắt đầu giao thêm:
- Email.
- Source code.
- Database.
- CRM.
- ERP.
- Payment.
- Production.
Nhưng khả năng reasoning tốt hơn không tự động làm hệ thống an toàn hơn.
Một Agent thông minh có thể thực hiện sai lầm phức tạp hơn.
Một prompt injection thành công có thể khiến nó sử dụng đúng công cụ, đúng API và đúng credential để làm một việc hoàn toàn sai mục đích.
Vì vậy, Agent càng mạnh thì identity, scope, policy và audit càng phải rõ.
Không phải vì không tin AI.
Mà vì chúng ta không giao quyền vô hạn cho bất kỳ thực thể nào.
Kể cả con người.
Tổng kết
Một người dùng gõ một câu.
Một Agent đọc câu đó.
Nó lập kế hoạch.
Gọi một Agent khác.
Agent thứ hai đọc log.
Gọi Agent thứ ba.
Agent thứ ba sửa cấu hình.
MCP Gateway kiểm tra quyền.
Source Control nhận Pull Request.
CI chạy test.
Tất cả diễn ra trong vài giây.
Trên màn hình, người dùng chỉ thấy:
1Đã xử lý xong.
Nhưng phía sau bốn chữ đó là một chuỗi hành động thật.
CPU đã chạy.
Token đã được ký.
Policy đã được đánh giá.
Dữ liệu đã được đọc.
Một file đã bị thay đổi.
Có thể cả hệ thống production vừa chuyển sang một trạng thái mới.
Không có gì là hoàn toàn ảo.
Và cũng không có hành động số nào nên hoàn toàn vô danh.
Điều đáng học từ Uber không phải là mọi doanh nghiệp phải sao chép nguyên kiến trúc của họ.
Điều đáng học là một nguyên tắc đơn giản:
Mỗi Agent cần có danh tính riêng, mỗi lần ủy quyền cần để lại dấu vết, và mỗi hành động quan trọng phải trả lời được ai đang làm, thay mặt ai, với quyền nào và vì mục đích gì.
Trước khi AI được phép bước vào kho dữ liệu, hãy cấp cho nó giấy khai sinh.
Trước khi giao chìa khóa, hãy ghi rõ chìa đó mở cửa nào.
Trước khi cho nó gọi một Agent khác, hãy giữ lại tên người đã bắt đầu câu chuyện.
Bởi vì trong tương lai, điều đáng sợ nhất có thể không phải là một AI làm sai.
Mà là một AI làm sai trong một hệ thống nơi mọi log đều nói:
1Một service nào đó đã thực hiện hành động.
Không ai biết nó là ai.
Không ai nhớ ai đã giao việc.
Và chiếc chìa khóa vẫn còn nằm trong tay nó.
Tham khảo
- Uber Engineering – Solving the Identity Crisis for AI Agents, Matt Mathew, Prasad Borole, Meng Huang và cộng sự, ngày 21/05/2026. (Uber)
- IETF – RFC 8693: OAuth 2.0 Token Exchange. (RFC Editor)
- SPIFFE – Secure Production Identity Framework for Everyone. (Spiffe)
- IETF WIMSE – Workload Identity in Multi-System Environments. (datatracker.ietf.org)
- Agent2Agent Project – A2A Protocol. (github.com)
Bình luận