aws-samples/sample-cedar-agentic-ai-authorization
GitHub: aws-samples/sample-cedar-agentic-ai-authorization
该项目使用 Cedar 策略语言在 AWS 上为多智能体 AI 委托链提供三层最小权限授权机制,防止智能体在跨层级委托时发生用户身份与权限滥用。
Stars: 2 | Forks: 0
# 使用 Cedar 在多智能体 AI 链中强制执行最小权限授权
## 简介
使用在 AWS 上部署的开源授权策略语言 [Cedar](https://www.cedarpolicy.com/),在多智能体 AI 委托链中强制执行最小权限授权。解决 [OWASP 智能体应用 Top 10](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications/) ASI03:身份与权限滥用问题,该问题指智能体会通过委托身份提升权限,执行超出发起用户授权范围的操作。符合 [NIST AI 智能体标准倡议](https://www.nist.gov/caisi/ai-agent-standards-initiative)关于授权和访问委托的支柱要求。
当智能体将任务委托给其他智能体时,传统的 RBAC 仅检查智能体本身的身份,而不检查发起请求的人类用户。低权限用户可以通过智能体委托链触发高权限操作(例如删除记录、处理付款)。本系统使用 Cedar 策略在三个层级上强制执行授权,通过 HMAC-SHA256 在委托跳转中不可变地传播原始用户上下文,并为每次授权决策生成 OCSF 99001 审计事件。
## 架构

*图 1:多智能体 AI 委托链的端到端授权架构。*
Cedar 负责评估授权,但不负责建立身份。在 Cedar 评估 `context.originating_user.role` 或 `context.originating_user.mfa_verified` 之前,必须由受信任的身份验证层建立用户身份并生成可验证的声明。步骤 1-3 负责身份验证;步骤 4-10 负责授权。
### 身份验证(步骤 1-3)
1. 发起用户通过兼容 OIDC 的身份提供商进行身份验证(在此参考实现中,为启用 TOTP MFA 的 Amazon Cognito)。IdP 签发一个包含 `sub`、`role`、`amr`(身份验证方法)和 `session_id` 等声明的已签名 JWT。
2. Amazon Cognito 将已签名的 JWT 返回给用户。
3. 用户将 JWT 和任务请求传递给 AI 智能体(MCP 客户端)。智能体在 MCP `_meta` 信封中携带原始用户上下文。
### 授权流水线(步骤 4-10)
4. AI 智能体向 AWS WAF 发送模型上下文协议 (MCP) 请求,AWS WAF 使用 CommonRuleSet、SQLiRuleSet、速率限制和主体大小限制进行过滤。
5. Amazon API Gateway(带有 Amazon Cognito 授权方)根据用户池的公钥验证 JWT 签名,并拒绝无效或过期的 token。有效请求被转发到 MCP 协议适配器 Lambda 函数,该函数应用 Amazon Bedrock Guardrails 内容过滤。
6. 适配器从 token 中提取已验证的声明,并将其映射到 Cedar 上下文属性:
- JWT `role` 声明 → `context.originating_user.role`
- JWT `amr` 包含 MFA 方法 → `context.originating_user.mfa_verified = true`
- JWT `sub` → `context.originating_user.user_id`
- JWT `sid` → `context.originating_user.session_id`
- JWT `amr` 声明 → `context.originating_user.authentication_method`
然后,适配器使用 AWS Secrets Manager 中的密钥,对用户上下文(按规范顺序的 `user_id`、`role`、`mfa_verified`、`authentication_method` 和 `session_id`)计算 HMAC-SHA256 签名。
7. 适配器构造已签名的请求信封,并调用 Cedar 评估器 Lambda 函数。
8. 评估器验证 HMAC-SHA256 签名,从 Amazon Verified Permissions 检索 L2 和 L3 Cedar 策略,并评估所有三个层级(L1、L2 和 L3),遇到首次拒绝 (deny) 时即停止评估。
9. 评估器向 Amazon CloudWatch Logs 发送开放网络安全架构 (OCSF) 99001 审计事件。发送失败的事件会转入 Amazon SQS 死信队列 (DLQ)。
10. Amazon CloudWatch 仪表板和告警监控评估延迟、拒绝率和 DLQ 深度。告警通知通过 Amazon SNS 路由。
### 跨委托跳转的上下文完整性
两种互补的机制用于保护跨跳转的 identity:
- **HMAC-SHA256** 确保完整性和真实性。每个下游评估器在信任上下文之前都会验证此签名。链中的任何智能体都无法篡改发起用户的属性。
- **OAuth 2.0 Token 交换 (RFC 8693)** 使用代表 (OBO) 模式设置委托范围。当编排器委托给下游智能体时,它将原始 token 交换为具有作用域的 OBO token,该 token 记录了谁代表谁行事以及拥有何种权限。Token 交换将每个下游智能体限制为仅能操作被委托任务的范围,而不是传递完整的原始 token。我们建议在企业部署中将 token 交换与 HMAC 结合使用。
## 三层 Cedar 策略模型
| 层级 | 检查内容 | 主体到资源 |
|-------|---------------|----------------------|
| L1 - 智能体到工具 | 调用智能体是否具有足够的信任分数 (1-5)、是否属于正确的 namespace(例如 "payments")以及是否处于 "production" 生命周期阶段 | 智能体到工具 |
| L2 - 智能体到智能体的委托 | 委托跳转次数是否在 5 次的硬性限制内,以及请求的任务是否是目标智能体已注册功能的子集 | 智能体到智能体 |
| L3 - 发起用户授权 | 发起链的人类用户是否具有所需角色(例如 "admin")、是否已完成 MFA 以及是否在允许的委托深度内 | 智能体到工具(上下文中的用户) |
只有当所有三层都返回 PERMIT 时,请求才被允许。评估在遇到第一个 DENY 时停止。
### 第 1 层(智能体到工具)
此策略仅当满足三个条件时才允许 finance-agent 调用 process_payment 工具:智能体的信任分数至少为 3、它属于 "payments" namespace,并且它部署在 "production" 生命周期阶段。
```
// L1-001: Finance agent can invoke payment tools
permit(
principal == AgentAuthz::Agent::"finance-agent",
action == AgentAuthz::Action::"invoke_tool",
resource == AgentAuthz::Tool::"process_payment"
) when {
principal.trust_level >= 3 &&
principal.namespace == "payments" &&
principal.lifecycle_stage == "production"
};
```
### 第 2 层(智能体到智能体的委托)
强制执行深度限制和功能约束。仅当委托链为 3 跳或更少,且请求的功能是 data-bot 已注册功能的子集时,编排器智能体才将任务委托给 data-bot。单独的禁止策略 (L2-004) 强制执行 5 跳的硬性系统范围限制。
```
// L2-002: Orchestrator can delegate to data agent
permit(
principal == AgentAuthz::Agent::"orchestrator",
action == AgentAuthz::Action::"delegate_task",
resource == AgentAuthz::Agent::"data-bot"
) when {
context.delegation_depth <= 3 &&
context.target_capabilities.containsAll(context.requested_capabilities)
};
```
### 第 3 层(发起用户授权)
保持智能体作为主体,但策略会评估 `context.originating_user` 以验证发起请求的人类用户。如果没有这一层,具有正确功能的智能体可能会调用破坏性工具,而不论是谁发起了请求。
```
// L3-001: High-risk tool (delete_records) requires admin with MFA
permit(
principal == AgentAuthz::Agent::"data-bot",
action == AgentAuthz::Action::"invoke_tool",
resource == AgentAuthz::Tool::"delete_records"
) when {
context.originating_user.role == "admin" &&
context.originating_user.mfa_verified == true &&
context.delegation_depth <= 2
};
```
**关键设计点:** 主体仍然是智能体,而不是用户实体。用户的角色和 MFA 状态通过上下文属性进行检查,从而将 schema 限制为两种实体类型和两种操作。
## 智能体拓扑和属性
| 实体 | 类型 | trust_level | namespace | lifecycle_stage | registered_capabilities |
|--------|------|-------------|-----------|-----------------|------------------------|
| orchestrator | Agent | 5 | orchestration | production | delegate_task, route_request |
| finance-agent | Agent | 3 | payments | production | process_payment, refund |
| data-bot | Agent | 4 | data | production | query_records, delete_records |
| 工具 | namespace | risk_level |
|------|-----------|-----------|
| process_payment | payments | medium |
| delete_records | data | high |
| query_records | data | low |
## 测试场景
### 场景 A:第 3 层强制执行 (DENY)
一名支持角色用户(无 MFA)通过 orchestrator → data-bot 请求删除记录。
| 层级 | 决策 | 原因 |
|-------|----------|--------|
| L1: 智能体到工具 | PERMIT | data-bot 的信任级别为 4,namespace 为 data,生命周期为 production |
| L2: 智能体到智能体 | PERMIT | Orchestrator 被授权委托给 data-bot,深度在限制范围内 |
| L3: 发起用户 | **DENY** | 用户角色为 support,而非 admin;MFA 未验证 |
| **总体** | **DENY** | 拒绝层:L3 |
如果没有第 3 层,此请求仅根据智能体的功能就会被允许。
### 场景 B:已授权的管理员请求 (PERMIT)
一名具有 MFA 的管理员用户通过相同的链请求相同的操作。
| 层级 | 决策 | 原因 |
|-------|----------|--------|
| L1 | PERMIT | 智能体属性匹配 |
| L2 | PERMIT | 委托路径已授权 |
| L3 | PERMIT | 角色为 admin,MFA 已验证,深度 ≤ 2 |
| **总体** | **PERMIT** | 三层均允许 |
### 场景 C:委托深度限制 (DENY)
一名具有 MFA 的管理员请求相同的操作,但委托链有 6 次跳转。
| 层级 | 决策 | 原因 |
|-------|----------|--------|
| L1 | PERMIT | 智能体属性匹配 |
| L2 | **DENY** | 深度 6 超过了 5 的硬性限制 |
| **总体** | **DENY** | 拒绝层:L2(L3 未评估) |
即使是已授权的管理员也无法绕过委托深度约束。
## 前置条件
- Python 3.12 或更高版本
- Node.js 20 或更高版本(用于 CDK CLI)
- AWS CDK CLI (`npm install -g aws-cdk`)
- 已进行 CDK 引导的 AWS 账户 (`cdk bootstrap`)
- 具有针对 Lambda、API Gateway、Amazon Verified Permissions、AWS Secrets Manager、Amazon VPC 和 Amazon CloudWatch 的作用域 IAM 策略权限的 AWS 凭证
- Amazon Bedrock Guardrail ID(在 Amazon Bedrock 控制台中创建)
## 设置
```
cd cedar-deputy-guard
python3 -m venv .venv
source .venv/bin/activate
```
安装核心依赖项:
```
pip install -r requirements.txt
```
安装开发依赖项:
```
pip install -r requirements-dev.txt
```
## 运行测试
```
# 单元 + property + integration + load 测试
.venv/bin/python -m pytest tests/ -v
# Cedar policy 测试(独立的 conftest)
.venv/bin/python -m pytest cedar/tests/ -v
# 仅 property 测试(9 个 correctness properties,每个 100 次迭代)
.venv/bin/python -m pytest tests/property/ -v
# 仅 load 测试
.venv/bin/python -m pytest tests/load/ -v -s
```
## 部署
```
# 打包 Lambda 依赖项(Linux x86_64 wheels)
source .venv/bin/activate
bash scripts/bundle_lambda.sh
# 部署所有 stacks(请将值替换为您自己的)
cdk deploy --all --require-approval never \
-c account_id=YOUR_ACCOUNT_ID \
-c guardrail_id=YOUR_BEDROCK_GUARDRAIL_ID
# 或者按顺序单独部署
cdk deploy KmsStack -c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk deploy VerifiedPermissionsStack -c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk deploy LambdaStack -c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk deploy SecurityLakeStack -c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk deploy MonitoringStack -c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
```
部署完成后,验证堆栈:
```
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE \
--query "StackSummaries[?contains(StackName,'Stack')].StackName" --output table
# 请注意 LambdaStack 输出中的 API Gateway endpoint
aws cloudformation describe-stacks --stack-name LambdaStack \
--query "Stacks[0].Outputs[?OutputKey=='ApiEndpoint'].OutputValue" --output text
```
## 针对已部署 API 的 E2E 测试
```
# 从 LambdaStack 输出中设置 API endpoint
export API_ENDPOINT=$(aws cloudformation describe-stacks --stack-name LambdaStack \
--query "Stacks[0].Outputs[?OutputKey=='ApiEndpoint'].OutputValue" --output text)
# 针对线上 API 运行 E2E 测试
.venv/bin/python -m pytest tests/e2e/ -v -s
```
## 清理
```
# 按反向依赖顺序销毁 stacks
cdk destroy MonitoringStack SecurityLakeStack --force \
-c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk destroy LambdaStack --force \
-c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk destroy VerifiedPermissionsStack --force \
-c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
cdk destroy KmsStack --force \
-c account_id=YOUR_ACCOUNT_ID -c guardrail_id=YOUR_GUARDRAIL_ID
# 删除保留的 log groups(RETAIN removal policy 会阻止自动删除)
aws logs delete-log-group --log-group-name /cedar-evaluator/audit
aws logs delete-log-group --log-group-name /cedar-evaluator/api-access
# 删除保留的 Secrets Manager secret
aws secretsmanager delete-secret --secret-id agent-authz/signing-key \
--force-delete-without-recovery
```
验证清理是否完成:
```
cdk list # Should return no stacks
aws logs describe-log-groups --log-group-name-prefix /cedar-evaluator/ \
--query "logGroups[*].logGroupName" --output text
# 应返回空
```
## 项目结构
```
cedar-deputy-guard/
├── app.py # CDK app entry point (5 stacks)
├── cdk.json # CDK context values
├── stacks/
│ ├── kms_stack.py
│ ├── verified_permissions_stack.py
│ ├── lambda_stack.py
│ ├── security_lake_stack.py
│ ├── monitoring_stack.py
│ └── pipeline_stack.py # Optional CI/CD, not part of the core five stacks
├── constructs/
│ ├── cedar_policy_store.py
│ ├── mcp_adapter_lambda.py
│ ├── cedar_evaluator_lambda.py
│ ├── audit_logger.py
│ ├── context_signer.py
│ ├── kms_encryption_key.py
│ ├── waf_web_acl.py
│ └── cognito_auth.py
├── lambda/
│ ├── mcp_adapter/
│ │ ├── handler.py
│ │ ├── mcp_parser.py
│ │ ├── envelope_builder.py
│ │ ├── context_signer.py
│ │ └── guardrails_client.py
│ ├── cedar_evaluator/
│ │ ├── handler.py
│ │ ├── policy_evaluator.py
│ │ ├── signature_verifier.py
│ │ └── audit_emitter.py
│ └── shared/
│ ├── types.py
│ ├── envelope_schema.py
│ └── ocsf_event_builder.py
├── cedar/
│ ├── policies/
│ │ ├── layer1-agent-to-tool/
│ │ ├── layer2-agent-to-agent/
│ │ └── layer3-originating-user-auth/
│ └── schema/
│ ├── cedar-entity-schema.json
│ └── cedar-context-schema.json
└── tests/
├── unit/
├── property/
├── integration/
├── load/
└── e2e/
```
## 正确性属性
系统使用 [Hypothesis](https://hypothesis.readthedocs.io/) 基于属性的测试验证了 9 项形式化正确性属性:
| # | 属性 | 验证目标 |
|---|----------|-----------|
| 1 | L1 智能体到工具策略的正确性 | 需求 1.1 |
| 2 | L2 委托策略的正确性 | 需求 1.2 |
| 3 | L3 发起用户授权的正确性 | 需求 1.3 |
| 4 | 三层逻辑与及拒绝识别 | 需求 1.4, 1.5 |
| 5 | 用户上下文提取的完整性 | 需求 2.1 |
| 6 | HMAC-SHA256 签名往返及篡改检测 | 需求 2.3, 2.4 |
| 7 | 委托深度递增不变性 | 需求 2.5 |
| 8 | OCSF 审计事件完整性 | 需求 4.1, 4.2 |
| 9 | MCP 解析生成有效信封 | 需求 5.2 |
## NIST SP 800-53 合规性映射
客户有责任评估此实现是否满足其合规要求。
| NIST 控制 | 控制名称 | 参考实现如何解决该控制 |
|-------------|-------------|----------------------------------------------|
| AC-4 | 信息流强制执行 | 用户上下文通过 HMAC 签名的信封不可变地流动 |
| AC-6 | 最小权限 | 三层评估同时要求智能体功能和用户角色 |
| AC-6(1) | 授权访问安全功能 | 第 3 层中的高风险工具需要 MFA |
| AC-6(5) | 特权账户 | 破坏性操作仅限于已验证 MFA 的管理员 |
| AU-2 | 事件记录 | 每次评估都记录为 OCSF 99001 |
| AU-3 | 审计记录内容 | 事件包含身份、链、操作、资源、决策和延迟 |
| SI-10 | 信息输入验证 | 评估前验证 HMAC;入站应用 Amazon Bedrock Guardrails |
| IA-2(1) | 多因素身份验证 | 第 3 层对高风险操作强制执行 MFA |
| SC-12 | 加密密钥管理 | Manager 中的签名密钥支持轮换 |
| SC-28 | 静态信息保护 | Verified Permissions 中的策略实施 STRICT 验证 |
## 安全加固
- **AWS KMS:** 带有自动轮换的客户托管密钥用于加密 Secrets Manager、CloudWatch Logs、Amazon SQS DLQ 和 Amazon SNS
- **AWS WAF:** 包含 CommonRuleSet、SQLiRuleSet、速率限制(每 5 分钟 100 次请求)和主体大小限制(8KB)的 WebACL
- **Amazon Cognito:** 要求 TOTP MFA、具有严格密码策略的 User Pool,用于人类操作员身份验证
- **Amazon VPC 隔离:** 两个 Lambda 函数均在带有 NAT 网关的私有子网中运行(无公共互联网入站流量)
- **HMAC 完整性:** 发起用户上下文使用 HMAC-SHA256 签名;验证器支持具有 24 小时宽限期的密钥轮换
## 扩展到多账户环境
在中央安全账户中部署 Cedar 策略存储,并使用跨账户 IAM 角色允许工作负载账户调用 `verifiedpermissions:IsAuthorized`。使用 AWS Organizations 服务控制策略 (SCP) 防止工作负载账户创建自己的策略存储。为了在整个组织中标准化用户身份属性,请考虑使用 IAM Identity Center 或集中式 OIDC 提供商向您的工作负载账户发布一致的声明。
对于生产部署,请考虑使用以下内容扩展此模式:
- 针对临界拒绝的**人工介入升级**
- 用于防止跨租户访问的**多租户 Cedar 策略隔离**
- 用于在无需重新部署的情况下紧急关闭工具的**Amazon S3 支持的动态策略热重载**
## 参考
- [Cedar 策略语言文档](https://docs.cedarpolicy.com/)
- [Amazon Verified Permissions 用户指南](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/)
- [OWASP 智能体应用 Top 10](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications/)
- [智能体 AI 系统的四大安全原则](https://aws.amazon.com/blogs/security/four-security-principles-for-agentic-ai-systems/)
- [OAuth 2.0 Token 交换 (RFC 8693)](https://datatracker.ietf.org/doc/html/rfc8693)
- [NIST AI 智能体标准倡议](https://www.nist.gov/caisi/ai-agent-standards-initiative)
- [NIST SP 800-53 Rev. 5](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final)
- [OCSF schema 文档](https://schema.ocsf.io/)
## 许可证
MIT-0 许可证。见 [LICENSE](LICENSE)。
标签:AI安全, AWS, Chat Copilot, DPI, 人工智能, 多智能体, 授权策略, 用户模式Hook绕过, 身份与访问控制, 逆向工具