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

11 KiB
Raw Blame History

English | 简体中文

身份、权限与安全

这篇讲登录方式、角色和权限、遮罩对谁是边界、代码沙箱的隔离程度,以及其他安全边界。给管理员和运维看。

登录方式

有三种登录方式。环境变量 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(见配置)。

会话

  • 会话放在 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 里的地址。
  • 登录连续失败后,等待时间逐次增加。

忘了密码

忘了密码、单点登录配错时,在服务器上执行:

cd backend && python -m app.auth reset-admin --username admin   # 不给 --password 时随机生成并打印一次

角色与授权

角色:管理员 ⊇ 搭建者 ⊇ 使用者。

  • 应用另有三档授权:使用、查看全部实例、管理。授给使用者的「管理」按「查看全部实例」算。
  • 搭建者绑定岗位、授权时,从只读的人员名录里选(GET /api/directory:用户名、显示名、是否停用、组名)。名录里没有的、已停用的名字不让添加。
  • 单点登录的人和组,第一次登录后才进名录;没进名录的,要确认后才添加。
  • 开了登录后,发布、发起、数据导入的确认一律记登录的人,界面上不再有署名框。

权限表

能做的事 管理员 搭建者 使用者
问数据、助手 ✓ ✓ 默认不能,管理员可在「设置 → 身份」开启
编排、探索运行、以已发布级发布、数据源、数据目录、定时任务、知识库、自定义工具 ✓ ✓ ✗
以受管级发布、把受管工作流降为已发布、版本退役 ✓ ✗ ✗
记录页、运行的实时推送 ✓(别人的个人应用除外) ✓(别人的个人应用除外) 只限自己的问数据运行
MCP 的 stdio、端点和凭据、能力治理、模型接入 ✓ 只读 ✗
应用:使用 / 查看全部实例 / 搭建发布 ✓ 能用能看;管理要创建者或有管理授权 按授权使用、查看
共享蓝图:读、改、试运行、出发布单 ✓ 自己建的、自己管理的应用出自的 ✗
建个人应用、刷新、提交审核 ✓ ✓ 默认不能,管理员可在「设置 → 应用」开启
别人的个人应用:名称、拥有者、创建和更新时间,归档 ✓ ✗ ✗
别人的个人应用:页面、刷新和试运行的运行、证据、附件、蓝图 ✗ ✗ ✗
处理派给自己的待办、核实动作 ✓ ✓ ✓
用户、组、登录方式、审计 ✓ ✗ ✗

使用者的问数据

管理员开启后,使用者的问数据只能发起探索运行:

  • 图里只许这些节点:输入、模型调用、Agent、报告撰写、成果、知识检索、数据整形、条件分支、口径卡、合并查询、调用工具。
  • Agent 和调用工具节点都只能用数据源查询和只读的内置工具。
  • 查询结果在工具边界先遮罩;数据源一律只读(调用工具节点和 Agent 走同一道);能力治理里改成写入的工具也不执行。
  • 记忆范围固定为自己的。
  • 对话按建立人隔离。

个人应用的图用同一份白名单(见个人应用)。

哪些角色看得到原值

数据源设置的遮罩列:

  • 对开了登录的使用者是边界:查询快照按派生遮罩处理后才给;工具快照的原文、运行事件里的结果预览一律不给;工件按白名单给。
  • 对搭建者、管理员,以及未开启登录时的所有人,遮罩只减少暴露:完整快照仍能按工件 id 取到。

开了登录时,使用者能读原始运行记录、事件和实时流的,只有自己的问数据运行。别的运行(包括替他发起的口径对账)经应用页和证据接口读,展示的 SQL 里写着的遮罩值换成「已遮罩」。

审计

写进审计的:

  • 管理类操作:登录方式、用户和角色、组、端点、能力治理、应用发布、版本退役。
  • 访问密钥的建、撤销、轮换、开关;每次用密钥的请求记一条,保留 90 天(见访问密钥)。
  • 分享链接的建和撤销(打开只计次数)。
  • 报告导出和可验证报告下载(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 的机器上,隔离边界只有容器本身(见部署)。怎么选后端、启用 microVM,见配置。

网络隔离不完整

这一项必须放在前面说清楚。 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 检查、拦内网和元数据地址、不跟随重定向;内网只对登记了「允许访问内网」的端点开放;文件工具不出工作区(见工具)。
  • 数据库:SQL 守卫、连接层只读、Oracle 要配只读账号(见数据源)。
  • 人工审批:只认明确的批准(true / 同意 / approve),看不懂的回复一律按拒绝处理。MCP 与自定义工具默认每次调用都等审批(见工具)。
  • 密钥:模型的 API Key 经 Fernet 加密落库,只向前端返回掩码;端点的认证头、自定义工具的请求头、MCP 的环境变量与请求头同样加密,只回掩码。
  • 开了登录:会话 cookie 在库里只存 token 的哈希;非 GET 请求核对来源标记头和 Origin;使用者只能读有授权的运行,看到的查询结果一律遮罩。
  • 写外部系统:必须经「调用工具」节点;先留生效记录再发送;确认卡上的内容哈希在发送前重算比对;结果未知永不自动重发(见应用)。
  • 安全响应头:nosniff、Referrer-Policy,以及 frame-ancestors(缺省 'self';AGENTLAB_FRAME_ANCESTORS 列出允许嵌整站的同站门户;只有 'self' 时另加 X-Frame-Options: SAMEORIGIN)。严格的 script-src 目前只发 Content-Security-Policy-Report-Only,观察一个版本没有误报再强制。HSTS 交给反向代理。
  • 系统代为发起的运行:评测、口径对账、口径召回的证据照常可查,但不进使用统计,记录页默认不列。