diff --git a/01-tutorials/identity/README.md b/01-tutorials/identity/README.md index bde7124..bc2e737 100644 --- a/01-tutorials/identity/README.md +++ b/01-tutorials/identity/README.md @@ -8,67 +8,67 @@ 与传统的微服务不同,真正的企业级 Agent 必须具备 **自主行动能力(Agency)**。而受制于模型能力,Agent 的行为又是不可预测的。这带来了三个核心挑战: -1. **入站安全 (Inbound Security) —— 谁能调用 Agent?** +1. **入站安全 (Inbound Security) —— 谁能调用 Agent?** * 常见的基于 API Key 的访问方式由于缺乏防重放机制,安全性低。 * 企业往往希望复用既有 IdP ,Agent 需要支持通过 SSO (如飞书) 方式验证用户身份,确保只有授权用户才能发起对话。 - -2. **出站安全 (Outbound Security) —— Agent 代表谁在操作?** + +2. **出站安全 (Outbound Security) —— Agent 代表谁在操作?** * **凭证泄露风险**:开发者习惯将 API Key 硬编码在 Agent 代码中,这是巨大的安全隐患。 * **权限越界**:当 Agent 访问飞书文档或数据库时,它应该拥有“上帝视角”,还是仅拥有“当前用户”的权限? * **身份传递**:如何让后端资源知道,这次调用是由“User A”授权“Agent B”发起的? -3. **细粒度权限管控 (Governance) —— 如何管控“黑盒”?** +3. **细粒度权限管控 (Governance) —— 如何管控“黑盒”?** * Agent 需要细粒度的策略控制,而不是一把梭的 `Admin` 权限。 * 企业 CISO 和安全团队需要知道 Agent 到底访问了什么资源。 ## Agent Identity 解决方案 Agent Identity 专为解决上述问题设计,它不是简单的 OAuth 包装,而是为智能体构建的一套完整的**身份治理基础设施**。 -![alt text](images/image.png) +![alt text](image.png) Agent Identity 把“用户 → 应用 → Agent → 资源”的链路拆开治理,并提供一套可复用的安全构件: -- **Inbound 认证**:对接企业现有 IdP(用户池 / OAuth / SSO 等),让“谁能调用 Agent”可配置、可审计。 -- **Agent 权威身份**:为 Agent 提供唯一、可验证的身份主体,便于策略绑定与审计归因。 -- **Outbound 凭证托管(Token Vault)**:把 OAuth / API Key 的存储、刷新、最小化授权从业务代码中剥离出来;默认做到“凭据不落地”。 -- **细粒度权限控制**:基于委托链(Delegation Chain)把“用户权限”和“Agent 权限”组合校验,默认拒绝、按需放开。 -- **可观测与审计**:把“谁在什么时候代表谁调用了哪个工具/资源”沉淀为审计事件,方便排障、合规与内控。 +**Inbound 认证**:对接企业现有 IdP(用户池 / OAuth / SSO 等),让“谁能调用 Agent”可配置、可审计。 +**Agent 权威身份**:为 Agent 提供唯一、可验证的身份主体,便于策略绑定与审计归因。 +**Outbound 凭证托管(Token Vault)**:把 OAuth / API Key 的存储、刷新、最小化授权从业务代码中剥离出来;默认做到“凭据不落地”。 +**细粒度权限控制**:基于委托链(Delegation Chain)把“用户权限”和“Agent 权限”组合校验,默认拒绝、按需放开。 +**可观测与审计**:把“谁在什么时候代表谁调用了哪个工具/资源”沉淀为审计事件,方便排障、合规与内控。 ## 实验列表 + | 实验 | 说明 | 目录 | -|------|------|------| -| **实验1: 用户池认证** | 使用用户池管控智能体访问 (Inbound 认证) | [tutorial-1-userpool-inbound](./tutorial-1-userpool-inbound/) | -| **实验2: 飞书联合登录** | 使用飞书账号作为企业身份源 (IdP 集成) | [tutorial-2-feishu-idp](./tutorial-2-feishu-idp/) | -| **实验3: 飞书文档访问** | 凭证托管实现安全访问飞书文档 (Outbound 凭证托管) | [tutorial-3-feishu-outbound](./tutorial-3-feishu-outbound/) | +| ------ | ------ | ------ | +| **实验1: 用户池认证** | 使用用户池管控智能体访问 (Inbound 认证) | [01_userpool_inbound](./01_userpool_inbound/) | +| **实验2: 飞书联合登录** | 使用飞书账号作为企业身份源 (IdP 集成) | [02_feishu_idp](./02_feishu_idp/) | +| **实验3: 飞书文档访问** | 配置 Agent 代表用户访问飞书文档 | [03_feishu_outbound](./03_feishu_outbound/) | ## 核心功能 -- **身份认证 (Inbound)**: 验证用户身份,只有授权用户才能访问 Agent -- **凭证托管 (Outbound)**: Agent 安全访问飞书等外部服务,凭证由平台管理 -- **权限控制**: 基于委托链的细粒度权限,控制 Agent 能访问的资源 - +**身份认证 (Inbound)**: 验证用户身份,只有授权用户才能访问 Agent +**凭证托管 (Outbound)**: Agent 安全访问飞书等外部服务,凭证由平台管理 +**权限控制**: 基于委托链的细粒度权限,控制 Agent 能访问的资源 ## 目录结构说明 -``` -identity/ +```bash +03-agentkit-identity/ ├── README.md # 本文件 -├── tutorial-1-userpool-inbound/ # 实验1: Inbound 认证 +├── 01_userpool_inbound/ # 实验1: Inbound 认证 │ ├── README.md # 教程文档 │ ├── main.py # 示例代码 │ ├── pyproject.toml # 依赖配置 -│ ├── .env.example # 环境变量模板 +│ ├── .env.template # 环境变量模板 │ └── assets/ # 截图和流程图 -├── tutorial-2-feishu-idp/ # 实验2: 飞书 IdP 联合登录 -│ ├── README.md -│ ├── main.py -│ ├── pyproject.toml -│ ├── .env.example -│ └── assets/ -└── tutorial-3-feishu-outbound/ # 实验3: Outbound 凭证托管 (进阶) +└── 02_feishu_idp/ # 实验2: 飞书 IdP 联合登录 ├── README.md ├── main.py ├── pyproject.toml - ├── .env.example + ├── .env.template + └── assets/ +└── 03_feishu_outbound/ # 实验3: 飞书文档访问 + ├── README.md + ├── main.py + ├── pyproject.toml + ├── .env.template └── assets/ ``` @@ -77,7 +77,7 @@ identity/ ### 前置准备 | 项目 | 说明 | -|------|------| +| ------ | ------ | | **火山控制台账号** | 需要 IDFullAccess、STSAssumeRoleAccess 权限的子账号 | | **Python 环境** | Python 3.12+ 及 [uv](https://docs.astral.sh/uv/) | | **飞书账号**(实验2/3) | 用于测试飞书登录和文档访问 | @@ -87,10 +87,10 @@ identity/ ```bash # 1. 克隆仓库 git clone https://github.com/volcengine/agentkit-samples.git -cd agentkit-samples/01-tutorials/identity +cd python/01-tutorials/03-agentkit-identity # 2. 选择实验目录 -cd tutorial-1-userpool-inbound # 或其他实验 +cd 01_userpool_inbound # 或其他实验 # 3. 配置环境变量 cp .env.example .env @@ -107,4 +107,26 @@ uv run veadk web 本教程所有示例均可通过 `uv run veadk web` 在本地运行。 -如需部署到 AgentKit Runtime,请参考 [AgentKit Runtime 文档](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html)。 \ No newline at end of file +如需部署到 AgentKit Runtime,请参考 [AgentKit Runtime 文档](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html)。 + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/01-tutorials/identity/tutorial-1-userpool-inbound/README.md b/01-tutorials/identity/tutorial-1-userpool-inbound/README.md index d8aec14..57fab6e 100644 --- a/01-tutorials/identity/tutorial-1-userpool-inbound/README.md +++ b/01-tutorials/identity/tutorial-1-userpool-inbound/README.md @@ -12,7 +12,7 @@ ### 没有认证会怎样? -**场景 1:裸奔的 Agent** +- **场景 1:裸奔的 Agent** ```mermaid flowchart LR @@ -23,22 +23,25 @@ flowchart LR ``` 后果: + - 有人写个脚本疯狂调用,你的 API 费用一夜爆炸 - 竞争对手拿你的 Agent 做逆向工程 - 出了安全事故,你不知道是谁干的 -**场景 2:Agent 不知道"你是谁"** +- **场景 2:Agent 不知道"你是谁"** 很多 Agent 需要根据用户身份提供个性化服务: + - 查"我的订单" —— 哪个"我"? - 访问"我的文档" —— 哪个"我"? - 执行敏感操作 —— 你有权限吗? 没有身份信息,Agent 要么拒绝服务,要么只能提供最基础的公开功能。 -**场景 3:审计和合规** +- **场景 3:审计和合规** 安全团队、CISO 会问你: + - 这个 Agent 谁在用? - 用了多少次? - 有没有异常调用? @@ -57,6 +60,7 @@ flowchart LR ``` 这就是 **Inbound(入站)认证** 要解决的事: + 1. **认证**:证明"你是你" 2. **授权**:确认"你能用" 3. **传递**:把身份信息带给 Agent @@ -66,7 +70,7 @@ flowchart LR 我们提供开箱即用的 **用户池** 方案: | 能力 | 说明 | -|------|------| +| ------ | ------ | | **统一用户目录** | 一个地方管理所有能访问 Agent 的用户 | | **标准协议** | OAuth2/OIDC,不用自己造轮子 | | **JWT Token** | 无状态认证,高性能,身份信息可传递给 Agent | @@ -106,7 +110,7 @@ flowchart TB - 选择登录属性:用户名 + 手机号 - 点击「确认」 -![新建用户池](images/image-2.png) + ![新建用户池](images/image-2.png) 3. **新建客户端** - 进入用户池详情 → 点击「新建客户端」 @@ -115,13 +119,13 @@ flowchart TB - 回调地址:`http://127.0.0.1:8000/api/v1/oauth2callback` - **记录 Client ID 和 Client Secret** -![新建客户端](images/image-3.png) + ![新建客户端](images/image-3.png) 4. **创建测试用户** - 在用户池中选择「用户管理」→「新建用户」 - 设置用户名和临时密码 -![创建测试用户](images/image-4.png) + ![创建测试用户](images/image-4.png) ### 步骤2: 配置环境变量 @@ -156,11 +160,11 @@ uv sync uv run veadk web ``` -服务启动后,访问 http://127.0.0.1:8000 +服务启动后,访问 ### 步骤4: 用户登录体验 -1. **访问应用** - 浏览器打开 http://127.0.0.1:8000 +1. **访问应用** - 浏览器打开 2. **跳转登录** - 自动跳转到用户池登录页面 3. **输入凭证** - 使用步骤1创建的用户登录 4. **首次修改密码** - 如有要求,设置新密码 @@ -195,8 +199,8 @@ flowchart LR --- - **关键点说明:** + - `veadk web` 命令自动读取环境变量中的 OAuth2 配置 - 所有请求都会验证 JWT Token - 未授权请求返回 401 错误 @@ -214,7 +218,7 @@ flowchart LR ## 常见问题 | 问题 | 解决方案 | -|------|----------| +| ------ | ------ | | 登录页面一直跳转 | 清除浏览器缓存,检查回调地址配置 | | Token 过期 | 默认 10 小时有效,可配置刷新机制 | | 忘记 Client Secret | 在控制台重新生成 | @@ -225,3 +229,25 @@ flowchart LR - [Agent Identity 产品文档](https://www.volcengine.com/docs/identity) - [VeADK 开发指南](https://volcengine.github.io/agentkit-sdk-python/) + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/01-tutorials/identity/tutorial-1-userpool-inbound/main.py b/01-tutorials/identity/tutorial-1-userpool-inbound/main.py index 6fd0589..bc0f6d1 100644 --- a/01-tutorials/identity/tutorial-1-userpool-inbound/main.py +++ b/01-tutorials/identity/tutorial-1-userpool-inbound/main.py @@ -74,6 +74,7 @@ # 本地测试入口(可选) # ============================================================ + async def test_agent(): """本地测试函数(绕过认证,仅用于开发调试)""" response = await runner.run( diff --git a/01-tutorials/identity/tutorial-2-feishu-idp/README.md b/01-tutorials/identity/tutorial-2-feishu-idp/README.md index 7ddcb7c..52969b9 100644 --- a/01-tutorials/identity/tutorial-2-feishu-idp/README.md +++ b/01-tutorials/identity/tutorial-2-feishu-idp/README.md @@ -7,11 +7,13 @@ 企业已经在使用飞书作为统一通讯和办公平台,员工都有飞书账号。现在要部署 AI 智能体,如何让员工使用飞书账号直接登录,而不是再创建一套新的账号? **传统方案的问题:** + - 每个系统维护独立用户库 → 用户需要记忆多套密码 - 用户离职/入职需要多个系统同步 → 管理成本高、遗漏风险 - 无法利用飞书的 MFA/安全策略 → 安全合规难以统一 **Agent Identity 解决方案:** + - 飞书作为身份源(IdP),用户池作为服务提供者(SP) - 一键登录,无需额外注册 - 继承飞书的安全策略和审计能力 @@ -19,7 +21,7 @@ ## 与实验1的区别 | 对比项 | 实验1 (用户池登录) | 实验2 (飞书联合登录) | -|--------|-------------------|---------------------| +| ------ | ------------------- | --------------------- | | 账号来源 | 用户池本地创建 | 飞书通讯录 | | 登录方式 | 用户名/密码 | 飞书授权 | | 适用场景 | 独立用户管理 | 企业统一身份 | @@ -58,7 +60,7 @@ sequenceDiagram ### 前置条件 - 完成实验1的用户池创建和客户端配置 -- 拥有飞书开放平台账号(https://open.feishu.cn/) +- 拥有飞书开放平台账号 [飞书开放平台](https://open.feishu.cn/) --- @@ -68,7 +70,7 @@ sequenceDiagram 访问 [飞书开放平台](https://open.feishu.cn/) → 点击「创建应用」 -![飞书开放平台](images/image.png) + ![飞书开放平台](images/image.png) 2. **创建企业自建应用** - 应用类型:企业自建应用 @@ -81,7 +83,7 @@ sequenceDiagram - **App ID**(客户端 ID) - **App Secret**(客户端密钥) -![获取应用凭证](images/image-1.png) + ![获取应用凭证](images/image-1.png) 4. **⚠️ 配置安全设置(最关键的一步!)** @@ -95,7 +97,8 @@ sequenceDiagram > 4. **直接复制该地址**,粘贴到飞书的「安全设置」中 回调 URL 格式类似: - ``` + + ```bash https://userpool-<用户池UID>.userpool.auth.id.cn-beijing.volces.com/login/generic_oauth/callback ``` @@ -104,14 +107,14 @@ sequenceDiagram > - 不要漏掉 `/login/generic_oauth/callback` 路径 > - URL 必须与控制台显示的完全一致,包括协议 `https://` -![配置安全设置](images/image-2.png) + ![配置安全设置](images/image-2.png) 5. **网页应用配置(可选,非必须)** 飞书可能提示配置「网页应用」,这是**可选的**: | 配置项 | 说明 | 是否必须 | - |--------|------|----------| + | -------- | ------ | ---------- | | 安全设置 → 重定向 URL | OAuth 回调地址 | ✅ 必须 | | 网页应用 → 桌面端主页 | 从飞书打开应用的地址 | ❌ 可选 | @@ -125,7 +128,7 @@ sequenceDiagram 进入「权限管理」→ 搜索并申请以下权限: | 权限 | 说明 | 是否必须 | - |------|------|----------| + | ------ | ------ | ---------- | | `contact:user.base:readonly` | 获取用户基本信息 | ✅ 必须 | | `contact:contact.base:readonly` | 获取通讯录基本信息 | ✅ 必须 | | `contact:user.employee_id:readonly` | 获取用户工号 | ❌ 可选 | @@ -135,7 +138,7 @@ sequenceDiagram > - **如果不申请这个权限,登录时会报错 `20027 当前应用未申请相关权限`** > - 两个必须权限缺一不可! -![添加权限](images/image-3.png) + ![添加权限](images/image-3.png) 7. **发布应用** @@ -158,8 +161,9 @@ sequenceDiagram 左侧菜单 →「外部身份供应商」→「添加供应商」 填写信息: + | 字段 | 值 | 说明 | - |------|------|------| + | ------ | ------ | ------ | | 供应商类型 | 飞书 | 选择飞书 | | 供应商名称 | feishu | 自定义名称 | | 客户端 ID | 步骤1获取的 App ID | 从飞书应用凭证复制 | @@ -205,9 +209,10 @@ uv run veadk web > **端口冲突?** 如果提示 `address already in use`,说明端口 8000 被占用。 > 运行以下命令清理: -> ```bash -> lsof -i :8000 | grep -v "^COMMAND" | awk '{print $2}' | xargs kill -9 -> ``` + +```bash +lsof -i :8000 | grep -v "^COMMAND" | awk '{print $2}' | xargs kill -9 +``` --- @@ -224,7 +229,7 @@ uv run veadk web ## 测试提示词 -``` +```bash 你好,我是通过飞书登录的,请介绍一下你自己 ``` @@ -239,7 +244,7 @@ uv run veadk web ### 错误速查表 | 错误码/现象 | 原因 | 解决方法 | -|-------------|------|----------| +| ------------- | ------ | ---------- | | `20029` redirect_uri 请求不合法 | 飞书安全设置中的重定向 URL 与实际请求不匹配 | 从用户池控制台复制正确的「重定向 URI」到飞书安全设置 | | `20027` 当前应用未申请相关权限 | 缺少 `contact:contact.base:readonly` 权限 | 在飞书权限管理中申请该权限,然后重新发布应用 | | 飞书登录按钮不显示 | 未在用户池配置外部身份供应商 | 在用户池添加飞书 IdP 配置 | @@ -281,6 +286,29 @@ uv run veadk web → [实验3: Outbound 凭证托管 - 让 Agent 安全访问飞书文档](../tutorial-3-feishu-outbound/) 在实验3中,你将学习: + - 如何让 Agent 获取用户授权的飞书 Token - 凭证托管的安全最佳实践 - 实现"凭证不落地"的 Outbound 访问模式 + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/01-tutorials/identity/tutorial-2-feishu-idp/main.py b/01-tutorials/identity/tutorial-2-feishu-idp/main.py index 331701e..d689676 100644 --- a/01-tutorials/identity/tutorial-2-feishu-idp/main.py +++ b/01-tutorials/identity/tutorial-2-feishu-idp/main.py @@ -86,6 +86,7 @@ # 本地测试入口(可选) # ============================================================ + async def test_agent(): """本地测试函数(绕过认证,仅用于开发调试)""" response = await runner.run( diff --git a/01-tutorials/identity/tutorial-3-feishu-outbound/README.md b/01-tutorials/identity/tutorial-3-feishu-outbound/README.md index 7f8a552..355cf0d 100644 --- a/01-tutorials/identity/tutorial-3-feishu-outbound/README.md +++ b/01-tutorials/identity/tutorial-3-feishu-outbound/README.md @@ -15,6 +15,7 @@ > 用户对 Agent 说:"帮我总结一下那个飞书文档的内容" > > Agent 需要访问用户的飞书文档,但是... +> > - **飞书 API 需要授权** > - **每个用户的授权是独立的** > - **凭证怎么安全管理?** @@ -22,7 +23,7 @@ ### 传统方案的问题 | 方案 | 问题 | -|------|------| +| ------ | ------ | | **硬编码凭证** | AK/SK 写在代码里,泄露风险极高 | | **共享凭证** | 所有用户用同一个 Token,无法追溯谁做了什么 | | **手动管理** | 每个用户单独管理 Token,运维成本爆炸 | @@ -54,7 +55,7 @@ flowchart LR ### 核心优势 | 特性 | 说明 | -|------|------| +| ------ | ------ | | **凭证不落地** | AK/SK 由平台统一管理,不在代码中出现 | | **用户级隔离** | 每个用户的飞书授权独立管理 | | **OAuth 自动化** | 首次使用引导授权,后续自动刷新 Token | @@ -109,7 +110,7 @@ sequenceDiagram ### 🔴 关键配置点 | 配置项 | 正确值 | 常见错误 | -|--------|--------|----------| +| ------ | ------ | ---------- | | **凭证提供者回调 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ❌ 错误地设为 Runtime URL(会导致 "Consumer authentication failed") | | **飞书安全设置重定向 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ❌ 只添加了本地开发 URL | | **飞书权限范围** | `drive:drive,docx:document:readonly,offline_access` | ❌ 使用 `openid` 等标准 OIDC scope(飞书不支持) | @@ -121,7 +122,7 @@ sequenceDiagram 本教程的 **Outbound 凭证托管** 功能依赖 **工作负载身份 (Workload Identity)**: | 环境 | 工作负载身份 | 凭证托管功能 | -|------|-------------|-------------| +| ------ | ------------- | ------------- | | 本地 veadk web | ⚠️ 需手动配置 | ✅ 可测试 | | AgentKit Runtime | ✅ 自动分配 | ✅ 完整支持 | @@ -147,11 +148,13 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ - 完成实验2的飞书应用创建(可复用) 2. **安装 AgentKit CLI** + ```bash pip install agentkit-cli ``` 3. **配置 AgentKit** + ```bash agentkit config --tos_bucket ``` @@ -177,16 +180,18 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ 进入「安全设置」→ 添加重定向 URL: > **重要:凭证托管使用不同的回调 URL!** - > ``` + > + > ```bash > https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback > ``` -![alt text](images/image.png) + + ![alt text](images/image.png) 4. **⚠️ 添加文档访问权限(关键步骤!)** 进入「权限管理」→ 搜索并申请以下权限: | 权限 | 说明 | 是否必须 | - |------|------|----------| + | ------ | ------ | ---------- | | `docx:document:readonly` | 查看、下载云文档 | ✅ 必须 | | `drive:drive` | 查看云空间 | ✅ 必须 | | `docs:document.content:read` | 读取文档内容 | ✅ 推荐 | @@ -210,31 +215,37 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ 点击「创建凭证提供者」,填写以下信息: | 字段 | 值 | 说明 | - |------|------|------| + | ------ | ------ | ------ | | 提供者名称 | `feishu` 或自定义 | 代码中会用到这个名称 | | 提供者类型 | OAuth 2.0 | 选择 OAuth 2.0 | | 服务商 | 飞书 | 选择飞书 | | Client ID | 步骤1获取的 App ID | 从飞书应用凭证复制 | | Client Secret | 步骤1获取的 App Secret | 从飞书应用凭证复制 | + ![alt text](images/image-1.png) 3. **⚠️ 配置关键参数(避坑重点!)** | 字段 | 正确配置 | 说明 | - |------|----------|------| + | ------ | ------ | ------ | | **OAuth2 流程** | `USER_FEDERATION` | 用户级三方授权 | | **回调 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ⚠️ **必须是 Identity Service 的端点!** | | **权限范围** | `drive:drive,docx:document:readonly,offline_access` | 飞书文档读取权限 | | **智能体身份池** | `default` | 默认工作负载池 | > 🚨 **常见错误**: + > > - ❌ 回调 URL 设为 Runtime 的 URL(如 `https://xxx.apigateway-cn-beijing.volceapi.com/...`) + > > - ❌ 权限范围使用 `openid`、`profile` 等标准 OIDC scope(飞书不支持) + ![alt text](images/image-2.png) 4. **验证配置** 点击「测试」按钮验证 OAuth 流程: - - ✅ 成功:能跳转到飞书授权页,授权后能获取 Token - - ❌ 失败:检查回调 URL 和权限范围配置 + + > - ✅ 成功:能跳转到飞书授权页,授权后能获取 Token + > - ❌ 失败:检查回调 URL 和权限范围配置 + ![alt text](images/image-3.png) 5. **保存配置** @@ -329,7 +340,8 @@ agentkit launch 2. **登录并发送请求** 在对话框中输入: - ``` + + ```bash 为我总结文档内容:https://feishu.feishu.cn/docx/xxxxxxxxxxxxxxxx ``` @@ -368,7 +380,7 @@ flowchart LR ## 测试提示词 -``` +```bash # 查询文档 为我总结文档内容:<飞书文档URL> @@ -378,6 +390,7 @@ flowchart LR # 清理凭证(如需重新授权测试) 清理我的身份凭据 ``` + ![alt text](images/image-8.png) ![alt text](images/image-9.png) ![alt text](images/image-10.png) @@ -387,7 +400,7 @@ flowchart LR ### 错误速查表 | 错误/现象 | 原因 | 解决方法 | -|-----------|------|----------| +| ------ | ------ | ------ | | **Consumer authentication failed** | 回调 URL 配置错误,指向了需要认证的 Runtime 端点 | 将凭证提供者的回调 URL 改为 `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | | **redirect_uri is missing** | 用户池客户端缺少回调 URL 配置 | 在用户池客户端添加回调 URL | | **Error 20043: openid 有误** | 飞书不支持标准 OIDC scope | 使用飞书特定 scope:`drive:drive,docx:document:readonly` | @@ -568,7 +581,7 @@ OAuth2 auth polling timed out after 60 seconds. User may not have completed auth Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区分清楚: | 配置位置 | 回调 URL | 用途 | -|----------|----------|------| +| ---------- | ---------- | ------ | | **1. 飞书开放平台** → 安全设置 | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | 飞书授权后重定向目标 | | **2. Agent Identity** → 凭证提供者 | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | Identity Service 接收 OAuth 回调 | | **3. 代码中 oauth2_auth()** | **不需要设置** | 让 Identity Service 使用凭证提供者配置 | @@ -605,7 +618,6 @@ Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区 ## 核心功能回顾 - > "Agent Identity 的凭证托管功能,让您的智能体可以 **安全无感** 地访问 > 飞书、Notion 等外部工具,凭证由平台统一管理,**告别 AK/SK 泄露风险**。 > @@ -623,3 +635,25 @@ Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区 - [飞书开放平台](https://open.feishu.cn/) - [Agent Identity 凭证托管文档](https://www.volcengine.com/docs/identity/credential-provider) - [AgentKit Runtime 部署指南](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html) + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/01-tutorials/identity/tutorial-3-feishu-outbound/github_assistant/agent.py b/01-tutorials/identity/tutorial-3-feishu-outbound/github_assistant/agent.py index c8176b1..4afd414 100644 --- a/01-tutorials/identity/tutorial-3-feishu-outbound/github_assistant/agent.py +++ b/01-tutorials/identity/tutorial-3-feishu-outbound/github_assistant/agent.py @@ -1,11 +1,10 @@ # Agent definition for ADK web discovery import sys from pathlib import Path +from main import root_agent, agent # Add parent directory to path to import main module parent_dir = Path(__file__).parent.parent sys.path.insert(0, str(parent_dir)) -from main import root_agent, agent - __all__ = ["root_agent", "agent"] diff --git a/01-tutorials/identity/tutorial-3-feishu-outbound/main.py b/01-tutorials/identity/tutorial-3-feishu-outbound/main.py index 513f97b..1a51680 100644 --- a/01-tutorials/identity/tutorial-3-feishu-outbound/main.py +++ b/01-tutorials/identity/tutorial-3-feishu-outbound/main.py @@ -39,6 +39,31 @@ # ============================================================ import sys +# ============================================================ +# 正常的导入和代码 +# ============================================================ + +import json +import os +from pathlib import Path +from typing import Any + +import httpx +from dotenv import load_dotenv + +from veadk import Agent +from veadk.integrations.ve_identity import ( + AuthRequestProcessor, + VeIdentityFunctionTool, + oauth2_auth, +) +from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin +from google.adk.tools.function_tool import FunctionTool +from google.adk.tools.tool_context import ToolContext + +load_dotenv(Path(__file__).parent / ".env") + + def _patched_patch_google_adk_telemetry(): """修复版本的 patch_google_adk_telemetry,避免 RuntimeError""" try: @@ -52,7 +77,9 @@ def _patched_patch_google_adk_telemetry(): for attr_name in dir(mod): try: obj = getattr(mod, attr_name, None) - if isinstance(obj, type) and issubclass(obj, (CallbackContext, ToolContext)): + if isinstance(obj, type) and issubclass( + obj, (CallbackContext, ToolContext) + ): if not hasattr(obj, "_veadk_span"): obj._veadk_span = property( lambda self: getattr(self.state, "_veadk_span", None), @@ -61,36 +88,14 @@ def _patched_patch_google_adk_telemetry(): except (TypeError, AttributeError): pass + try: import veadk.utils.patches + veadk.utils.patches.patch_google_adk_telemetry = _patched_patch_google_adk_telemetry except ImportError: pass -# ============================================================ -# 正常的导入和代码 -# ============================================================ - -import json -import os -from pathlib import Path -from typing import Any - -import httpx -from dotenv import load_dotenv - -load_dotenv(Path(__file__).parent / ".env") - -from veadk import Agent -from veadk.integrations.ve_identity import ( - AuthRequestProcessor, - VeIdentityFunctionTool, - oauth2_auth, -) -from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin -from google.adk.tools.function_tool import FunctionTool -from google.adk.tools.tool_context import ToolContext - # 从环境变量读取凭证提供者名称 GITHUB_CREDENTIAL_PROVIDER = os.getenv("GITHUB_CREDENTIAL_PROVIDER", "github_oauth") FEISHU_CREDENTIAL_PROVIDER = os.getenv("FEISHU_CREDENTIAL_PROVIDER", "feishu_oauth") @@ -102,6 +107,7 @@ def _patched_patch_google_adk_telemetry(): # GitHub API 工具 # ============================================================ + async def github_get_user(*, access_token: str) -> str: """ 获取当前用户的 GitHub 信息 @@ -129,17 +135,21 @@ async def github_get_user(*, access_token: str) -> str: return f"GitHub API 错误: {response.status_code} - {response.text}" user_data = response.json() - return json.dumps({ - "login": user_data.get("login"), - "name": user_data.get("name"), - "email": user_data.get("email"), - "bio": user_data.get("bio"), - "public_repos": user_data.get("public_repos"), - "followers": user_data.get("followers"), - "following": user_data.get("following"), - "created_at": user_data.get("created_at"), - "html_url": user_data.get("html_url"), - }, indent=2, ensure_ascii=False) + return json.dumps( + { + "login": user_data.get("login"), + "name": user_data.get("name"), + "email": user_data.get("email"), + "bio": user_data.get("bio"), + "public_repos": user_data.get("public_repos"), + "followers": user_data.get("followers"), + "following": user_data.get("following"), + "created_at": user_data.get("created_at"), + "html_url": user_data.get("html_url"), + }, + indent=2, + ensure_ascii=False, + ) except Exception as e: return f"获取用户信息出错: {str(e)}" @@ -178,16 +188,18 @@ async def github_list_repos(*, access_token: str) -> str: repos = response.json() result = [] for repo in repos: - result.append({ - "name": repo.get("name"), - "full_name": repo.get("full_name"), - "description": repo.get("description"), - "private": repo.get("private"), - "html_url": repo.get("html_url"), - "language": repo.get("language"), - "stargazers_count": repo.get("stargazers_count"), - "updated_at": repo.get("updated_at"), - }) + result.append( + { + "name": repo.get("name"), + "full_name": repo.get("full_name"), + "description": repo.get("description"), + "private": repo.get("private"), + "html_url": repo.get("html_url"), + "language": repo.get("language"), + "stargazers_count": repo.get("stargazers_count"), + "updated_at": repo.get("updated_at"), + } + ) return json.dumps(result, indent=2, ensure_ascii=False) @@ -224,21 +236,25 @@ async def github_get_repo(owner: str, repo: str, *, access_token: str) -> str: return f"GitHub API 错误: {response.status_code} - {response.text}" repo_data = response.json() - return json.dumps({ - "name": repo_data.get("name"), - "full_name": repo_data.get("full_name"), - "description": repo_data.get("description"), - "private": repo_data.get("private"), - "html_url": repo_data.get("html_url"), - "language": repo_data.get("language"), - "stargazers_count": repo_data.get("stargazers_count"), - "forks_count": repo_data.get("forks_count"), - "open_issues_count": repo_data.get("open_issues_count"), - "default_branch": repo_data.get("default_branch"), - "created_at": repo_data.get("created_at"), - "updated_at": repo_data.get("updated_at"), - "topics": repo_data.get("topics", []), - }, indent=2, ensure_ascii=False) + return json.dumps( + { + "name": repo_data.get("name"), + "full_name": repo_data.get("full_name"), + "description": repo_data.get("description"), + "private": repo_data.get("private"), + "html_url": repo_data.get("html_url"), + "language": repo_data.get("language"), + "stargazers_count": repo_data.get("stargazers_count"), + "forks_count": repo_data.get("forks_count"), + "open_issues_count": repo_data.get("open_issues_count"), + "default_branch": repo_data.get("default_branch"), + "created_at": repo_data.get("created_at"), + "updated_at": repo_data.get("updated_at"), + "topics": repo_data.get("topics", []), + }, + indent=2, + ensure_ascii=False, + ) except Exception as e: return f"获取仓库信息出错: {str(e)}" @@ -274,6 +290,7 @@ async def github_get_repo(owner: str, repo: str, *, access_token: str) -> str: # 飞书 API 工具 # ============================================================ + async def feishu_get_document(document_id: str, *, access_token: str) -> str: """ 获取飞书文档的内容并总结 @@ -350,14 +367,16 @@ async def feishu_list_docs(*, access_token: str) -> str: files = data.get("data", {}).get("files", []) result = [] for f in files: - result.append({ - "name": f.get("name"), - "token": f.get("token"), - "type": f.get("type"), - "url": f.get("url"), - "created_time": f.get("created_time"), - "modified_time": f.get("modified_time"), - }) + result.append( + { + "name": f.get("name"), + "token": f.get("token"), + "type": f.get("type"), + "url": f.get("url"), + "created_time": f.get("created_time"), + "modified_time": f.get("modified_time"), + } + ) return json.dumps(result, indent=2, ensure_ascii=False) @@ -387,7 +406,10 @@ async def feishu_list_docs(*, access_token: str) -> str: # 凭证清理工具(用于重新触发授权) # ============================================================ -async def clean_github_state(args: dict[str, Any], *, tool_context: ToolContext) -> None: + +async def clean_github_state( + args: dict[str, Any], *, tool_context: ToolContext +) -> None: """ 清理用户的 GitHub OAuth 身份凭据 @@ -402,7 +424,9 @@ async def clean_github_state(args: dict[str, Any], *, tool_context: ToolContext) return None -async def clean_feishu_state(args: dict[str, Any], *, tool_context: ToolContext) -> None: +async def clean_feishu_state( + args: dict[str, Any], *, tool_context: ToolContext +) -> None: """ 清理用户的飞书 OAuth 身份凭据 diff --git a/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README.md b/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README.md index 2a08d36..57fab6e 100644 --- a/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README.md +++ b/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README.md @@ -12,7 +12,7 @@ ### 没有认证会怎样? -**场景 1:裸奔的 Agent** +- **场景 1:裸奔的 Agent** ```mermaid flowchart LR @@ -23,22 +23,25 @@ flowchart LR ``` 后果: + - 有人写个脚本疯狂调用,你的 API 费用一夜爆炸 - 竞争对手拿你的 Agent 做逆向工程 - 出了安全事故,你不知道是谁干的 -**场景 2:Agent 不知道"你是谁"** +- **场景 2:Agent 不知道"你是谁"** 很多 Agent 需要根据用户身份提供个性化服务: + - 查"我的订单" —— 哪个"我"? - 访问"我的文档" —— 哪个"我"? - 执行敏感操作 —— 你有权限吗? 没有身份信息,Agent 要么拒绝服务,要么只能提供最基础的公开功能。 -**场景 3:审计和合规** +- **场景 3:审计和合规** 安全团队、CISO 会问你: + - 这个 Agent 谁在用? - 用了多少次? - 有没有异常调用? @@ -57,6 +60,7 @@ flowchart LR ``` 这就是 **Inbound(入站)认证** 要解决的事: + 1. **认证**:证明"你是你" 2. **授权**:确认"你能用" 3. **传递**:把身份信息带给 Agent @@ -66,7 +70,7 @@ flowchart LR 我们提供开箱即用的 **用户池** 方案: | 能力 | 说明 | -|------|------| +| ------ | ------ | | **统一用户目录** | 一个地方管理所有能访问 Agent 的用户 | | **标准协议** | OAuth2/OIDC,不用自己造轮子 | | **JWT Token** | 无状态认证,高性能,身份信息可传递给 Agent | @@ -106,7 +110,7 @@ flowchart TB - 选择登录属性:用户名 + 手机号 - 点击「确认」 -![新建用户池](./assets/images/image-2.png) + ![新建用户池](images/image-2.png) 3. **新建客户端** - 进入用户池详情 → 点击「新建客户端」 @@ -115,13 +119,13 @@ flowchart TB - 回调地址:`http://127.0.0.1:8000/api/v1/oauth2callback` - **记录 Client ID 和 Client Secret** -![新建客户端](./assets/images/image-3.png) + ![新建客户端](images/image-3.png) 4. **创建测试用户** - 在用户池中选择「用户管理」→「新建用户」 - 设置用户名和临时密码 -![创建测试用户](./assets/images/image-4.png) + ![创建测试用户](images/image-4.png) ### 步骤2: 配置环境变量 @@ -156,19 +160,19 @@ uv sync uv run veadk web ``` -服务启动后,访问 http://127.0.0.1:8000 +服务启动后,访问 ### 步骤4: 用户登录体验 -1. **访问应用** - 浏览器打开 http://127.0.0.1:8000 +1. **访问应用** - 浏览器打开 2. **跳转登录** - 自动跳转到用户池登录页面 3. **输入凭证** - 使用步骤1创建的用户登录 4. **首次修改密码** - 如有要求,设置新密码 5. **授权确认** - 允许应用访问您的信息 6. **进入应用** - 登录成功,可以开始使用 Agent -![登录页面](./assets/images/image-5.png) -![登录成功](./assets/images/image-6.png) +![登录页面](images/image-5.png) +![登录成功](images/image-6.png) ```mermaid flowchart LR @@ -195,8 +199,8 @@ flowchart LR --- - **关键点说明:** + - `veadk web` 命令自动读取环境变量中的 OAuth2 配置 - 所有请求都会验证 JWT Token - 未授权请求返回 401 错误 @@ -214,7 +218,7 @@ flowchart LR ## 常见问题 | 问题 | 解决方案 | -|------|----------| +| ------ | ------ | | 登录页面一直跳转 | 清除浏览器缓存,检查回调地址配置 | | Token 过期 | 默认 10 小时有效,可配置刷新机制 | | 忘记 Client Secret | 在控制台重新生成 | @@ -225,3 +229,25 @@ flowchart LR - [Agent Identity 产品文档](https://www.volcengine.com/docs/identity) - [VeADK 开发指南](https://volcengine.github.io/agentkit-sdk-python/) + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README_en.md b/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README_en.md index 85d83fd..31cf444 100644 --- a/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README_en.md +++ b/python/01-tutorials/03-agentKit-identity/01_userpool_inbound/README_en.md @@ -12,7 +12,7 @@ At this point, you'll encounter a fundamental problem: **Who can call your Agent ### What happens without authentication? -**Scenario 1: The Naked Agent** +- **Scenario 1: The Naked Agent** ```mermaid flowchart LR @@ -28,7 +28,7 @@ Consequences: - Competitors reverse-engineer your Agent. - If a security incident occurs, you don't know who did it. -**Scenario 2: The Agent doesn't know "who you are"** +- **Scenario 2: The Agent doesn't know "who you are"** Many Agents need to provide personalized services based on user identity: @@ -38,7 +38,7 @@ Many Agents need to provide personalized services based on user identity: Without identity information, the Agent either has to refuse service or can only provide the most basic public functions. -**Scenario 3: Auditing and Compliance** +- **Scenario 3: Auditing and Compliance** The security team and CISO will ask you: @@ -110,7 +110,7 @@ flowchart TB - Select login attributes: Username + Phone Number - Click "Confirm" -![Create New User Pool](./assets/images/image-2.png) + ![Create New User Pool](./assets/images/image-2.png) 3. **Create a New Client** - Go to the user pool details → Click "New Client" @@ -119,7 +119,7 @@ flowchart TB - Callback URL: `http://127.0.0.1:8000/api/v1/oauth2callback` - **Record the Client ID and Client Secret** -![Create New Client](./assets/images/image-3.png) + ![Create New Client](./assets/images/image-3.png) 4. **Create a Test User** - In the user pool, select "User Management" → "New User" @@ -160,11 +160,11 @@ uv sync uv run veadk web ``` -After the service starts, access http://127.0.0.1:8000 +After the service starts, access ### Step 4: User Login Experience -1. **Access the Application** - Open http://127.0.0.1:8000 in your browser +1. **Access the Application** - Open in your browser 2. **Redirect to Login** - You will be automatically redirected to the user pool login page 3. **Enter Credentials** - Log in with the user created in Step 1 4. **Change Password on First Login** - If required, set a new password diff --git a/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README.md b/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README.md index 42806fd..52969b9 100644 --- a/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README.md +++ b/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README.md @@ -7,11 +7,13 @@ 企业已经在使用飞书作为统一通讯和办公平台,员工都有飞书账号。现在要部署 AI 智能体,如何让员工使用飞书账号直接登录,而不是再创建一套新的账号? **传统方案的问题:** + - 每个系统维护独立用户库 → 用户需要记忆多套密码 - 用户离职/入职需要多个系统同步 → 管理成本高、遗漏风险 - 无法利用飞书的 MFA/安全策略 → 安全合规难以统一 **Agent Identity 解决方案:** + - 飞书作为身份源(IdP),用户池作为服务提供者(SP) - 一键登录,无需额外注册 - 继承飞书的安全策略和审计能力 @@ -19,7 +21,7 @@ ## 与实验1的区别 | 对比项 | 实验1 (用户池登录) | 实验2 (飞书联合登录) | -|--------|-------------------|---------------------| +| ------ | ------------------- | --------------------- | | 账号来源 | 用户池本地创建 | 飞书通讯录 | | 登录方式 | 用户名/密码 | 飞书授权 | | 适用场景 | 独立用户管理 | 企业统一身份 | @@ -58,7 +60,7 @@ sequenceDiagram ### 前置条件 - 完成实验1的用户池创建和客户端配置 -- 拥有飞书开放平台账号(https://open.feishu.cn/) +- 拥有飞书开放平台账号 [飞书开放平台](https://open.feishu.cn/) --- @@ -68,7 +70,7 @@ sequenceDiagram 访问 [飞书开放平台](https://open.feishu.cn/) → 点击「创建应用」 -![飞书开放平台](./assets/images/image.png) + ![飞书开放平台](images/image.png) 2. **创建企业自建应用** - 应用类型:企业自建应用 @@ -81,7 +83,7 @@ sequenceDiagram - **App ID**(客户端 ID) - **App Secret**(客户端密钥) -![获取应用凭证](./assets/images/image-1.png) + ![获取应用凭证](images/image-1.png) 4. **⚠️ 配置安全设置(最关键的一步!)** @@ -95,7 +97,8 @@ sequenceDiagram > 4. **直接复制该地址**,粘贴到飞书的「安全设置」中 回调 URL 格式类似: - ``` + + ```bash https://userpool-<用户池UID>.userpool.auth.id.cn-beijing.volces.com/login/generic_oauth/callback ``` @@ -104,14 +107,14 @@ sequenceDiagram > - 不要漏掉 `/login/generic_oauth/callback` 路径 > - URL 必须与控制台显示的完全一致,包括协议 `https://` -![配置安全设置](./assets/images/image-2.png) + ![配置安全设置](images/image-2.png) 5. **网页应用配置(可选,非必须)** 飞书可能提示配置「网页应用」,这是**可选的**: | 配置项 | 说明 | 是否必须 | - |--------|------|----------| + | -------- | ------ | ---------- | | 安全设置 → 重定向 URL | OAuth 回调地址 | ✅ 必须 | | 网页应用 → 桌面端主页 | 从飞书打开应用的地址 | ❌ 可选 | @@ -125,7 +128,7 @@ sequenceDiagram 进入「权限管理」→ 搜索并申请以下权限: | 权限 | 说明 | 是否必须 | - |------|------|----------| + | ------ | ------ | ---------- | | `contact:user.base:readonly` | 获取用户基本信息 | ✅ 必须 | | `contact:contact.base:readonly` | 获取通讯录基本信息 | ✅ 必须 | | `contact:user.employee_id:readonly` | 获取用户工号 | ❌ 可选 | @@ -135,7 +138,7 @@ sequenceDiagram > - **如果不申请这个权限,登录时会报错 `20027 当前应用未申请相关权限`** > - 两个必须权限缺一不可! -![添加权限](./assets/images/image-3.png) + ![添加权限](images/image-3.png) 7. **发布应用** @@ -158,8 +161,9 @@ sequenceDiagram 左侧菜单 →「外部身份供应商」→「添加供应商」 填写信息: + | 字段 | 值 | 说明 | - |------|------|------| + | ------ | ------ | ------ | | 供应商类型 | 飞书 | 选择飞书 | | 供应商名称 | feishu | 自定义名称 | | 客户端 ID | 步骤1获取的 App ID | 从飞书应用凭证复制 | @@ -170,8 +174,8 @@ sequenceDiagram > 保存后,页面会显示「重定向 URI」,确认这个 URL 已经添加到飞书应用的「安全设置」中。 -![配置飞书 IdP](./assets/images/image-4.png) -![保存配置](./assets/images/image-5.png) +![配置飞书 IdP](images/image-4.png) +![保存配置](images/image-5.png) 配置完成后,用户池登录页面将显示「使用飞书登录」按钮。 @@ -181,7 +185,7 @@ sequenceDiagram ```bash # 进入教程目录 -cd python/01-tutorials/03-agentkit-identity/02_feishu_idp +cd 01-tutorials/identity/tutorial-2-feishu-idp # 复制环境变量模板 cp .env.example .env @@ -205,9 +209,10 @@ uv run veadk web > **端口冲突?** 如果提示 `address already in use`,说明端口 8000 被占用。 > 运行以下命令清理: -> ```bash -> lsof -i :8000 | grep -v "^COMMAND" | awk '{print $2}' | xargs kill -9 -> ``` + +```bash +lsof -i :8000 | grep -v "^COMMAND" | awk '{print $2}' | xargs kill -9 +``` --- @@ -219,12 +224,12 @@ uv run veadk web 4. 返回应用后,点击 **「允许访问」** 5. 成功登录,开始与 Agent 对话 -![飞书登录按钮](./assets/images/image-6.png) -![飞书授权页面](./assets/images/image-7.png) +![飞书登录按钮](images/image-6.png) +![飞书授权页面](images/image-7.png) ## 测试提示词 -``` +```bash 你好,我是通过飞书登录的,请介绍一下你自己 ``` @@ -239,7 +244,7 @@ uv run veadk web ### 错误速查表 | 错误码/现象 | 原因 | 解决方法 | -|-------------|------|----------| +| ------------- | ------ | ---------- | | `20029` redirect_uri 请求不合法 | 飞书安全设置中的重定向 URL 与实际请求不匹配 | 从用户池控制台复制正确的「重定向 URI」到飞书安全设置 | | `20027` 当前应用未申请相关权限 | 缺少 `contact:contact.base:readonly` 权限 | 在飞书权限管理中申请该权限,然后重新发布应用 | | 飞书登录按钮不显示 | 未在用户池配置外部身份供应商 | 在用户池添加飞书 IdP 配置 | @@ -278,9 +283,32 @@ uv run veadk web 完成联合登录后,如果需要让 Agent **代表用户**安全访问飞书文档等外部资源,请继续: -→ [实验3: Outbound 凭证托管 - 让 Agent 安全访问飞书文档](../tutorial_3_feishu_outbound/) +→ [实验3: Outbound 凭证托管 - 让 Agent 安全访问飞书文档](../tutorial-3-feishu-outbound/) 在实验3中,你将学习: + - 如何让 Agent 获取用户授权的飞书 Token - 凭证托管的安全最佳实践 - 实现"凭证不落地"的 Outbound 访问模式 + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README_en.md b/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README_en.md index 37d3dae..c62ce46 100644 --- a/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README_en.md +++ b/python/01-tutorials/03-agentKit-identity/02_feishu_idp/README_en.md @@ -60,7 +60,7 @@ sequenceDiagram ### Prerequisites - Completed the user pool creation and client configuration from Experiment 1. -- Have a Feishu Open Platform account (https://open.feishu.cn/). +- Have a Feishu Open Platform account [Feishu Open Platform](https://open.feishu.cn/). --- @@ -70,7 +70,7 @@ sequenceDiagram Visit the [Feishu Open Platform](https://open.feishu.cn/) → Click "Create Application". -![Feishu Open Platform](./assets/images/image.png) + ![Feishu Open Platform](./assets/images/image.png) 2. **Create a Custom App** - Application Type: Custom App @@ -83,7 +83,7 @@ sequenceDiagram - **App ID** (Client ID) - **App Secret** (Client Secret) -![Get Application Credentials](./assets/images/image-1.png) + ![Get Application Credentials](./assets/images/image-1.png) 4. **⚠️ Configure Security Settings (The most critical step!)** @@ -97,7 +97,8 @@ sequenceDiagram > 4. **Copy this address directly** and paste it into Feishu's "Security Settings". The callback URL format is similar to: - ``` + + ```bash https://userpool-.userpool.auth.id.cn-beijing.volces.com/login/generic_oauth/callback ``` @@ -106,7 +107,7 @@ sequenceDiagram > - Do not omit the `/login/generic_oauth/callback` path. > - The URL must be exactly the same as the one displayed in the console, including the `https://` protocol. -![Configure Security Settings](./assets/images/image-2.png) + ![Configure Security Settings](./assets/images/image-2.png) 5. **Web App Configuration (Optional, not required)** @@ -137,7 +138,7 @@ sequenceDiagram > - **If you do not apply for this permission, you will get an error `20027 The current application has not applied for the relevant permissions` when logging in.** > - Both required permissions are indispensable! -![Add Permissions](./assets/images/image-3.png) + ![Add Permissions](./assets/images/image-3.png) 7. **Publish the Application** @@ -208,6 +209,7 @@ uv run veadk web > **Port conflict?** If you get an `address already in use` error, it means that port 8000 is occupied. > Run the following command to clean it up: +> > ```bash > lsof -i :8000 | grep -v "^COMMAND" | awk '{print $2}' | xargs kill -9 > ``` @@ -227,7 +229,7 @@ uv run veadk web ## Test Prompt -``` +```bash Hello, I logged in through Feishu, please introduce yourself. ``` diff --git a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README.md b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README.md index 679de88..355cf0d 100644 --- a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README.md +++ b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README.md @@ -15,6 +15,7 @@ > 用户对 Agent 说:"帮我总结一下那个飞书文档的内容" > > Agent 需要访问用户的飞书文档,但是... +> > - **飞书 API 需要授权** > - **每个用户的授权是独立的** > - **凭证怎么安全管理?** @@ -22,7 +23,7 @@ ### 传统方案的问题 | 方案 | 问题 | -|------|------| +| ------ | ------ | | **硬编码凭证** | AK/SK 写在代码里,泄露风险极高 | | **共享凭证** | 所有用户用同一个 Token,无法追溯谁做了什么 | | **手动管理** | 每个用户单独管理 Token,运维成本爆炸 | @@ -54,7 +55,7 @@ flowchart LR ### 核心优势 | 特性 | 说明 | -|------|------| +| ------ | ------ | | **凭证不落地** | AK/SK 由平台统一管理,不在代码中出现 | | **用户级隔离** | 每个用户的飞书授权独立管理 | | **OAuth 自动化** | 首次使用引导授权,后续自动刷新 Token | @@ -109,7 +110,7 @@ sequenceDiagram ### 🔴 关键配置点 | 配置项 | 正确值 | 常见错误 | -|--------|--------|----------| +| ------ | ------ | ---------- | | **凭证提供者回调 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ❌ 错误地设为 Runtime URL(会导致 "Consumer authentication failed") | | **飞书安全设置重定向 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ❌ 只添加了本地开发 URL | | **飞书权限范围** | `drive:drive,docx:document:readonly,offline_access` | ❌ 使用 `openid` 等标准 OIDC scope(飞书不支持) | @@ -121,7 +122,7 @@ sequenceDiagram 本教程的 **Outbound 凭证托管** 功能依赖 **工作负载身份 (Workload Identity)**: | 环境 | 工作负载身份 | 凭证托管功能 | -|------|-------------|-------------| +| ------ | ------------- | ------------- | | 本地 veadk web | ⚠️ 需手动配置 | ✅ 可测试 | | AgentKit Runtime | ✅ 自动分配 | ✅ 完整支持 | @@ -147,11 +148,13 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ - 完成实验2的飞书应用创建(可复用) 2. **安装 AgentKit CLI** + ```bash pip install agentkit-cli ``` 3. **配置 AgentKit** + ```bash agentkit config --tos_bucket ``` @@ -177,16 +180,18 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ 进入「安全设置」→ 添加重定向 URL: > **重要:凭证托管使用不同的回调 URL!** - > ``` + > + > ```bash > https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback > ``` -![alt text](./assets/images/image.png) + + ![alt text](images/image.png) 4. **⚠️ 添加文档访问权限(关键步骤!)** 进入「权限管理」→ 搜索并申请以下权限: | 权限 | 说明 | 是否必须 | - |------|------|----------| + | ------ | ------ | ---------- | | `docx:document:readonly` | 查看、下载云文档 | ✅ 必须 | | `drive:drive` | 查看云空间 | ✅ 必须 | | `docs:document.content:read` | 读取文档内容 | ✅ 推荐 | @@ -210,32 +215,38 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ 点击「创建凭证提供者」,填写以下信息: | 字段 | 值 | 说明 | - |------|------|------| + | ------ | ------ | ------ | | 提供者名称 | `feishu` 或自定义 | 代码中会用到这个名称 | | 提供者类型 | OAuth 2.0 | 选择 OAuth 2.0 | | 服务商 | 飞书 | 选择飞书 | | Client ID | 步骤1获取的 App ID | 从飞书应用凭证复制 | | Client Secret | 步骤1获取的 App Secret | 从飞书应用凭证复制 | -![alt text](./assets/images/image-1.png) + +![alt text](images/image-1.png) 3. **⚠️ 配置关键参数(避坑重点!)** | 字段 | 正确配置 | 说明 | - |------|----------|------| + | ------ | ------ | ------ | | **OAuth2 流程** | `USER_FEDERATION` | 用户级三方授权 | | **回调 URL** | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | ⚠️ **必须是 Identity Service 的端点!** | | **权限范围** | `drive:drive,docx:document:readonly,offline_access` | 飞书文档读取权限 | | **智能体身份池** | `default` | 默认工作负载池 | > 🚨 **常见错误**: + > > - ❌ 回调 URL 设为 Runtime 的 URL(如 `https://xxx.apigateway-cn-beijing.volceapi.com/...`) + > > - ❌ 权限范围使用 `openid`、`profile` 等标准 OIDC scope(飞书不支持) -![alt text](./assets/images/image-2.png) + +![alt text](images/image-2.png) 4. **验证配置** 点击「测试」按钮验证 OAuth 流程: - - ✅ 成功:能跳转到飞书授权页,授权后能获取 Token - - ❌ 失败:检查回调 URL 和权限范围配置 -![alt text](./assets/images/image-3.png) + + > - ✅ 成功:能跳转到飞书授权页,授权后能获取 Token + > - ❌ 失败:检查回调 URL 和权限范围配置 + +![alt text](images/image-3.png) 5. **保存配置** 记住凭证提供者名称(如 `feishu`),后续配置时需要使用。 @@ -246,7 +257,7 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ ```bash # 进入教程目录 -cd python/01-tutorials/03-agentKit-identity/03_feishu_outbound +cd 01-tutorials/identity/tutorial-3-feishu-outbound # 复制环境变量模板 cp .env.example .env @@ -329,7 +340,8 @@ agentkit launch 2. **登录并发送请求** 在对话框中输入: - ``` + + ```bash 为我总结文档内容:https://feishu.feishu.cn/docx/xxxxxxxxxxxxxxxx ``` @@ -368,7 +380,7 @@ flowchart LR ## 测试提示词 -``` +```bash # 查询文档 为我总结文档内容:<飞书文档URL> @@ -378,16 +390,17 @@ flowchart LR # 清理凭证(如需重新授权测试) 清理我的身份凭据 ``` -![alt text](./assets/images/image-8.png) -![alt text](./assets/images/image-9.png) -![alt text](./assets/images/image-10.png) + +![alt text](images/image-8.png) +![alt text](images/image-9.png) +![alt text](images/image-10.png) ## 常见问题排查 ### 错误速查表 | 错误/现象 | 原因 | 解决方法 | -|-----------|------|----------| +| ------ | ------ | ------ | | **Consumer authentication failed** | 回调 URL 配置错误,指向了需要认证的 Runtime 端点 | 将凭证提供者的回调 URL 改为 `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | | **redirect_uri is missing** | 用户池客户端缺少回调 URL 配置 | 在用户池客户端添加回调 URL | | **Error 20043: openid 有误** | 飞书不支持标准 OIDC scope | 使用飞书特定 scope:`drive:drive,docx:document:readonly` | @@ -568,7 +581,7 @@ OAuth2 auth polling timed out after 60 seconds. User may not have completed auth Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区分清楚: | 配置位置 | 回调 URL | 用途 | -|----------|----------|------| +| ---------- | ---------- | ------ | | **1. 飞书开放平台** → 安全设置 | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | 飞书授权后重定向目标 | | **2. Agent Identity** → 凭证提供者 | `https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback` | Identity Service 接收 OAuth 回调 | | **3. 代码中 oauth2_auth()** | **不需要设置** | 让 Identity Service 使用凭证提供者配置 | @@ -605,7 +618,6 @@ Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区 ## 核心功能回顾 - > "Agent Identity 的凭证托管功能,让您的智能体可以 **安全无感** 地访问 > 飞书、Notion 等外部工具,凭证由平台统一管理,**告别 AK/SK 泄露风险**。 > @@ -623,3 +635,25 @@ Outbound 凭证托管涉及 **三个地方** 需要配置回调 URL,务必区 - [飞书开放平台](https://open.feishu.cn/) - [Agent Identity 凭证托管文档](https://www.volcengine.com/docs/identity/credential-provider) - [AgentKit Runtime 部署指南](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html) + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README_en.md b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README_en.md index cfba59e..81d9226 100644 --- a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README_en.md +++ b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/README_en.md @@ -15,7 +15,7 @@ Imagine this scenario: > A user says to the Agent: "Help me summarize the content of that Feishu document." > > The Agent needs to access the user's Feishu document, but... - +> > - **The Feishu API requires authorization.** > - **Each user's authorization is independent.** > - **How to manage credentials securely?** @@ -55,7 +55,7 @@ flowchart LR ### Core Advantages | Feature | Description | -|---|---| +| ------------------ | ----------- | | **Credentials don't land** | AK/SK are managed uniformly by the platform and do not appear in the code. | | **User-level isolation** | Each user's Feishu authorization is managed independently. | | **OAuth automation** | Guides authorization on first use, automatically refreshes tokens subsequently. | @@ -180,12 +180,12 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ Go to "Security Settings" → Add a redirect URL: > **Important: Credential hosting uses a different callback URL!** - - > ``` + > + > ```bash > https://auth.id.cn-beijing.volces.com/api/v1/oauth2callback > ``` -![alt text](./assets/images/image.png) + ![alt text](./assets/images/image.png) 4. **⚠️ Add Document Access Permissions (Key step!)** Go to "Permission Management" → Search for and apply for the following permissions: @@ -236,13 +236,13 @@ RUNTIME_IAM_ROLE_TRN=trn:iam:::role/ > 🚨 **Common Mistakes**: > - ❌ Setting the callback URL to the Runtime URL (e.g., `https://xxx.apigateway-cn-beijing.volceapi.com/...`) > - ❌ Using standard OIDC scopes like `openid`, `profile` (Feishu does not support this) -![alt text](./assets/images/image-2.png) + ![alt text](./assets/images/image-2.png) 4. **Verify Configuration** Click the "Test" button to verify the OAuth flow: - ✅ Success: Can jump to the Feishu authorization page and get a token after authorization. - ❌ Failure: Check the callback URL and permission scope configuration. -![alt text](./assets/images/image-3.png) + ![alt text](./assets/images/image-3.png) 5. **Save Configuration** Remember the credential provider name (e.g., `feishu`), as it will be needed for subsequent configuration. @@ -337,7 +337,7 @@ After successful deployment, the access address of the Agent will be output. Enter in the dialog box: - ``` + ```bash Summarize the document content for me: https://feishu.feishu.cn/docx/xxxxxxxxxxxxxxxx ``` @@ -377,7 +377,7 @@ flowchart LR ## Test Prompts -``` +```bash # Query document Summarize the document content for me: @@ -615,7 +615,6 @@ The configuration method is similar, just create the corresponding Credential Pr ## Core Functionality Review - > "Agent Identity's credential hosting feature allows your intelligent agent to **securely and seamlessly** access > external tools like Feishu and Notion, with credentials managed uniformly by the platform, **saying goodbye to the risk of AK/SK leakage**. > diff --git a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/github_assistant/agent.py b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/github_assistant/agent.py index c8176b1..4afd414 100644 --- a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/github_assistant/agent.py +++ b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/github_assistant/agent.py @@ -1,11 +1,10 @@ # Agent definition for ADK web discovery import sys from pathlib import Path +from main import root_agent, agent # Add parent directory to path to import main module parent_dir = Path(__file__).parent.parent sys.path.insert(0, str(parent_dir)) -from main import root_agent, agent - __all__ = ["root_agent", "agent"] diff --git a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/main.py b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/main.py index ba166cc..1a51680 100644 --- a/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/main.py +++ b/python/01-tutorials/03-agentKit-identity/03_feishu_outbound/main.py @@ -39,6 +39,30 @@ # ============================================================ import sys +# ============================================================ +# 正常的导入和代码 +# ============================================================ + +import json +import os +from pathlib import Path +from typing import Any + +import httpx +from dotenv import load_dotenv + +from veadk import Agent +from veadk.integrations.ve_identity import ( + AuthRequestProcessor, + VeIdentityFunctionTool, + oauth2_auth, +) +from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin +from google.adk.tools.function_tool import FunctionTool +from google.adk.tools.tool_context import ToolContext + +load_dotenv(Path(__file__).parent / ".env") + def _patched_patch_google_adk_telemetry(): """修复版本的 patch_google_adk_telemetry,避免 RuntimeError""" @@ -72,30 +96,6 @@ def _patched_patch_google_adk_telemetry(): except ImportError: pass -# ============================================================ -# 正常的导入和代码 -# ============================================================ - -import json -import os -from pathlib import Path -from typing import Any - -import httpx -from dotenv import load_dotenv - -load_dotenv(Path(__file__).parent / ".env") - -from veadk import Agent -from veadk.integrations.ve_identity import ( - AuthRequestProcessor, - VeIdentityFunctionTool, - oauth2_auth, -) -from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin -from google.adk.tools.function_tool import FunctionTool -from google.adk.tools.tool_context import ToolContext - # 从环境变量读取凭证提供者名称 GITHUB_CREDENTIAL_PROVIDER = os.getenv("GITHUB_CREDENTIAL_PROVIDER", "github_oauth") FEISHU_CREDENTIAL_PROVIDER = os.getenv("FEISHU_CREDENTIAL_PROVIDER", "feishu_oauth") diff --git a/python/01-tutorials/03-agentKit-identity/README.md b/python/01-tutorials/03-agentKit-identity/README.md index 8d56da9..bc2e737 100644 --- a/python/01-tutorials/03-agentKit-identity/README.md +++ b/python/01-tutorials/03-agentKit-identity/README.md @@ -8,16 +8,16 @@ 与传统的微服务不同,真正的企业级 Agent 必须具备 **自主行动能力(Agency)**。而受制于模型能力,Agent 的行为又是不可预测的。这带来了三个核心挑战: -1. **入站安全 (Inbound Security) —— 谁能调用 Agent?** +1. **入站安全 (Inbound Security) —— 谁能调用 Agent?** * 常见的基于 API Key 的访问方式由于缺乏防重放机制,安全性低。 * 企业往往希望复用既有 IdP ,Agent 需要支持通过 SSO (如飞书) 方式验证用户身份,确保只有授权用户才能发起对话。 - -2. **出站安全 (Outbound Security) —— Agent 代表谁在操作?** + +2. **出站安全 (Outbound Security) —— Agent 代表谁在操作?** * **凭证泄露风险**:开发者习惯将 API Key 硬编码在 Agent 代码中,这是巨大的安全隐患。 * **权限越界**:当 Agent 访问飞书文档或数据库时,它应该拥有“上帝视角”,还是仅拥有“当前用户”的权限? * **身份传递**:如何让后端资源知道,这次调用是由“User A”授权“Agent B”发起的? -3. **细粒度权限管控 (Governance) —— 如何管控“黑盒”?** +3. **细粒度权限管控 (Governance) —— 如何管控“黑盒”?** * Agent 需要细粒度的策略控制,而不是一把梭的 `Admin` 权限。 * 企业 CISO 和安全团队需要知道 Agent 到底访问了什么资源。 @@ -27,29 +27,29 @@ Agent Identity 专为解决上述问题设计,它不是简单的 OAuth 包装 ![alt text](image.png) Agent Identity 把“用户 → 应用 → Agent → 资源”的链路拆开治理,并提供一套可复用的安全构件: -- **Inbound 认证**:对接企业现有 IdP(用户池 / OAuth / SSO 等),让“谁能调用 Agent”可配置、可审计。 -- **Agent 权威身份**:为 Agent 提供唯一、可验证的身份主体,便于策略绑定与审计归因。 -- **Outbound 凭证托管(Token Vault)**:把 OAuth / API Key 的存储、刷新、最小化授权从业务代码中剥离出来;默认做到“凭据不落地”。 -- **细粒度权限控制**:基于委托链(Delegation Chain)把“用户权限”和“Agent 权限”组合校验,默认拒绝、按需放开。 -- **可观测与审计**:把“谁在什么时候代表谁调用了哪个工具/资源”沉淀为审计事件,方便排障、合规与内控。 +**Inbound 认证**:对接企业现有 IdP(用户池 / OAuth / SSO 等),让“谁能调用 Agent”可配置、可审计。 +**Agent 权威身份**:为 Agent 提供唯一、可验证的身份主体,便于策略绑定与审计归因。 +**Outbound 凭证托管(Token Vault)**:把 OAuth / API Key 的存储、刷新、最小化授权从业务代码中剥离出来;默认做到“凭据不落地”。 +**细粒度权限控制**:基于委托链(Delegation Chain)把“用户权限”和“Agent 权限”组合校验,默认拒绝、按需放开。 +**可观测与审计**:把“谁在什么时候代表谁调用了哪个工具/资源”沉淀为审计事件,方便排障、合规与内控。 ## 实验列表 + | 实验 | 说明 | 目录 | -|------|------|------| +| ------ | ------ | ------ | | **实验1: 用户池认证** | 使用用户池管控智能体访问 (Inbound 认证) | [01_userpool_inbound](./01_userpool_inbound/) | | **实验2: 飞书联合登录** | 使用飞书账号作为企业身份源 (IdP 集成) | [02_feishu_idp](./02_feishu_idp/) | | **实验3: 飞书文档访问** | 配置 Agent 代表用户访问飞书文档 | [03_feishu_outbound](./03_feishu_outbound/) | ## 核心功能 -- **身份认证 (Inbound)**: 验证用户身份,只有授权用户才能访问 Agent -- **凭证托管 (Outbound)**: Agent 安全访问飞书等外部服务,凭证由平台管理 -- **权限控制**: 基于委托链的细粒度权限,控制 Agent 能访问的资源 - +**身份认证 (Inbound)**: 验证用户身份,只有授权用户才能访问 Agent +**凭证托管 (Outbound)**: Agent 安全访问飞书等外部服务,凭证由平台管理 +**权限控制**: 基于委托链的细粒度权限,控制 Agent 能访问的资源 ## 目录结构说明 -``` +```bash 03-agentkit-identity/ ├── README.md # 本文件 ├── 01_userpool_inbound/ # 实验1: Inbound 认证 @@ -77,7 +77,7 @@ Agent Identity 把“用户 → 应用 → Agent → 资源”的链路拆开治 ### 前置准备 | 项目 | 说明 | -|------|------| +| ------ | ------ | | **火山控制台账号** | 需要 IDFullAccess、STSAssumeRoleAccess 权限的子账号 | | **Python 环境** | Python 3.12+ 及 [uv](https://docs.astral.sh/uv/) | | **飞书账号**(实验2/3) | 用于测试飞书登录和文档访问 | @@ -107,4 +107,26 @@ uv run veadk web 本教程所有示例均可通过 `uv run veadk web` 在本地运行。 -如需部署到 AgentKit Runtime,请参考 [AgentKit Runtime 文档](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html)。 \ No newline at end of file +如需部署到 AgentKit Runtime,请参考 [AgentKit Runtime 文档](https://volcengine.github.io/agentkit-sdk-python/content/4.runtime/1.runtime_quickstart.html)。 + +## 概述 + +## 核心功能 + +## Agent 能力 + +## 目录结构说明 + +## 本地运行 + +## AgentKit 部署 + +## 示例提示词 + +## 效果展示 + +## 常见问题 + +## 代码许可 + +本工程遵循 Apache 2.0 License diff --git a/python/01-tutorials/03-agentKit-identity/README_en.md b/python/01-tutorials/03-agentKit-identity/README_en.md index 8b4638c..8c68b8e 100644 --- a/python/01-tutorials/03-agentKit-identity/README_en.md +++ b/python/01-tutorials/03-agentKit-identity/README_en.md @@ -27,11 +27,11 @@ Agent Identity is specifically designed to solve the above problems. It is not a ![alt text](image.png) Agent Identity governs the "user → application → Agent → resource" link separately and provides a set of reusable security components: -- **Inbound Authentication**: Integrates with existing enterprise IdPs (user pools / OAuth / SSO, etc.), making "who can call the Agent" configurable and auditable. -- **Agent Authoritative Identity**: Provides a unique and verifiable identity principal for the Agent, which is convenient for policy binding and audit attribution. -- **Outbound Credential Hosting (Token Vault)**: Separates the storage, refresh, and minimization of authorization of OAuth / API Keys from the business code; by default, "credentials do not land on the ground." -- **Fine-grained Permission Control**: Combines and verifies "user permissions" and "Agent permissions" based on the delegation chain, denying by default and opening up as needed. -- **Observability and Auditing**: Precipitates "who, on behalf of whom, called which tool/resource at what time" into audit events, which is convenient for troubleshooting, compliance, and internal control. +**Inbound Authentication**: Integrates with existing enterprise IdPs (user pools / OAuth / SSO, etc.), making "who can call the Agent" configurable and auditable. +**Agent Authoritative Identity**: Provides a unique and verifiable identity principal for the Agent, which is convenient for policy binding and audit attribution. +**Outbound Credential Hosting (Token Vault)**: Separates the storage, refresh, and minimization of authorization of OAuth / API Keys from the business code; by default, "credentials do not land on the ground." +**Fine-grained Permission Control**: Combines and verifies "user permissions" and "Agent permissions" based on the delegation chain, denying by default and opening up as needed. +**Observability and Auditing**: Precipitates "who, on behalf of whom, called which tool/resource at what time" into audit events, which is convenient for troubleshooting, compliance, and internal control. ## Experiment List @@ -43,14 +43,13 @@ Agent Identity governs the "user → application → Agent → resource" link se ## Core Features -- **Identity Authentication (Inbound)**: Verify user identity, only authorized users can access the Agent -- **Credential Hosting (Outbound)**: The Agent securely accesses external services such as Feishu, and the credentials are managed by the platform -- **Permission Control**: Fine-grained permissions based on the delegation chain to control the resources that the Agent can access - +**Identity Authentication (Inbound)**: Verify user identity, only authorized users can access the Agent +**Credential Hosting (Outbound)**: The Agent securely accesses external services such as Feishu, and the credentials are managed by the platform +**Permission Control**: Fine-grained permissions based on the delegation chain to control the resources that the Agent can access ## Directory Structure Description -``` +```bash 03-agentkit-identity/ ├── README.md # This file ├── 01_userpool_inbound/ # Experiment 1: Inbound Authentication