Files
AgentLab/docs/zh-CN/identity-and-security.md
T
ThearchyHelios 2714890d0d 文档重新梳理:README 精简成介绍和索引,细节按主题拆进 docs/zh-CN 与 docs/en(17 篇一一对应),英文文档不含中文
README.zh-CN.md / README.md 只留:这是什么、为什么用它、主要功能(按领域一行一条,链到文档)、快速开始、部署、文档索引、
开发与测试、许可(原文不动)。原来的每一节按读者和任务分到 17 篇主题文档:ask-data、workflows、evidence、
data-sources(新增:接入数据库、只读保证、上传表格、跨库合并、遮罩列)、data-catalog、tools(新增:工具、审批档位、
能力登记、端点、网络规则——它们管所有工作流,不只应用)、apps、evaluation-and-ledger、schedules(含通知)、deployment、
configuration、postgresql-and-scaling、identity-and-security、architecture、development、upgrade-notes(按时间倒序,
每波先写要做的事)、faq。删掉的只有模块名(api/copilot_gen.py、chat/drive.py、data/schema_view.py)、重复的话和
「以前…现在…」的叙述;操作步骤、命令、配置名、限制、权限边界都有归宿。中文是原文,英文按新的中文写;英文里界面文字
只写英文名,开头注明界面目前只有简体中文,中文占位符换成英文占位符,中文数字的例子改成不依赖中文的说法。
数据剖析可以同时剖析 2–3 张表(baf23998)收进 data-catalog。
新增 scripts/check-docs.py:英文文档(README.md、docs/en/**)不许有中日韩字符和全角符号(代码块也算),
README、docs/**、deploy/README.md 的相对链接和锚点都要通,docs/zh-CN 与 docs/en 文件一一对应、标题层级相同。
中文提示里指向 README 章节的地方改指新文档:cluster/guard.py、cluster/version.py、db/base.py 两处报错,
data/schema_view.py 文档串,.env.example 三处,scripts/prod.sh、scripts/test-postgres.sh,terms.ts 两处、
DataSourcesTab.tsx、check-manage.mjs 注释,deploy/README.md 三处链接。deploy/agentlab.env 未动。
验收:check-docs 0 问题(英文文档 18 个 0 处中文,相对链接 369 条 0 断链,18 对标题层级一致);相关后端测试
117 通过、7 跳过;tsc -b、check-copy 通过。
2026-10-21 10:23:26 +08:00

129 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[English](../en/identity-and-security.md) | 简体中文
# 身份、权限与安全
这篇讲登录方式、角色和权限、遮罩对谁是边界、代码沙箱的隔离程度,以及其他安全边界。给管理员和运维看。
## 登录方式
有三种登录方式。环境变量 `AGENTLAB_AUTH_MODE`(`off` / `local` / `oidc`)优先于「设置 → 身份」。
- **off**(默认):`X-Actor` 自报署名,所有人等同管理员,应用首页上写明这一点。同一网络里打得开页面的人都能用全部功能:跑工作流、花你配的模型额度、读数据源、执行沙箱代码;审批和发起记的是各自填的署名,未经核实。只在信得过的网络里这样用;`dev.sh --host`、`prod.sh --host` 会监听所有网卡。
- **local**:用户名 + 密码(`hashlib.scrypt`)。从未开启过登录、在设置里切过来时,必须在同一次保存里建出第一个管理员。环境变量直接指定 `local` 的新部署,在登录页建第一个管理员(只在还没有管理员时可用)。
- **oidc**:通用 OIDC,授权码 + PKCE。飞书、企业微信这类非标准协议暂不支持。要配身份提供方地址、客户端标识和密钥,并至少配一个管理员映射(管理员用户名或管理员组)。每次登录按映射重算角色,`groups` 声明同步成只读的组。回调地址是 `<对外地址>/api/auth/oidc/callback`;在反向代理后面时设 `AGENTLAB_PUBLIC_URL`(见[配置](configuration.md#对外访问地址))。
### 会话
- 会话放在 HttpOnly、SameSite=Lax 的 cookie 里,库里只存 token 的哈希。
- 闲置 12 小时、最长 7 天过期(`AGENTLAB_AUTH_SESSION_IDLE_HOURS`、`AGENTLAB_AUTH_SESSION_MAX_DAYS`)。
- cookie 是否带 Secure,按请求是不是 https 决定;`AGENTLAB_AUTH_COOKIE_SECURE` 可以强制。
- 开了登录后,非 GET 请求必须带 `X-AgentLab-Request` 头;带了 `Origin` 的,必须是本站或 `AGENTLAB_CORS_ORIGINS` 里的地址。
- 登录连续失败后,等待时间逐次增加。
### 忘了密码
忘了密码、单点登录配错时,在服务器上执行:
```bash
cd backend && python -m app.auth reset-admin --username admin # 不给 --password 时随机生成并打印一次
```
## 角色与授权
角色:管理员 ⊇ 搭建者 ⊇ 使用者。
- 应用另有三档授权:使用、查看全部实例、管理。授给使用者的「管理」按「查看全部实例」算。
- 搭建者绑定岗位、授权时,从只读的人员名录里选(`GET /api/directory`:用户名、显示名、是否停用、组名)。名录里没有的、已停用的名字不让添加。
- 单点登录的人和组,第一次登录后才进名录;没进名录的,要确认后才添加。
- 开了登录后,发布、发起、数据导入的确认一律记登录的人,界面上不再有署名框。
## 权限表
| 能做的事 | 管理员 | 搭建者 | 使用者 |
|---|---|---|---|
| 问数据、助手 | ✓ | ✓ | 默认不能,管理员可在「设置 → 身份」开启 |
| 编排、探索运行、以已发布级发布、数据源、数据目录、定时任务、知识库、自定义工具 | ✓ | ✓ | ✗ |
| 以受管级发布、把受管工作流降为已发布、版本退役 | ✓ | ✗ | ✗ |
| 记录页、运行的实时推送 | ✓(别人的个人应用除外) | ✓(别人的个人应用除外) | 只限自己的问数据运行 |
| MCP 的 stdio、端点和凭据、能力治理、模型接入 | ✓ | 只读 | ✗ |
| 应用:使用 / 查看全部实例 / 搭建发布 | ✓ | 能用能看;管理要创建者或有管理授权 | 按授权使用、查看 |
| 共享蓝图:读、改、试运行、出发布单 | ✓ | 自己建的、自己管理的应用出自的 | ✗ |
| 建个人应用、刷新、提交审核 | ✓ | ✓ | 默认不能,管理员可在「设置 → 应用」开启 |
| 别人的个人应用:名称、拥有者、创建和更新时间,归档 | ✓ | ✗ | ✗ |
| 别人的个人应用:页面、刷新和试运行的运行、证据、附件、蓝图 | ✗ | ✗ | ✗ |
| 处理派给自己的待办、核实动作 | ✓ | ✓ | ✓ |
| 用户、组、登录方式、审计 | ✓ | ✗ | ✗ |
## 使用者的问数据
管理员开启后,使用者的问数据只能发起探索运行:
- 图里只许这些节点:输入、模型调用、Agent、报告撰写、成果、知识检索、数据整形、条件分支、口径卡、合并查询、调用工具。
- Agent 和调用工具节点都只能用数据源查询和只读的内置工具。
- 查询结果在工具边界先遮罩;数据源一律只读(调用工具节点和 Agent 走同一道);能力治理里改成写入的工具也不执行。
- 记忆范围固定为自己的。
- 对话按建立人隔离。
个人应用的图用同一份白名单(见[个人应用](apps.md#个人应用))。
## 哪些角色看得到原值
数据源设置的遮罩列:
- **对开了登录的使用者是边界**:查询快照按派生遮罩处理后才给;工具快照的原文、运行事件里的结果预览一律不给;工件按白名单给。
- **对搭建者、管理员,以及未开启登录时的所有人,遮罩只减少暴露**:完整快照仍能按工件 id 取到。
开了登录时,使用者能读原始运行记录、事件和实时流的,只有自己的问数据运行。别的运行(包括替他发起的口径对账)经应用页和证据接口读,展示的 SQL 里写着的遮罩值换成「已遮罩」。
## 审计
写进审计的:
- 管理类操作:登录方式、用户和角色、组、端点、能力治理、应用发布、版本退役。
- 访问密钥的建、撤销、轮换、开关;每次用密钥的请求记一条,保留 90 天(见[访问密钥](apps.md#访问密钥))。
- 分享链接的建和撤销(打开只计次数)。
- 报告导出和可验证报告下载(`report.exported`)。
## 代码沙箱
代码节点和工具里的 Python 在沙箱里执行。沙箱分两档:
- **轻量档**:操作系统自带的访问控制。macOS 用 Seatbelt(`sandbox-exec`),Linux 用 bubblewrap。冷启动约 25ms,不用额外安装。
- **重量档**:microVM(libkrun + Hypervisor.framework),启动带独立内核的虚拟机。
两档共同保证三项约束:**默认断网**、**家目录不可读**、**只有工作区可写**。
- Seatbelt 的策略由内核强制,对子进程也生效:沙箱里用 `subprocess` 启动的 `cat` 读家目录,同样返回 `Operation not permitted`。
- 解释器刻意用 `sys.base_prefix` 下的干净 Python,不用项目环境,所以沙箱代码 import 不了 FastAPI、SQLAlchemy 和任何处理凭据的模块。
- bubblewrap 沙箱不继承后端的环境变量。
**Seatbelt 的局限**:它提供访问控制,不是虚拟化。
- 进程表共享,看得到宿主机的进程列表。
- 代码以当前用户身份运行,不像容器那样降权到 nobody。
- **macOS 不强制 `RLIMIT_AS`,内存用量限不住**:实测设了 256MB,仍能分配 900MB。CPU 时间、单文件大小、墙钟超时三项有效。
**microVM 补齐的正是内存这一项**。本机实测:宿主是 Darwin 27.0.0,VM 里是 Linux 6.12.99(libkrunfw 编译),PID 1 是 `init.krun`,VM 里没有 `/Users`,`free` 只显示 512MB。申请 900MB 会被内核的 OOM killer 终止,VM 本身存活——`RLIMIT_AS` 在 macOS 上形同虚设的问题,在这里不是被修好了,而是结构上不存在。两台 VM 之间也互相看不见。
microVM 的代价:运行时约 50MB;OCI 镜像**第一次拉取实测 54.5 秒**;缓存后热启动 0.19 秒,VM 里执行 7–30ms。成本集中在第一次,所以 auto 模式在镜像没缓存时优先用 Seatbelt,免得等一分钟(显式指定 strict 不受此限)。
都不可用时降级到 `local`,**不含任何访问控制**,界面标红。Docker 部署在没有 KVM 的机器上,隔离边界只有容器本身(见[部署](deployment.md#离线包里的代码沙箱))。怎么选后端、启用 microVM,见[配置](configuration.md#沙箱后端)。
### 网络隔离不完整
> **这一项必须放在前面说清楚。**
> `network=false` 时,HTTP/HTTPS 和域名解析都被切断,但 **UDP/53 拦不住**:实测手写的 DNS 包仍能拿到真实响应。`default_egress=DENY`、`Rule.deny_dns()`、显式 deny UDP、`max_connections=0` 都试过,UDP 通道始终堵不上(`deny_dns` 生成的规则只作用于宿主,DNS 出口在 microsandbox 的网络栈里硬编码放行)。
> 也就是说,**DNS 隧道这条外泄通道始终开着**。这层隔离足以防「代码意外联网装依赖」,不足以防「恶意代码窃取数据」。所以设置页把网络这一项标成黄色的「部分生效」,不标绿色——拦了一半却显示全绿,比显示全红更危险。真正的外泄防护要在网络层做。
## 安全边界
- **表达式**:分支条件等表达式用 AST 白名单求值器,不用 `eval`。
- **工具网络**:HTTP 工具逐 IP 检查、拦内网和元数据地址、不跟随重定向;内网只对登记了「允许访问内网」的端点开放;文件工具不出工作区(见[工具](tools.md#网络和凭据))。
- **数据库**:SQL 守卫、连接层只读、Oracle 要配只读账号(见[数据源](data-sources.md#只读保证))。
- **人工审批**:只认明确的批准(`true` / 同意 / approve),看不懂的回复一律按拒绝处理。MCP 与自定义工具默认每次调用都等审批(见[工具](tools.md#审批档位))。
- **密钥**:模型的 API Key 经 Fernet 加密落库,只向前端返回掩码;端点的认证头、自定义工具的请求头、MCP 的环境变量与请求头同样加密,只回掩码。
- **开了登录**:会话 cookie 在库里只存 token 的哈希;非 GET 请求核对来源标记头和 Origin;使用者只能读有授权的运行,看到的查询结果一律遮罩。
- **写外部系统**:必须经「调用工具」节点;先留生效记录再发送;确认卡上的内容哈希在发送前重算比对;结果未知永不自动重发(见[应用](apps.md#写外部系统))。
- **安全响应头**:`nosniff`、`Referrer-Policy`,以及 `frame-ancestors`(缺省 `'self'`;`AGENTLAB_FRAME_ANCESTORS` 列出允许嵌整站的同站门户;只有 `'self'` 时另加 `X-Frame-Options: SAMEORIGIN`)。严格的 `script-src` 目前只发 `Content-Security-Policy-Report-Only`,观察一个版本没有误报再强制。HSTS 交给反向代理。
- **系统代为发起的运行**:评测、口径对账、口径召回的证据照常可查,但不进使用统计,记录页默认不列。