Quản lý quyền truy cập của tác nhân AI bằng Okta Cross App Access và Amazon Bedrock AgentCore – Phần 1

Tóm lược nhanh
Tổng hợp và đối chiếu bởi gemini-2.0-flash-thinking-exp
“Một tác nhân AI cập nhật phiếu hoặc đọc hồ sơ khách hàng sẽ thay mặt một người, bên trong các ứng dụ”
Các điểm cốt lõi
- 1.Một tác nhân AI cập nhật phiếu hoặc đọc hồ sơ khách hàng sẽ thay mặt một người, bên trong các ứng dụng mà người đó có thể tiếp cận.
- 2.Sau đó, nhóm nhận dạng của bạn phải trả lời một câu hỏi mà các tài khoản dịch vụ chia sẻ và đồng ý OAuth trên mỗi ứng dụng vẫn để ngỏ: tác nhân nào có thể hành động cho người dùng nào trong ứng dụng nào và cách bạn dừng tác nhân đó.
- 3.Okta Cross App Access (XAA) trả lời câu hỏi đó trong nhà cung cấp danh tính (IdP) của bạn.
Một tác nhân AI cập nhật phiếu hoặc đọc hồ sơ khách hàng sẽ thay mặt một người, bên trong các ứng dụng mà người đó có thể tiếp cận. Sau đó, nhóm nhận dạng của bạn phải trả lời một câu hỏi mà các tài khoản dịch vụ chia sẻ và đồng ý OAuth trên mỗi ứng dụng vẫn để ngỏ: tác nhân nào có thể hành động cho người dùng nào trong ứng dụng nào và cách bạn dừng tác nhân đó. Okta Cross App Access (XAA) trả lời câu hỏi đó trong nhà cung cấp danh tính (IdP) của bạn. Bạn đăng ký đại lý ở Okta, quản trị viên phê duyệt các ứng dụng mà nó có thể tiếp cận và Okta đánh giá chính sách mỗi khi đại lý yêu cầu hành động thay mặt người dùng. Trong các thử nghiệm của chúng tôi, sau khi quản trị viên xóa nhiệm vụ của người dùng cho tổng đài viên, Okta đã từ chối các yêu cầu mới của đại lý dành cho người dùng đó trong vòng khoảng 1 giây và các mã thông báo đã phát hành sẽ hết hạn trong vòng 5 phút. Amazon Bedrock AgentCore là một nền tảng để xây dựng, kết nối và tối ưu hóa các tác nhân trên quy mô lớn, với bất kỳ khung hoặc mô hình nào. Giải pháp này sử dụng hai khả năng của nó để thực hiện quyết định của Okta trên AWS. Thời gian chạy Amazon Bedrock AgentCore, một khả năng của Amazon Bedrock AgentCore, xác nhận sự cấp phép của Okta. Amazon Bedrock AgentCore Identity, một khả năng của Amazon Bedrock AgentCore, đổi lấy mã thông báo truy cập ngắn hạn với thông tin xác thực mà mã đại lý của bạn không nhìn thấy và giữ mã thông báo đó trong kho mã thông báo của nó. Trong các thử nghiệm của chúng tôi, AgentCore Identity đã thêm khoảng 0,6 giây vào một yêu cầu mất khoảng 30 giây từ đầu đến cuối. Trong bài đăng này, bài đầu tiên trong số hai bài đăng này, bạn xây dựng một tác nhân tác vụ trên thời gian chạy AgentCore hoạt động cho người dùng đã đăng nhập thông qua XAA và AgentCore Identity. Bạn định cấu hình các phần AgentCore Identity mà nó cần, thực thi quyền của từng người dùng trong các công cụ và xem những gì chúng tôi đo được: mỗi lần kiểm tra từ chối những gì, các phương pháp chúng tôi đã giải quyết và các biện pháp kiểm soát của Okta có hiệu lực nhanh như thế nào. Sau đó, Phần 2 sẽ đưa ra cách quản trị tương tự cho Amazon Bedrock AgentCore Gateway, khả năng của Amazon Bedrock AgentCore, với các chính sách của Cedar, tác nhân thứ hai trên Amazon Elastic Kubernetes Service (Amazon EKS) và quy trình kiểm tra trong Amazon CloudWatch. Tổng quan về giải pháp Okta là mặt phẳng quản trị: nó quyết định tác nhân nào có thể hành động cho người dùng nào, chống lại tài nguyên nào. AgentCore Identity là mặt phẳng thực thi: nó chứa thông tin xác thực của tác nhân, biến quyết định của Okta thành mã thông báo mà tài nguyên chấp nhận và giữ cả hai danh tính trong mã thông báo đó. Trong Hình 1, tác nhân và hai máy chủ Giao thức ngữ cảnh mô hình (MCP) mà nó gọi đều chạy trên thời gian chạy AgentCore.
Hình 1: Cấu trúc giải pháp, với các con số khớp với các bước tiếp theo
Mỗi yêu cầu mang ba mã thông báo và mỗi yêu cầu ghi lại một quyết định khác nhau: mã thông báo ID cho biết người dùng là ai, Cấp phép xác nhận danh tính JWT (ID-JAG) là quyết định của Okta và mã thông báo truy cập là những gì tài nguyên chấp nhận. Một yêu cầu diễn ra như thế này:
Người dùng đăng nhập vào giao diện người dùng web, phần phụ trợ cho giao diện người dùng (BFF), bằng OpenID Connect thông qua ứng dụng Okta được liên kết của đại lý. Đối với mỗi yêu cầu, BFF trao đổi mã thông báo ID của người dùng lấy ID-JAG tại máy chủ ủy quyền tổ chức của Okta, được xác thực là tác nhân (trao đổi mã thông báo RFC 8693). Okta kiểm tra xem tác nhân có đang hoạt động hay không, người dùng có được chỉ định cho tác nhân đó không và quản trị viên đã kết nối tác nhân đó với máy chủ ủy quyền mục tiêu cho các phạm vi được yêu cầu hay chưa. ID-JAG chỉ sử dụng một lần và hết hạn sau 5 phút. BFF gọi tác nhân trong thời gian chạy AgentCore với ID-JAG làm mã thông báo mang của nó. Người ủy quyền JWT của thời gian chạy chỉ chấp nhận ID-JAG mà Okta cấp cho tác nhân này. Thời gian chạy nhận được mã thông báo truy cập khối lượng công việc từ AgentCore Identity để liên kết danh tính khối lượng công việc của tác nhân với người dùng và chuyển nó tới mã tác nhân. Mã thông báo truy cập khối lượng công việc này là mã thông báo liên kết nội bộ của AWS: cả Okta và tài nguyên đều không nhìn thấy nó, vì vậy nó không phải là một trong ba mã thông báo. Nhân viên yêu cầu AgentCore Identity cung cấp mã thông báo truy cập. AgentCore Identity đổi ID-JAG tại máy chủ ủy quyền tùy chỉnh Okta của tài nguyên với cấp ủy quyền JWT (RFC 7523), được xác thực là đại lý. Okta trả về mã thông báo truy cập 5 phút đặt tên cho cả người dùng và tác nhân, đồng thời chứa các nhóm của người dùng. Tác nhân gọi máy chủ MCP bằng mã thông báo đó. Trình quản lý tác vụ kiểm tra xem tác nhân đã đăng ký có lấy được nó hay không, nhóm và phạm vi của người dùng có cho phép công cụ này hay không.
Hình 2 cho thấy yêu cầu tương tự như một trình tự, với sự kiểm tra mà mỗi bên thực hiện.
Hình 2: Chuỗi ba mã thông báo và quá trình kiểm tra mà mỗi bên thực hiện, với mã thông báo truy cập khối lượng công việc ở bước 4 nằm trong AWS
Điều kiện tiên quyết Để làm theo, bạn cần những điều sau đây:
Điều kiện tiên quyết Những gì chúng tôi đã sử dụng
Tài khoản AWS có quyền truy cập vào Amazon Bedrock AgentCore và mô hình Anthropic Claude trong Amazon Bedrock Miền Tây Hoa Kỳ (Oregon)
Một tổ chức Okta có quyền truy cập ứng dụng chéo cho các tác nhân AI và Quản lý quyền truy cập API (máy chủ ủy quyền tùy chỉnh) Tổ chức có gói miễn phí của Okta Integrator
Python, Giao diện dòng lệnh AWS (AWS CLI), boto3, AgentCore CLI và AgentCore Python SDK, khả năng của Amazon Bedrock AgentCore Python 3.11, AWS CLI phiên bản 2, boto3 1.43, AgentCore CLI 0.31.1 và AgentCore Python SDK 1.24.1
Quyền quản lý quyền truy cập và nhận dạng AWS (IAM) Quyền tạo tài nguyên AgentCore và vai trò IAM
Quá trình hướng dẫn mất khoảng 1 giờ. AgentCore tính phí cho những gì bạn sử dụng. Xem giá Amazon Bedrock AgentCore. Cơ sở cho giải pháp này là chuỗi ủy quyền mẫu 08-okta-xaa-xaa của AWS trong kho lưu trữ mẫu AgentCore trên GitHub và bạn có thể xây dựng giải pháp trong bài đăng này bên trên giải pháp đó. Ngoài mẫu đó, các đoạn mã và cấu hình trong bài đăng này hiển thị mẫu về mặt khái niệm. Chúng không phải là một giải pháp hoàn chỉnh và có thể triển khai được. Mã này là mã mẫu để sử dụng cho mục đích phi sản xuất, vì vậy hãy làm việc với nhóm bảo mật và pháp lý của bạn để đáp ứng các yêu cầu về bảo mật, quy định và tuân thủ của tổ chức trước khi bạn triển khai mã. Đăng ký đại lý ở Okta Okta cần một máy chủ ủy quyền cho tài nguyên, tác nhân, kết nối giữa chúng và chính sách thừa nhận sự cấp phép của tác nhân. Thực hiện tất cả các bước này trong Bảng điều khiển dành cho quản trị viên Okta: đăng ký đại lý sẽ tạo ứng dụng được liên kết của nó, do đó bạn không cần trình hướng dẫn tích hợp ứng dụng.
Tạo máy chủ ủy quyền tùy chỉnh cho ứng dụng tài nguyên với đối tượng api://task-manager và phạm vi tùy chỉnh xaa:read và xaa:write. Chỉ yêu cầu phạm vi tùy chỉnh của tài nguyên: Okta từ chối yêu cầu ID-JAG bao gồm các phạm vi OpenID Connect như openid hoặc profile (invalid_scope), do đó, yêu cầu cần ít nhất một phạm vi tùy chỉnh và không có phạm vi OpenID Connect. Thêm xác nhận quyền sở hữu nhóm vào mã thông báo truy cập của nhóm đó, được lọc theo các nhóm bắt đầu bằng xaa-. Tuyên bố này mang lại quyền hạn của mỗi người dùng đối với các công cụ. Trong Bảng điều khiển dành cho quản trị viên, đi tới Thư mục > Tác nhân AI, chọn Đăng ký tác nhân AI rồi Đăng ký thủ công, tùy ý chỉ định chủ sở hữu và tạo ứng dụng OpenID Connect được liên kết. Khi đăng ký Khách hàng, chọn Bí mật khách hàng, tạo bí mật rồi kích hoạt đại lý. Tác nhân và ứng dụng chia sẻ một ID khách hàng và ứng dụng đó phải đăng nhập người dùng của bạn: mã thông báo ID từ một ứng dụng khác không trao đổi được với "ứng dụng khách chưa được đăng ký để ủy quyền cho tác nhân này". Trên tab Kết nối tài nguyên của tác nhân, hãy kết nối nó với máy chủ ủy quyền, giới hạn ở phạm vi mà nó cần, như Hình 3 hiển thị. Thêm quy tắc chính sách truy cập vào máy chủ ủy quyền tùy chỉnh cho phép cấp JWT Bearer của đại lý, với thời gian tồn tại của mã thông báo truy cập là 5 phút. Nếu không có loại cấp phép, trao đổi thứ hai sẽ không thành công với no_matching_policy và giới hạn thời gian tồn tại mà ủy quyền bị thu hồi sẽ tiếp tục hoạt động trong bao lâu. Chỉ định người dùng hoặc nhóm có thể hành động thông qua tác nhân. Họ đăng nhập thông qua ứng dụng được liên kết, vì vậy hãy cung cấp cho ứng dụng đó chính sách đăng nhập ứng dụng để thừa nhận họ bằng trình xác thực mà họ đã đăng ký. Trong tổ chức hộp cát của chúng tôi, ứng dụng được liên kết có chính sách riêng với quy tắc dành cho nhóm thử nghiệm. Đối với người dùng thực, hãy áp dụng chính sách của tổ chức bạn, bao gồm cả xác thực đa yếu tố.
Hình 3: Kết nối tài nguyên của tác nhân tác vụ trong Okta, giới hạn ở phạm vi xaa:read và xaa:write
Hướng dẫn Truy cập ứng dụng chéo của Okta bao gồm các bước của bảng điều khiển và tập lệnh chuỗi ủy quyền 08-okta-xaa-delegation-chain mẫu của AWS cho máy chủ ủy quyền và chính sách mang JWT của nó. BFF sau đó yêu cầu ID-JAG, được xác thực là tác nhân:
BÀI ĐĂNG /oauth2/v1/mã thông báo HTTP/1.1 Máy chủ: YOUR-ORG.okta.com Ủy quyền: Cơ bản Loại nội dung: application/x-www-form-urlencoded
Grant_type=urn:ietf:params:oauth:grant-type:token-exchange &requested_token_type=urn:ietf:params:oauth:token-type:id-jag &chủ đề_token= &subject_token_type=urn:ietf:params:oauth:token-type:id_token &audience=https://YOUR-ORG.okta.com/oauth2/YOUR-CUSTOM-AS-ID &scope=xaa:đọc xaa:viết
Mẫu AWS 06-okta-xaa gửi yêu cầu tương tự bằng Python (agent/xaa_client.py). BFF xác thực với tư cách là tác nhân, do đó, hãy lưu trữ bí mật máy khách của tác nhân trong AWS Secrets Manager thay vì trong tệp mã hoặc cấu hình. Thiết lập danh tính AgentCore AgentCore Identity nắm giữ ba điều cho giải pháp này và mã đại lý của bạn không nhìn thấy bí mật ứng dụng khách hoặc gọi điểm cuối mã thông báo của Okta:
Một phần của bản sắc AgentCore Nó chứa cái gì Ai tạo ra nó
Nhận dạng khối lượng công việc Danh tính của tác nhân trên AWS, được liên kết với người dùng đã đăng nhập cho mỗi yêu cầu Thời gian chạy AgentCore, cho mỗi thời gian chạy của tác nhân
Nhà cung cấp thông tin xác thực OAuth2 ID và bí mật khách hàng Okta của đại lý cũng như quyền sử dụng Bạn, một lần cho mỗi đại lý Okta
Kho tiền mã thông báo Mã thông báo truy cập mà nhà cung cấp nhận được Nhận dạng AgentCore
Tạo nhà cung cấp thông tin xác thực Nhà cung cấp thông tin xác thực thực hiện trao đổi thứ hai. Trỏ nó vào máy chủ ủy quyền tùy chỉnh, xác thực nó là tác nhân AI và đặt quyền cấp thay mặt cho JWT_AUTHORIZATION_GRANT, mà AgentCore Identity gửi với tư cách là người mang jwt với ID-JAG làm xác nhận:
control = boto3.client("bedrock-agentcore-control") nhà cung cấp = control.create_oauth2_credential_provider( name="okta-xaa-obo", credentialProviderVendor="CustomOauth2", oauth2ProviderConfigInput={"customOauth2ProviderConfig": { "oauthDiscovery": {"discoveryUrl": f"{OKTA_ORG}/oauth2/{CUSTOM_AS_ID}/.well-known/openid-configuration"}, "clientId": AGENT_CLIENT_ID, # ID khách hàng Okta của tác nhân AI "clientSecret": AGENT_CLIENT_SECRET, # AgentCore Identity lưu trữ nó trong AWS Secrets Manager "Phương thức xác thực khách hàng": "CLIENT_SECRET_BASIC", "onBehalfOfTokenExchangeConfig": {"grantType": "JWT_AUTHORIZATION_GRANT"}, }}, ) nhà cung cấp_arn = nhà cung cấp ["credentialProviderArn"]
Okta liên kết cả hai sàn giao dịch với khách hàng có tên trong ID-JAG, vì vậy mỗi đại lý Okta cần có nhà cung cấp riêng: khi chúng tôi đổi ID-JAG của một đại lý thành một đại lý khác, Okta đã từ chối với “‘client_id’ trong JWT Bearer Grant phải khớp với ‘client_id’ được sử dụng để xác thực khách hàng.” AgentCore Identity giữ bí mật trong bí mật của Trình quản lý bí mật AWS do dịch vụ quản lý mà bạn xoay vòng với update-oauth2-credential-provider. Nếu nhóm của bạn đã quản lý bí mật ứng dụng khách trong Trình quản lý bí mật thì thay vào đó, bạn có thể tham chiếu ARN của bí mật đó. AgentCore Identity đọc bí mật của máy khách từ đó, do đó bạn có thể xoay vòng bí mật mà không cần cập nhật nhà cung cấp (xem Tham khảo các bí mật của Trình quản lý bí mật AWS của riêng bạn trong Amazon Bedrock AgentCore Identity). Để tránh bí mật được chia sẻ, thay vào đó hãy xác thực bằng khóa riêng. Xem Xác thực bằng khóa riêng JWT bằng Amazon Bedrock AgentCore Identity. Hình 4 hiển thị nhà cung cấp trong bảng điều khiển AgentCore.
Hình 4: Nhà cung cấp thông tin xác thực xác thực là đại lý được cấp quyền JWT
Sử dụng danh tính khối lượng công việc mà thời gian chạy AgentCore quản lý Thời gian chạy AgentCore tạo và quản lý danh tính khối lượng công việc cho từng thời gian chạy tác nhân. Khi một yêu cầu vượt qua người ủy quyền JWT của thời gian chạy, thời gian chạy sẽ nhận được mã thông báo truy cập khối lượng công việc cho danh tính khối lượng công việc đó cũng như nhà phát hành và chủ đề của mã thông báo gửi đến, đồng thời chuyển nó tới mã của bạn. Sau đó, AgentCore Identity sử dụng ID-JAG đằng sau nó làm xác nhận cho việc trao đổi. SDK AgentCore Python giữ mã thông báo truy cập khối lượng công việc trong BedrockAgentCoreContext, không phải trong tiêu đề yêu cầu mà điểm truy cập của bạn nhận được. Phiên bản đầu tiên của chúng tôi đã tìm kiếm nó trong các tiêu đề, không tìm thấy gì và quay lại lệnh gọi GetWorkloadAccessTokenForJWT của chính nó với nhận dạng khối lượng công việc thứ hai, trên tất cả 21 yêu cầu mà chúng tôi đã kiểm tra. Thay vào đó hãy đọc nó từ ngữ cảnh:
từ nhập bedrock_agentcore.runtime BedrockAgentCoreContext
danh tính = boto3.client("bedrock-agentcore")
def okta_access_token() -> str: khối lượng công việc_token = BedrockAgentCoreContext.get_workload_access_token() # được tạo ra bởi thời gian chạy trả về danh tính.get_resource_oauth2_token( khối lượng công việcIdentityToken=workload_token, ResourceCredentialProviderName="okta-xaa-obo", phạm vi=["xaa:read", "xaa:write"], # phải bằng phạm vi của ID-JAG oauth2Flow="ON_BEHALF_OF_TOKEN_EXCHANGE", )["accessToken"]
AgentCore Identity giữ mã thông báo truy cập trong kho mã thông báo cho phần còn lại của yêu cầu. Qua 10 yêu cầu, cuộc gọi đầu tiên của nhân viên hỗ trợ đã đổi ID-JAG trong khoảng nửa giây (xem bảng độ trễ trong Xác thực kết quả) và cuộc gọi thứ hai, đối với máy chủ MCP khác, đã trả lại cùng một mã thông báo trong khoảng thời gian trung bình là 58 mili giây mà không đổi lại ID-JAG sử dụng một lần. ID-JAG mới cho cùng một người dùng sẽ nhận được mã thông báo mới, vì vậy mỗi yêu cầu đều phản ánh quyết định mới nhất của Okta. Chuỗi ủy quyền mẫu 08-okta-xaa-đọc mã thông báo truy cập khối lượng công việc theo cách tương tự (agent/agent.py). Phạm vi vai trò của tổng đài viên đối với danh tính khối lượng công việc và nhà cung cấp của nó AgentCore Identity không ràng buộc danh tính khối lượng công việc với các nhà cung cấp thông tin xác thực trong cùng một tài khoản. Vai trò IAM của tổng đài viên thực hiện, do đó, hãy xác định phạm vi của nó đối với danh tính và nhà cung cấp khối lượng công việc của chính tổng đài viên cũng như bí mật của nhà cung cấp đó:
[ { "Sid": "OktaOnBehalfOf", "Hiệu ứng": "Cho phép", "Hành động": "bedrock-agentcore:GetResourceOauth2Token", "Tài nguyên": [ "arn:aws:bedrock-agentcore:us-west-2:123456789012:workload-identity-directory/default", "arn:aws:bedrock-agentcore:us-west-2:123456789012:workload-identity-directory/default/workload-identity/RUNTIME-WORKLOAD-IDENTITY", "arn:aws:bedrock-agentcore:us-west-2:123456789012:token-vault/default", "arn:aws:bedrock-agentcore:us-west-2:123456789012:token-vault/default/oauth2credentialprovider/okta-xaa-obo" ] }, { "Sid": "ReadProviderSecret", "Hiệu ứng": "Cho phép", "Hành động": "secretmanager:GetSecretValue", "Tài nguyên": "arn:aws:secretsmanager:us-west-2:123456789012:secret:bedrock-agentcore-identity!default/oauth2/okta-xaa-obo-*" } ]
Lấy tên nhận dạng khối lượng công việc từ khối lượng công việcIdentityDetails trong GetAgentRuntime và ARN của nhà cung cấp từ credentialProviderArn: phân đoạn là oauth2credentialprovider và với biểu mẫu có dấu gạch nối, mọi lệnh gọi đều không thành công với AccessDeniedException. Vai trò này không cần có quyền GetWorkloadAccessToken vì bộ thực thi nhận được mã thông báo đó chứ không phải tác nhân. Các bài kiểm tra của chúng tôi đã vượt qua chỉ với hai tuyên bố này. Triển khai tác nhân trên thời gian chạy AgentCore Định cấu hình trình ủy quyền gửi đến của thời gian chạy tác nhân để chỉ chấp nhận ID-JAG mà Okta cấp cho tác nhân này. Nhà phát hành của nó là máy chủ ủy quyền tổ chức của Okta và đối tượng của nó là máy chủ ủy quyền tùy chỉnh của tài nguyên. Trong Agentcore.json:
"authorizerType": "CUSTOM_JWT", "authorizerConfiguration": { "customJwtAuthorizer": { "discoveryUrl": "https://YOUR-ORG.okta.com/.well-known/openid-configuration", "allowedAudience": ["https://YOUR-ORG.okta.com/oauth2/YOUR-CUSTOM-AS-ID"], "được phépKhách hàng": ["YOUR_AGENT_CLIENT_ID"], "allowedScopes": ["xaa:read", "xaa:write"] } }
allowClients khớp với xác nhận client_id mà ID-JAG mang theo. Nếu không có nó, bộ thực thi đã thừa nhận ID-JAG của một tác nhân khác với HTTP 200 và yêu cầu sau đó không thành công tại sàn giao dịch. Với nó, bộ thực thi đã từ chối mã thông báo đó bằng HTTP 401. Ngoài chính sách ở phần trước, vai trò thực thi cần có nền tảng:InvokeModel và nền tảng:InvokeModelWithResponseStream. Nó không cần quyền bedrock-agentcore:InvokeAgentRuntime đối với các máy chủ MCP: mỗi máy chủ chạy trên thời gian chạy AgentCore đằng sau trình ủy quyền JWT riêng của nó, với máy chủ ủy quyền tùy chỉnh là nhà phát hành và api://task-manager là đối tượng, do đó, tác nhân gọi nó bằng mã thông báo truy cập Okta làm mã thông báo mang, không phải với AWS Signature Phiên bản 4 (SigV4). Thực thi quyền của mỗi người dùng trong máy chủ MCP Kết nối tài nguyên đặt phạm vi cho mọi người dùng của một tác nhân, do đó, cả ba người dùng thử nghiệm đều nhận được xaa:read xaa:write và thay vào đó, quyền hạn của mỗi người dùng trong yêu cầu của nhóm: Mã thông báo của Alice mang theo xaa-reader, xaa-writer của Bob và Carol không có. Trình quản lý tác vụ kiểm tra hai điều: nó chỉ chấp nhận mã thông báo mà tác nhân đã đăng ký nhận được và nó chỉ cho phép ghi khi cả nhóm và phạm vi đều có mặt:
REGISTERED_AGENTS = {"YOUR_AGENT_CLIENT_ID"}
def _require_agent() -> Không có: Claims = _decode_claims() # Người ủy quyền JWT của thời gian chạy đã xác thực mã thông báo tác nhân = (claim.get("act") hoặc {}).get("sub") nếu tác nhân trong REGISTERED_AGENTS và Claims.get("cid") == tác nhân: trở lại raise ToolError("không đủ_đặc quyền: máy chủ này chỉ chấp nhận các token đã đăng ký " "Đại lý AI có được thông qua quyền truy cập ứng dụng chéo Okta")
def _require_write() -> Không có: _require_agent() nếu WRITERS_GROUP trong _groups() và "xaa:write" trong _scopes(): trở lại raise ToolError(f"infull_privileges: công cụ này yêu cầu phải là thành viên trong '{WRITERS_GROUP}'")
Cả hai lần kiểm tra đều thu hẹp các khoảng trống mà chúng tôi đã tìm thấy: một kiểm tra ghi cho phép mã thông báo không có yêu cầu nhóm cho phép Carol, người không thuộc nhóm nào, tạo nhiệm vụ và trước _require_agent một mã thông báo trao đổi mã thông báo đơn giản, được cấp cho một ứng dụng dịch vụ không có yêu cầu hành động, đã tạo một nhiệm vụ cho Bob. Máy chủ có thể đọc các xác nhận quyền sở hữu mà không cần xác minh lại mã thông báo chỉ vì người ủy quyền JWT của thời gian chạy đã xác minh nó. Máy chủ không có người ủy quyền phía trước phải kiểm tra chữ ký, nhà phát hành, đối tượng và thời hạn sử dụng, giống như tác nhân Phần 2 trên Amazon EKS thực hiện. Xác thực kết quả Chúng tôi đã tiến hành mọi kiểm tra đối với giải pháp đã triển khai. Alice, Bob và Carol mỗi người yêu cầu nhân viên tạo một nhiệm vụ và sau đó liệt kê các nhiệm vụ của dự án:
Người gọi tạo_task danh sách_tasks
Alice Bị từ chối: yêu cầu thành viên trong xaa-writers Được phép
Bob Đã tạo Được phép
Carol Bị từ chối: không có nhóm nào xác nhận quyền sở hữu Được phép
Bob, rồi Alice ngay sau anh ấy Được tạo cho Bob, sau đó bị từ chối cho Alice: không có quyền nào được chuyển giao Được phép
Các yêu cầu này đã dừng trước khi công cụ chạy:
Yêu cầu Đã dừng lại phản hồi
ID-JAG của Đặc vụ B được gửi cho đặc vụ Người ủy quyền JWT của thời gian chạy 401: “Xác nhận giá trị ‘client_id’ không khớp với cấu hình.”
ID-JAG được giữ trong 245 giây Người ủy quyền JWT của thời gian chạy 401: “Mã thông báo không có hiệu lực, sẽ hết hạn trong phút tiếp theo”
Mã thông báo mang không đúng định dạng Người ủy quyền JWT của thời gian chạy 403: “Không thể phân tích mã thông báo”
Một ID-JAG được đổi hai lần Máy chủ ủy quyền tùy chỉnh của Okta 400: “Id-jag đã được sử dụng.”
Phạm vi hẹp hơn ở lần trao đổi thứ hai Máy chủ ủy quyền tùy chỉnh của Okta 400: “Tham số phạm vi phải khớp chính xác với phạm vi trong id-jag.”
Một phạm vi bên ngoài kết nối Máy chủ ủy quyền tổ chức của Okta 400 không hợp lệ_scope
Mã thông báo trao đổi mã thông báo đơn giản tại máy chủ MCP Máy chủ MCP Bị từ chối: chỉ các mã thông báo mà đại lý AI đã đăng ký nhận được
Mã thông báo mà AgentCore Identity trả về khớp với mã mà chúng tôi đã đổi trực tiếp tại Okta, yêu cầu bồi thường: phụ là người dùng, cid và hành động được đặt tên là tác nhân, scp giữ phạm vi kết nối, các nhóm giữ nhóm người dùng và nó tồn tại được 300 giây. AgentCore Identity mất khoảng 0,6 giây cho một yêu cầu kéo dài khoảng 30 giây từ đầu đến cuối, hầu hết là lệnh gọi mô hình và công cụ. Trung bình của năm lần chạy từ ứng dụng khách thử nghiệm của chúng tôi:
Gọi trung vị
Đăng nhập, theo kịch bản (luồng mã ủy quyền) 1.205 mili giây
Mã thông báo ID tới ID-JAG tại máy chủ ủy quyền tổ chức của Okta 216 mili giây
GetWorkloadAccessTokenForJWT 135 mili giây
GetResourceOauth2Token, bao gồm cả khoản trợ cấp mang JWT của Okta 508 mili giây
Cơ quan nhà nước đang hoạt động Okta đánh giá tác nhân, người dùng và kết nối khi tạo ID-JAG. Chúng tôi đã đo lường hành động của mỗi hành động của quản trị viên đối với yêu cầu tiếp theo và đối với mã thông báo đã phát hành:
Hành động của quản trị viên ở Okta Yêu cầu mới Token đã được phát hành
Xóa kết nối tài nguyên của đại lý Từ chối ngay lập tức (invalid_target) Làm việc cho đến khi hết hạn, tối đa 5 phút
Xóa nhiệm vụ của người dùng Từ chối trong vòng khoảng 1 giây, ngay cả khi người dùng đã giữ mã thông báo ID Tối đa 5 phút
Vô hiệu hóa đại lý Bị từ chối sau khi Okta chạy hoạt động mà tổ chức thử nghiệm của chúng tôi đã xếp hàng đợi trong 86 phút Tối đa 5 phút
Các hành động trên một tác nhân khiến tác nhân kia hoạt động. Okta không kiểm tra lại người dùng khi đổi ID-JAG: máy chủ ủy quyền tùy chỉnh của nó đã cấp mã thông báo truy cập 3 giây sau khi chúng tôi xóa người dùng, đối với ID-JAG được tạo trước khi xóa. Nhật ký hệ thống của Okta ghi lại từng khoản trợ cấp với đại lý là tác nhân và Phần 2 truyền các sự kiện đó vào CloudWatch. Các phương pháp hay nhất cho chuỗi ủy quyền Sáu cách thực hành được rút ra từ các phép đo này, mỗi cách thực hành là một đặc tính của chuỗi chứ không phải là một sở thích:
Thực hành Những gì chúng tôi đo được
Tạo ID-JAG mới cho mỗi yêu cầu ID-JAG chỉ sử dụng một lần và tồn tại trong 300 giây. Thời gian chạy từ chối một thời gian còn lại dưới 60 giây, vì vậy 225 giây hoạt động, 245 thì không
Thực hiện quyền của mỗi người dùng trong yêu cầu của nhóm và yêu cầu một phạm vi được đặt cho mỗi yêu cầu Okta đặt phạm vi từ kết nối tài nguyên, vì vậy cả ba người dùng đều có cùng phạm vi và trao đổi thứ hai phải yêu cầu chính xác ID-JAG
Ghim tác nhân trong thời gian chạy và kiểm tra hành động và cid trong công cụ allowClients khớp với yêu cầu client_id mà ID-JAG mang theo. Thay vào đó, mã thông báo truy cập Okta mang theo cid
Tái tạo một cuộc trao đổi thất bại trực tiếp với Okta Thông qua AgentCore Identity, cả phạm vi không khớp và ứng dụng khách sai đều xuất hiện khi "Trao đổi mã thông báo không thành công với trạng thái HTTP 400"
Cấp cho vai trò của đại lý quyền truy cập đọc vào bí mật của nhà cung cấp GetResourceOauth2Token không thành công cho đến khi vai trò có thể đọc được nó
Giữ thời gian tồn tại ngắn và sử dụng kết nối tài nguyên làm công tắc tiêu diệt của bạn Việc xóa kết nối có hiệu lực ngay lập tức. Việc vô hiệu hóa tác nhân nằm trong hàng đợi API tác nhân AI beta của Okta trong 86 phút mà không bị hủy
Quyền truy cập ứng dụng chéo so với trao đổi mã thông báo đơn giản Trao đổi mã thông báo RFC 8693 đơn giản cũng mang theo danh tính của người dùng. Chúng tôi đã so sánh nó với XAA với cùng một máy chủ và người dùng ủy quyền Okta:
Hành vi chúng tôi quan sát được Trao đổi token đơn giản Truy cập ứng dụng chéo
Nhận dạng đại lý trong mã thông báo Không có yêu cầu hành động hành động đặt tên cho đại lý
Phạm vi Mở rộng: Mã thông báo của riêng Alice có xaa:read và sàn giao dịch trả về xaa:read xaa:write Phạm vi quản trị viên đã phê duyệt
Quy tắc trao đổi giới hạn cho xaa-writer Alice vẫn nhận được token Alice phủ nhận
Người dùng chưa được chỉ định, mã thông báo trước đó được sử dụng lại Vẫn trao đổi Từ chối
Quản trị viên thấy gì Một ứng dụng dịch vụ có loại trợ cấp Tác nhân, các kết nối của nó và tác nhân trong mỗi sự kiện nhật ký
Những kết quả này phản ánh cấu hình Okta của chúng tôi. Hướng dẫn của Okta hiển thị yêu cầu hành động đối với mã thông báo đã trao đổi mà chúng tôi không nhận được. Trao đổi mã thông báo đơn giản mang danh tính của người dùng nhưng không có quyền của người dùng. Trường hợp áp dụng mẫu này Chúng tôi làm việc với các công ty truyền thông và giải trí, và đây là lúc chúng tôi gặp vấn đề đầu tiên. Một studio hoặc tổ chức phát trực tuyến hoặc trò chơi điều hành các đại diện chống lại việc theo dõi sản xuất, siêu dữ liệu nội dung và tiêu đề, quyền và bản địa hóa cũng như hỗ trợ người xem hoặc người chơi. Mỗi hệ thống có mô hình ủy quyền và kiểm toán viên riêng, đồng thời quyền hạn của người dùng khác nhau tùy theo chức danh, lãnh thổ hoặc thời hạn phát hành, do đó, “đại lý nào có thể hành động cho người dùng nào trong hệ thống nào” phải được trả lời trước khi đại lý giao hàng. Không có gì trong chuỗi dành riêng cho ngành đó: tác nhân là danh tính trong IdP của bạn, mục tiêu là máy chủ ủy quyền OAuth 2.0 và quyền của người dùng dựa trên yêu cầu. Các nhóm dịch vụ tài chính, chăm sóc sức khỏe và khu vực công đặt các nguồn lực khác nhau vào cùng một biện pháp kiểm soát. Dọn dẹp Để tránh bị tính phí liên tục, hãy xóa tài nguyên bạn đã tạo:
Xóa ngăn xếp AWS CloudFormation mà AgentCore CLI đã tạo cho tác nhân và hai máy chủ MCP. Xóa nhà cung cấp thông tin xác thực bằng aws bedrock-agentcore-control delete-oauth2-credential-provider --name okta-xaa-obo và mọi danh tính khối lượng công việc mà bạn tự tạo bằng delete-workload-identity. Xóa chính sách IAM mà bạn đã thêm vào vai trò thực thi. Trong Okta, hãy hủy kích hoạt và xóa tác nhân AI cũng như ứng dụng được liên kết của nó, đồng thời xóa kết nối tài nguyên, quy tắc chính sách, phạm vi và yêu cầu của máy chủ ủy quyền cũng như người dùng và nhóm thử nghiệm.
Kết luận Trong bài đăng này, bạn đã sử dụng Quyền truy cập ứng dụng chéo Okta để quyết định tác nhân nào có thể hành động cho người dùng nào và AgentCore Identity để thực hiện từng quyết định. Thời gian chạy chỉ thừa nhận ID-JAG của chính tác nhân, nhà cung cấp thông tin xác thực đã đổi từng ID-JAG bằng một bí mật mà tác nhân không giữ, kho mã thông báo sử dụng lại kết quả trong một yêu cầu và máy chủ MCP thực thi quyền của từng người dùng từ yêu cầu của nhóm. Thiết kế này giữ vai trò trao đổi trong vai trò của tác nhân và lặp lại việc kiểm tra ủy quyền trong mọi máy chủ MCP. Xem Phần 2 của loạt bài này để tìm hiểu lý do tại sao thiết kế của nó lại chuyển sang sử dụng một Cổng AgentCore với các chính sách của Cedar, thêm tác nhân thứ hai trên Amazon EKS và tham gia Nhật ký hệ thống Okta với các dấu vết AgentCore trong CloudWatch. Để bắt đầu, hãy khám phá các mẫu AgentCore và tài liệu về Quyền truy cập ứng dụng chéo của Okta. Để biết chi tiết về API, hãy xem Trao đổi mã thông báo thay mặt trong Hướng dẫn dành cho nhà phát triển AgentCore.
Về các tác giả
Bản quyền & Xuất xứ thông tin
Bài viết này được tổng hợp và phân tích AI từ ấn phẩm AWS Machine Learning Blog. Mọi bản quyền nội dung thuộc về tác giả và toà soạn gốc.


