Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

认证与主体

每个到 daemon 的 RPC 连接都会在 initialize 握手期间绑定一个 principal,并且每次方法调用都会根据当前配置为该 principal 分配的权限进行检查。本页介绍 provider 集合、本地用户列表、权限配置文件,以及最重要的:现有远程连接会发生哪些变化。

按一次处理完成

  1. provider 负责验证单个凭据:握手中显式提供的 auth_token 会选中由 auth_provider 指定的 provider(默认为 native,即网关配对令牌);若未提供令牌,本地 Unix 套接字会将其内核对端 uid 提交给 peercred provider。被选中的 provider 一旦拒绝,该结论即为最终结果,凭据不会再尝试其他 provider。

  2. 共享解析器将已验证的身份映射为规范的主体 ID,以及配置为其分配的权限配置文件。OIDC 身份以已验证的 issuer + subject 作为键,本地名册身份则以其持久的 [users.<name>] 主体 ID 作为键。

  3. 每个 RPC 方法(除两个握手方法外)都被归类到所需的资源-动词授权,缺少该授权则拒绝访问。initialize 携带凭据本身,而 cert/renew 则通过提交它的双向 TLS 客户端证书进行身份验证,而非通过主体(principal)。细粒度选择器在此基础上叠加:

    • 配置写入会检查 config_write_paths;
    • session/new 和 session/prompt 会检查 agent 选择器,并将会话工作区限定在该 agent 策略允许读写的目录内,无论工作区是由请求指定的、随恢复的会话一同存储的,还是从持久化会话中恢复的。会话绑定到解析后的目录,而非请求中的写法,因此在准入之后重新指向符号链接形式的 cwd 不会改变会话的目录;以此类别名保持的活动会话会被拒绝。其他会话方法目前尚未检查 agent,详见此层尚未做的事情(待实现);
    • 运行或批准 SOP 时,需要具备其所运行的每个代理的权限,并遵循与会话相同的工具选择器规则;创建、保存或删除 SOP 时,同样需要具备其所运行代理的权限。未指定代理的步骤(无论是在步骤本身还是在流程上)视为按排序顺序排列的第一个已配置代理别名,即无头执行器回退使用的代理。每个步骤都计入在内,包括确定性流程中的步骤。
    • 附件、人格文件、指定了某个智能体的成本查询以及定时任务都会检查智能体选择器。通过本地路径发送的附件还必须指定一个目标智能体的策略允许其读取的绝对路径。舰队成本摘要的按智能体明细仅列出委托方的智能体,但其总计和按模型用量仍涵盖所有智能体;
    • fs/list_dir 仅列出启用的智能体(主体可使用的智能体)策略允许该智能体读取的绝对路径。它会拒绝相对路径、.. 组件,以及在 Windows 上的网络路径和设备路径。 这些根路径来自每个智能体解析后的策略:其风险配置文件、其 workspace.access 授予读取权限的同级工作区(对于会话工作区,还包括读写权限),以及只读的共享 skills 目录。非工作区限定的智能体(自治级别为 full、风险配置文件中设置了 workspace_only = false、使用 yolo 预设,或设置了 workspace.unrestricted_filesystem = true)可以读取任何不在禁止访问路径中的路径,因此有权使用此类智能体的主体,可以列出并打开该智能体能够访问的任意位置的会话。

    session/new 和 session/prompt 在等待会话队列之后会重复执行这些检查,因此在请求排队期间,如果其主体权限被收窄或凭证已过期,该请求轮到执行时会被拒绝。

授权对通过守护进程 RPC 配置方法所做的编辑即时生效,zerocode 的配置编辑器正是使用这些方法。以这种方式编辑 [permission_profiles]、[users]、[oidc] 或 security.trust_daemon_uid 时,会在保存时重新编译策略。已建立的原生令牌连接和本地连接会在下一次操作时重新解析,无需重新连接或重启;OIDC 连接则必须重新初始化。在守护进程之外所做的编辑,包括直接修改 config.toml、通过 Web 仪表板修改,或使用 zeroclaw config set,将在下一次守护进程重新加载或重启时生效。通过网关的配对控制撤销网关配对令牌后,使用该令牌认证的连接将在其下一次操作前失效。通过编辑配置(无论是通过 RPC 还是直接修改磁盘文件)从 gateway.paired_tokens 中删除令牌,对正在运行的守护进程没有任何影响,使用该令牌的连接仍保持授权。该删除将在下一次守护进程重新加载或重启时生效,除非在此之前通过网关进行的配对变更将包括该令牌在内的当前生效令牌集写回配置。请通过配对控制撤销令牌。

提供者

提供者凭据Configured by
nativeGateway 配对承载令牌Gateway 配对(/pair);守护进程与网关共享同一个实时令牌授权方
peercredUnix 域套接字上的对端 UID常开;[users.<name>].uid 将 uid 映射到一个命名主体
oidc.<alias>JWT 或不透明的 Bearer 令牌(来自您的 IdP)[oidc.<alias>]

本地连接

在 Unix 套接字上,未提供令牌的连接通过其内核对端 uid 识别。当 security.trust_daemon_uid 为 true(默认值)时,守护进程的自身 uid 会以受信任的共享操作员身份连接,并拥有完全访问权限,无论是否配置了 [users] 名单。因此,未配置名单的安装对于运行守护进程的账户,其行为与之前保持一致。

运行守护进程的操作员拥有其配置文件,而仅限本地的锁定恢复依赖于这一权限。在 Unix 套接字上,将 security.trust_daemon_uid 设置为 false,要求每个本地对端(包括守护进程自身的 uid)都必须通过名册映射或提供令牌。该设置对 Windows 命名管道无效,详见下文。

任何其他 uid 都必须通过显式的 [users.<name>].uid 条目进行映射。未映射的 uid(包括 root)如果未提供令牌,则会被拒绝,无论是否存在 roster;不会回退到共享操作员访问权限。监听器以仅所有者可访问的方式创建套接字,因此目前只有守护进程自身的账户和 root 能够访问它;roster 条目决定了其他任何 uid 在获得访问权限后可以执行的操作。

Windows 命名管道不携带对端 uid。在没有名册时,管道的 ACL 即为凭据,本地连接即视为共享操作员。一旦存在 [users] 名册,本地客户端必须在此出示令牌,security.trust_daemon_uid 不再生效,守护进程自身的账户也没有受信任的本地途径。在策略编译期间,已配对的网关令牌仍会被认证为共享操作员,因此发送该令牌的客户端(无论通过 WSS 还是通过管道)都可以在线修复名册。zerocode 的本地管道连接不发送令牌,因此若没有此类客户端,锁定状态需通过编辑 config.toml 并重启来修复。

客户端可以在 initialize 中转发其 shell 环境,使守护进程的子进程能够看到其 PATH 和凭据套接字(参见 环境变量透传)。该快照仅保留给操作员级别的主体(共享操作员,或设置了 admin = true 的名册主体)在本地连接上使用。其他所有主体以及所有远程连接,则改用守护进程自身的环境。

每次构建或恢复会话时都会重新检查资格。如果现有会话保留了非空的转发环境,则只有当前已获授权的本地操作员才能恢复或向其发送提示。通过 WSS 重新连接,或在提示排队期间失去 admin 权限,都不会将该环境带入下一轮:请求会在执行前被拒绝。若要在不使用转发环境的情况下继续,请创建新会话。没有转发值的会话仍可正常恢复,但需满足其他授权检查。保留的环境在会话生命周期内不可变;拒绝后续请求不会在已运行的轮次下方改写它。恢复时,当前连接的已授权环境还必须与会话保留的环境一致。若两者不同,请创建新会话;不含环境的会话在移除 admin 权限后仍可恢复。

恢复

远程身份验证绕过功能从不提供:远程连接始终必须出示有效凭据。在授权策略仍可编译的情况下,持有已配对网关令牌或操作员级主体的客户端可以从任何位置修复锁定状态。若没有此类凭据,并且始终处于全部拒绝状态时,恢复路径需在运行守护进程的主机上执行。适用哪种本地恢复路径,取决于策略是否仍可编译。

无法修改已能编译的策略。 授权已生效,本地可信路径在 Unix socket 上保持完好;在 Windows 上,请参见上文的命名管道说明。以守护进程自身的 uid 进行本地连接:在 security.trust_daemon_uid = true(默认值)下,该账户即为受信任的共享操作员,无论名单中如何设置。通过该本地连接修复有问题的条目,例如在 zerocode 的配置编辑器中,或使用 RPC config/set 设置 users.alice.uid,更改会在保存时编译并发布。编辑 config.toml 或运行 zeroclaw config set 同样可以修复,但只有在守护进程重新加载或重启之后才会生效。

因已接受的全拒绝状态而被锁定。 策略未能编译,因此已接受的状态会在解析运行之前拒绝所有主体,包括守护进程自身的 uid 和共享操作员。没有任何 RPC 能修复它:config/set 和 config/reload 与其他所有操作一样被拒绝。请以 config.toml 的所有者身份直接编辑该文件,然后重启守护进程,以便编译并发布已修复的部分。守护进程会忽略 SIGHUP,因此需要重启才能使其重新加载。

如果将 security.trust_daemon_uid 设置为 false,受信任 UID 途径就会失效。能够通过编译的策略,仍可能被出示已配对网关令牌的客户端,或拥有管理员授权的名册主体在运行时修复。否则,两种状态下的修复方式相同:以 config.toml 的所有者身份编辑该文件,然后重启。仅在可以接受的场景下关闭此设置。

用户名单

permission_profiles string[] · default []

[permission_profiles.<alias>] 条目,用于授予该用户的权限,按确定性并集合并。此项为必填;没有配置任何 profile 的用户无法通过身份验证。

将它放置在任何表面上:

网关仪表板

打开 /config/users,并设置 users.<alias>.permission_profiles 字段。

zerocode

在 Config 窗格中,设置 users.<alias>.permission_profiles 字段。

zeroclaw config

zeroclaw config set users.<alias>.permission_profiles <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_users__<alias>__permission_profiles=
principal_id string? · default null

持久化的主体标识符,用于此条目;默认为条目名称。审计记录以此 id 为键,而非条目名称;在主体专属存储功能上线后,会话、记忆和审批的归属也将以此为键。若要重命名条目而不使其数据成为孤立数据,请在同一次编辑中将 principal_id 设置为原始 id。更改条目的有效主体 id 会创建一个新主体。

将它放置在任何表面上:

网关仪表板

打开 /config/users,并设置 users.<alias>.principal_id 字段。

zerocode

在 Config 窗格中,设置 users.<alias>.principal_id 字段。

zeroclaw config

zeroclaw config set users.<alias>.principal_id <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_users__<alias>__principal_id=
uid integer? · default null

Unix uid accepted for this user over the local socket (peer credential). Required today: it is the only roster credential the accepted provider set supports.

Wait, the input above is the string to translate, and I should translate it, not repeat it. Translation:

通过本地套接字(对端凭据)为此用户接受的 Unix uid。当前必需:它是已接受的提供方集合所支持的唯一 roster 凭据。

将它放置在任何表面上:

网关仪表板

打开 /config/users,并设置 users.<alias>.uid 字段。

zerocode

在 Config 窗格中,设置 users.<alias>.uid 字段。

zeroclaw config

zeroclaw config set users.<alias>.uid <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_users__<alias>__uid=

条目名称在未通过 principal_id 显式指定时,即作为持久的主体 ID。审计记录当前即以该 ID 为键。会话、记忆和审批尚未以其为键(参见 本层尚未实现的功能),但未来将会如此。因此,若要重命名条目而不使其数据日后失去关联,请在同一次编辑中将 principal_id 设置为原始 ID。

OIDC

每个 [oidc.<alias>] 条目对应一个与单一颁发者(issuer)的信任关系;令牌验证(离线 JWKS 或 RFC 7662 内省)、声明映射以及生命周期上限的说明,请参阅该章节的参考文档:

actor_claim string · default ""

指向颁发者仅为某一类主体(actor)令牌添加的声明(存在且非 null)的点分隔路径,例如 Auth0 在 client-credentials 令牌上的 gty,或 Okta 在用户令牌上的 uid。actor_claim_marks 指明该声明存在所证明的主体类型,缺失则证明另一类主体。对于同时签发人类令牌和机器令牌的客户端(未在任一客户端列表中声明)为必需项;同时会针对已声明的客户端进行检查,若出现矛盾证据则拒绝访问。留空时表示不进行基于声明的分类,因此每个被接受的客户端都必须已声明。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.actor_claim 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.actor_claim 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.actor_claim <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__actor_claim=
actor_claim_marks OidcActorKind · default "service"

actor_claim 的存在所证明的 actor 类型。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.actor_claim_marks 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.actor_claim_marks 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.actor_claim_marks <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__actor_claim_marks=
allowed_authorized_parties string[] · default []

允许的 azp(授权方)值,即令牌签发给的客户端。为空表示不限制;非空表示令牌必须携带列在此处的 azp 声明,否则身份验证将失败并采取故障关闭(fail closed)策略。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.allowed_authorized_parties 字段。

zerocode

在 Config 面板中,设置 oidc.<alias>.allowed_authorized_parties 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.allowed_authorized_parties <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__allowed_authorized_parties=
audience string · default ""

Audience 是此守护进程的 aud 声明中必须携带的值(通常为在身份提供方(IdP)注册的客户端 ID 或资源标识符)。令牌验证时必需。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.audience 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.audience 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.audience <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__audience=
claim_path string · default ""

指向经过验证的声明的点分路径,该声明包含此部署的角色/组值(例如 realm_access.roles、groups)。必须显式设置:守护进程拒绝猜测权限授予信息在令牌中的位置。

将它放置在任何表面上:

网关仪表板

/config/oidc 打开页面,并设置 oidc.<alias>.claim_path 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.claim_path 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.claim_path <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__claim_path=
client_id string · default ""

Client ID:守护进程在机密流程(令牌内省;注册将在后续阶段实现)中用于身份验证的客户端 ID。留空时默认为 audience。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.client_id 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.client_id 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.client_id <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__client_id=
client_secret 🔑 secret · default null

客户端密钥,用于机密客户端流程(令牌内省)。JWKS 验证不需要此项。静态加密存储。

将它放置在任何表面上:

网关仪表板

/config/oidc 打开页面,并设置 oidc.<alias>.client_secret 字段。

zerocode

在 Config 面板中,设置 oidc.<alias>.client_secret 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.client_secret    # 掩码输入,加密存储

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__client_secret=
interactive_clients string[] · default []

此类客户端的令牌始终对应人类主体(授权码 / 设备码客户端),按已验证的 client_id 声明进行匹配。其令牌必须包含非空的 sub,并能通过 profile_map 解析。同一客户端只能出现在 service_clients 和 interactive_clients 之一中。

将它放置在任何表面上:

网关仪表板

/config/oidc 打开页面,并设置 oidc.<alias>.interactive_clients 字段。

zerocode

在 Config 面板中,设置 oidc.<alias>.interactive_clients 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.interactive_clients <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__interactive_clients=
issuer string · default ""

与已验证令牌中的 iss 声明完全一致的颁发者 URL(例如 https://sso.example.com/realms/main)。发现文档从 <issuer>/.well-known/openid-configuration 获取,其中的 issuer 字段必须与此值完全一致。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.issuer 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.issuer 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.issuer <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__issuer=
max_auth_lifetime_secs integer · default 86400

最长认证有效期(秒),适用于离线验证(JWKS)的令牌。离线验证无法感知吊销状态,因此身份将在令牌的 exp 与 iat 加上该上限值两者中的较早时间点过期。必须大于 0。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.max_auth_lifetime_secs 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.max_auth_lifetime_secs 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.max_auth_lifetime_secs <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__max_auth_lifetime_secs=
profile_map map · default {}

映射在 claim_path 处找到的声明值到 [permission_profiles.<alias>] 名称。没有映射的声明值不授予任何权限;未映射到任何配置文件的身份将被拒绝。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.profile_map 字段。

zerocode

在 Config 窗格中设置 oidc.<alias>.profile_map 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.profile_map <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__profile_map=
require_at_jwt bool · default true

要求对 JWKS 验证使用 RFC 9068 定义的 typed JWT 配置文件。不透明令牌仅在通过已配置的内省端点时保持有效。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.require_at_jwt 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.require_at_jwt 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.require_at_jwt <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__require_at_jwt=
require_mfa bool · default false

要求令牌通过身份提供方(IdP)的聚合 mfa 标记或已接受的已配置 ACR 证明已完成多因素认证,之后才能认证成功。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.require_mfa 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.require_mfa 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.require_mfa <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__require_mfa=
required_acr string[] · default []

可接受的 acr(认证上下文类)值。留空表示无要求;非空时,令牌的 acr 声明必须是其中之一,否则认证失败(fail closed)。

将它放置在任何表面上:

网关仪表板

在 /config/oidc 中打开页面,并设置 oidc.<alias>.required_acr 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.required_acr 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.required_acr <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__required_acr=
revalidation_secs integer · default 60

内省模式的重新验证间隔(秒):为每个身份标记的截止时间,超过该时间后,下一次特权操作必须重新内省,否则以失败关闭方式拒绝。0 表示在每次特权操作时都重新验证。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.revalidation_secs 字段。

zerocode

在 Config 面板中,设置 oidc.<alias>.revalidation_secs 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.revalidation_secs <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__revalidation_secs=
service_clients string[] · default []

其令牌始终为服务主体的客户端身份(client_credentials 调用方),与令牌经过验证的 client_id 声明进行匹配。服务主体以颁发者加客户端身份作为键,永远不会继承人类用户的假设,无论其 sub 采用何种提供方特定的格式(<client>@clients、服务账户用户 ID,或客户端 ID 本身)。主体分类是声明式的,绝不根据 sub 与 client_id 之间的关系推断:令牌为服务,是因为其客户端列于此处;为人类,是因为其客户端列于 interactive_clients 中;或者依据 actor_claim 进行分类。若令牌的客户端未在任何地方声明,且不包含已配置的 actor_claim 证据,则拒绝该令牌。同一客户端只能出现在两个列表之一中。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.service_clients 字段。

zerocode

在 Config 窗格中设置 oidc.<alias>.service_clients 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.service_clients <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__service_clients=
service_profile_map map · default {}

将 SERVICE 客户端已验证的 client_id 映射到 [permission_profiles.<alias>] 名称。服务主体仅通过此映射解析,绝不通过 profile_map 解析,因此机器凭证无法从名称相似的声明继承人工用户的配置文件。没有对应条目的服务 client_id 虽已通过身份验证,但不享有任何权限(失败即关闭)。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.service_profile_map 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.service_profile_map 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.service_profile_map <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__service_profile_map=
validation OidcValidation · default "jwks"

受理的令牌如何校验。

将它放置在任何表面上:

网关仪表板

打开 /config/oidc,并设置 oidc.<alias>.validation 字段。

zerocode

在 Config 窗格中,设置 oidc.<alias>.validation 字段。

zeroclaw config

zeroclaw config set oidc.<alias>.validation <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_oidc__<alias>__validation=

注册(获取用于出示的令牌)

守护进程仅负责验证令牌;客户端需从身份提供方(IdP)获取令牌。CLI 内置两种无浏览器流程:

# 通过设备授权许可(RFC 8628)进行交互式登录:
# prints a verification code to enter in any browser, waits for
授权后,将访问令牌写入标准输出。
export ZEROCLAW_AUTH_TOKEN="$(zeroclaw oidc login corp)"

# 同样通过系统浏览器:Authorization Code + PKCE(仅 S256)
# with an RFC 8252 one-shot loopback listener. The mechanisms never
# 相互融合。
export ZEROCLAW_AUTH_TOKEN="$(zeroclaw oidc login corp --browser)"

# 通过 client_credentials 使用无界面服务主体(需要
# entryś的 client_secret):
export ZEROCLAW_AUTH_TOKEN="$(zeroclaw oidc token corp)"

进度消息输出到 stderr,stdout 仅输出令牌,因此两个命令都可以与命令替换组合使用(oidc 命令会在任何可能输出内容的启动前置步骤之前运行,包括 OTP 种子披露)。不会存储任何内容:请在令牌过期前,将其作为 auth_token 在 RPC 握手中提交(或通过环境变量提供),然后重新注册。

客户端只信任条目中指定的 issuer,不信任其他任何来源。发现文档(discovery document)必须明确声明该 issuer 与之完全一致,之后才能使用其中公布的任何端点。凡是会接收凭据的端点,都必须满足与 issuer 相同的 URL 策略:使用 https,或仅当主机为精确的回环地址时才允许使用 http。重定向一律不跟随,响应正文有大小上限。只有包含非空 Bearer 访问令牌的令牌响应才会被接受。机密客户端(条目中包含 client_secret)在每个请求中都使用 HTTP Basic 进行认证;公共客户端则在表单中发送其 client_id。

--browser 在 macOS 和 Linux 上会为你自动打开系统浏览器,并且在所有平台上都会打印登录 URL,以便你在同一台机器的浏览器中手动打开(回调会发送到运行 CLI 的主机上的本地回环端口)。浏览器启动程序与 CLI 的标准流分离运行,因此启动程序自身写到 stdout 的任何内容都无法污染结果:stdout 仍然只输出令牌。

两个回调适配器(CLI 的回环监听器和网关回调)都会执行 RFC 9207 的 issuer 校验。如果响应中的 iss 参数与发起该流程的 issuer 不匹配,则在处理其中的 code 或 error 之前直接拒绝。如果响应中完全没有 iss,则予以接受,因为该参数是可选的,并非所有 issuer 都会发送它。当代码交换在返回访问令牌的同时返回了 id_token,该 id_token 会被完整校验(包括 issuer、audience、过期时间以及与本次流程绑定的 nonce),校验通过后随即丢弃。只有访问令牌会被提交给守护进程。注册客户端对发现过程本身同样保持怀疑:在使用其中列出的任何端点之前,它会拒绝 issuer 与所配置 issuer 不完全一致(包括末尾斜杠)的 .well-known/openid-configuration 文档(即 RFC 8414 校验),并且会限制所读取文档的大小,从而确保恶意或故障的 issuer 无法将流程重定向到其自选的端点,也无法返回无上限的响应体。

不持有 IdP 凭据的客户端(Web 仪表盘、zerocode)改为通过网关完成注册,网关使用已配置条目的客户端凭据代理相同的流程:GET /api/oidc/providers 列出别名,POST /api/oidc/{alias}/device/start 和 /device/poll 驱动设备授权流程,GET /oidc/login/{alias} 运行浏览器流程。其一次性回调页面通过 postMessage(仅限同源)将令牌交给打开它的窗口,并提供手动复制的备用方式。网关还会发送 Cross-Origin-Opener-Policy: same-origin,该响应头会在弹窗经由身份提供方跳转后切断 window.opener,因此在当前浏览器中,该页面上的手动复制是目前可用的交接方式,而 postMessage 约定已就位,供仪表盘后续开发使用。这些路由因注册先于认证而必然无需认证,并受速率限制,且不授予任何权限:它们只是转发用户批准后 IdP 所授予的内容。设计原理与故障模式表见仓库中的 docs/security/oidc-browser-pkce-design-8289.md。

速率限制分层生效。启动流程的请求(POST /api/oidc/{alias}/device/start、GET /oidc/login/{alias} 和 GET /oidc/callback)会计入注册专用的网关暴力破解限制器实例。该实例与错误配对令牌所适用的阈值和锁定机制相同,但使用独立的计数账本,因此被注册阶段锁定的地址仍可进行配对或提交 Webhook 签名,而在这两者上触发的锁定也不会阻止注册。

只有无效的回调才计为一次尝试:所携带的 state 没有对应的有效流程状态、颁发者不匹配、身份提供方返回错误、缺少授权码、流程进行中别名已被删除,或代码交换失败。成功完成登录的回调不计费,网关因中继容量已满而拒绝的回调同样不计费,这样大量同时登录的用户不会锁定其共享地址。因待处理流程存储已满而被拒绝的浏览器登录同样不计费,原因相同。

提供方列表、设备轮询和登录启动请求,每个客户端的预算为每分钟 20 次请求。这一额度高于 RFC 8628 规定的五秒最小轮询间隔(每分钟 12 次轮询),留有余量,同时又能防止客户端疯狂轮询。当身份提供方返回 slow_down 或直接拒绝设备码时,该轮询计为一次尝试,因此提交无效设备码的客户端会触发现有锁定机制,而不会无限轮询。网关与身份提供方之间链路上的传输失败与调用方无关,不计入其费用。

客户端超出预算或处于锁定状态时,会收到 HTTP 429 响应,并附带以秒为单位表示延迟的 Retry-After。zerocode 会至少等待该延迟时长,且不少于 RFC 规定的五秒递增间隔,然后才发起下一次轮询(仍受设备码剩余有效期限制)。无论何种情况,zerocode 的轮询频率都不会超过每五秒一次。

所有客户端共同进行的对身份提供方的出站中继,同时最多有 16 个在进行中,从而限制网关代所有客户端对身份提供方的访问规模。

待处理流程存储最多同时容纳 32 个浏览器登录。单个远程客户端最多可占用 8 个名额,因此,一个只发起登录却从不完成的调用方,无法在这些流程存活的十分钟内独占该存储,影响其他人。

回环地址客户端与其他网关认证限制一样,免除各客户端的预算限制。因此,若反向代理与网关位于同一主机,则必须启用 trust_forwarded_headers,才能使各客户端限制作用于其背后的真实调用方。

每个注册响应除网关既有的 no-referrer 策略外,还会附加 Cache-Control: no-store 和 Pragma: no-cache,因为设备码和访问令牌都会在这些响应体中传输。

zerocode 通过同一 API 进行注册,其配置独立于会话连接。[connection.wss] enroll_url 指定网关的 HTTP 源,允许附加可选的路径前缀。除非指向环回地址(127.0.0.1、::1 或 localhost),否则必须使用 https://,因为设备码以及随后的访问令牌都会通过该连接传输。重定向不会被跟随,因此无法在事后引入明文跳转。注册连接使用与 WSS 链路相同的 [connection.wss.tls] 信任材料:配置的 CA、skip_verify 以及双向 TLS 客户端证书。当该材料未对证书进行校验时,zerocode 会在发送设备码之前而不是在令牌到达之后进行询问,并且询问的是注册源本身,它可能不是会话随后连接的守护进程。回答 always 会将该源记录到 skip_verify_routes 中。非交互式运行没有可供询问的对象,因此注册会在此处停止。zerocode 会将每次轮询等待时间限制在设备码的剩余有效期内,并且在设备码过期后不再轮询。对于声明的有效期超过一小时或轮询间隔超过五分钟的情况,它会直接拒绝,而不是对恶意的响应进行休眠等待。若通告的间隔为 0 或 1,则会提升至 RFC 8628 规定的五秒默认值,因此网关的响应不会使 zerocode 进入每秒一次的轮询,那样只会被每客户端配额拒绝。它接收到的令牌仅保存在内存中,且仅限于该会话。

权限配置文件

admin bool · default false

授予全部权限。为 true 时,其他所有字段均不生效。

将它放置在任何表面上:

网关仪表板

打开 /config/permission_profiles,并设置 permission_profiles.<alias>.admin 字段。

zerocode

在 Config 窗格中设置 permission_profiles.<alias>.admin 字段。

zeroclaw config

zeroclaw config set permission_profiles.<alias>.admin <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_permission_profiles__<alias>__admin=
allowed_agents string[] · default []

Agent 别名:持有此配置文件的用户可以绑定或调用的代理。留空则不授予任何代理;如需授予所有代理,请使用显式的 "*" 条目。

将它放置在任何表面上:

网关仪表板

打开 /config/permission_profiles,并设置 permission_profiles.<alias>.allowed_agents 字段。

zerocode

在 Config 窗格中,设置 permission_profiles.<alias>.allowed_agents 字段。

zeroclaw config

zeroclaw config set permission_profiles.<alias>.allowed_agents <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_permission_profiles__<alias>__allowed_agents=
allowed_tools string[] · default []

可能被持有者的智能体运行的工具名称。空列表表示不授予任何工具;若需广泛访问权限,必须显式包含 "*" 条目。此选择器与粗粒度的 tools = ["execute"] 授权组合使用,而非替代它:若未授予该项,则持有者的会话无论此处列出什么都将无工具可用。(注意:这与风险配置文件中的 allowed_tools 不同,后者中空列表表示不受约束;权限配置文件默认拒绝。智能体自身的风险配置文件策略仍会在此之上生效。)

将它放置在任何表面上:

网关仪表板

打开 /config/permission_profiles,并设置 permission_profiles.<alias>.allowed_tools 字段。

zerocode

在 Config 面板中,设置 permission_profiles.<alias>.allowed_tools 字段。

zeroclaw config

zeroclaw config set permission_profiles.<alias>.allowed_tools <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_permission_profiles__<alias>__allowed_tools=
config_write_paths string[] · default []

Dotted config path prefixes holders may write. A trailing .* grants the subtree (e.g. channels.*); a bare path grants that exact prop; "*" grants every path. Empty grants NO paths.

Wait — the source is English, so I should translate it. Here is the translation:

持有者可以写入的点分配置路径前缀。以 .* 结尾表示授予整个子树(例如 channels.*);裸路径表示仅授予该确切属性;"*" 表示授予所有路径。空值表示不授予任何路径。

将它放置在任何表面上:

网关仪表板

Open /config/permission_profiles 并设置 permission_profiles.<alias>.config_write_paths 字段。

zerocode

在 Config 面板中,设置 permission_profiles.<alias>.config_write_paths 字段。

zeroclaw config

zeroclaw config set permission_profiles.<alias>.config_write_paths <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_permission_profiles__<alias>__config_write_paths=
grants map · default {}

资源类授权:针对每种资源类型,允许的操作。资源包括:system、sessions、memory、cron、config、agents、cost、skills、personality、logs、tui、files、locales、quickstart、channels、providers、models、peer_groups、plugins、tools、sops。操作包括:create、read、update、delete、execute。未列出的资源一律拒绝访问。

将它放置在任何表面上:

网关仪表板

打开 /config/permission_profiles,并设置 permission_profiles.<alias>.grants 字段。

zerocode

在 Config 面板中,设置 permission_profiles.<alias>.grants 字段。

zeroclaw config

zeroclaw config set permission_profiles.<alias>.grants <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc、~/.zshrc、.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_permission_profiles__<alias>__grants=

配置文件默认拒绝访问:未列出的资源会被拒绝,空的选择器列表不授予任何实例,广泛访问需要显式的 "*" 选择器或 admin = true。多个配置文件通过并集合并。对于定时任务、附件、人格文件、按代理的成本查询以及 SOP 编写,allowed_agents = ["*"] 仅覆盖配置中定义的代理,不覆盖请求中指定的任何别名。

工具选择器在智能体组装时通过交集组合,并在粗粒度授权之上生效:面向模型的工具执行需要授予 tools = ["execute"],没有该授权的主体将获得一个不带工具的会话,无论其 allowed_tools 中列出什么内容,包括 "*"。在持有该授权的前提下,受限主体创建的会话仅接收其 allowed_tools 所列出的工具(空列表将产生一个不带工具的会话),且仍受智能体自身风险配置所允许范围的约束。排队的提示词被接受后,将通过共享解析器重新检查授权,包括凭证过期和吊销。当前主体选择器会收窄静态工具、延迟搜索注册表、已激活的工具以及固定的 MCP 资源内容(每个固定内容块以其 <server>__<uri> 名称被接纳,一旦选择器不再指定该名称,它就会从后续提示词中撤回);已移除的工具无法被重新激活。复用的会话会在其下一轮对话之前被收窄,而重新水合的会话则依据当前授权重新构建。智能体选择器会在每轮对话之前以及重新水合之前进行检查。

收窄权限绝不会向已有的 agent 重新添加工具。扩大授权之后,需要创建一个新会话,以接收扩展后的工具范围。agent 中不会存储新的配置快照,也不会存储独立的主体策略缓存。

延迟 MCP 指令源自剩余可加载的工具,且仅在暴露 tool_search 时显示。主体若要按需激活,需同时具备 tool_search 和指定的延迟 MCP 工具;该辅助工具绝不会被隐式授予。获准的 mode = "always" MCP 工具会被预激活,无需辅助工具即可保持可调用。

如果主体的工具选择器或代理选择器中任一受限,则 delegate(有界且独立)、spawn_subagent 和 execute_pipeline 均不可用,包括包装这些工具的技能别名。这些嵌套路径目前尚未同时承载两个当前的主体上限;普通的父轮次仍可正常使用。管理员主体以及两个选择器均设为 "*" 的主体,保留其代理所配置的嵌套能力。

现有的八参数 Rust 构造函数 Agent::from_live_config_with_tui_env 仍然可用。RPC 使用新增的 from_live_config_with_tui_env_and_principal_tools 构造函数,并在提示词准入时重新应用共享解析器的授权。

该组合并未覆盖通往 agent 工具的所有途径。Cron 任务和 SOP 编写仅检查 agent 选择器。持有 cron 授权的受限主体可以为其 agent 创建 shell 任务,或为现有的 agent 任务设置新的提示词并触发它;持有 SOP 创建或更新授权的主体可以保存一个流程,其触发器会在之后运行该流程。应将 cron 和 SOP 编写授权视为对 agent 工具的授权。

破坏性变更:远程 WSS 需要身份验证

从本次变更起,远程 WSS 连接必须在 initialize 中提供 auth_token。不存在未经身份验证的远程回退方案。

一个启用了 [wss] 的监听器,如果不存在任何可用的凭证路径(既没有 [oidc.<alias>],也没有已配对的令牌,且 gateway.require_pairing = false),会被配置校验拒绝,因此没有任何受支持的途径能够保存这种配置。已经存在于磁盘上、呈现此形态的配置仍然可以启动:守护进程会正常运行,而该监听器会拒绝所有远程握手。它不会拒绝加载,因为操作人员必须能够启动守护进程,才能修复该配置。

无效的 [oidc.<alias>]、[users] 或 [permission_profiles] 配置段属于另一种情况。此时授权策略本身无法编译,因此守护进程会安装全部拒绝的接受状态,并记录日志说明其正在这样做,直到修复这些配置段并重新加载为止。在该状态下,所有主体都会被拒绝,无论远程还是本地连接,包括守护进程自身的 uid。因此,修复方法是上文「Recovery」一节所述的磁盘端修复。

迁移现有远程 zerocode 用户:

  1. 与网关配对,以获取 Bearer 令牌。

  2. Give zerocode the token, either in its config:

    [connection.wss]
    uri = "wss://daemon.example.com:9443"
    auth_token = "zc_..."
    

    或者通过 ZEROCLAW_AUTH_TOKEN 环境变量进行设置,该变量会覆盖配置文件中的值,并使凭据不必写入文件中。

    或者通过指定包含它的文件:

    [connection.wss]
    uri = "wss://daemon.example.com:9443"
    auth_token_file = "/etc/zeroclaw/zerocode-bearer"
    

    优先级依次为 ZEROCLAW_AUTH_TOKEN、auth_token_file、auth_token。在支持 Unix 权限位的平台上,如果被引用的文件可被其他任何账户读取,则会跳过该文件并发出警告,而不是使用它,随后按该顺序应用下一个来源。在其他平台上,文件的 ACL 是唯一的防护措施。

    环境变量是推荐的方式。如果改为将令牌保存在配置文件中,zerocode 会将该文件设置为仅所有者可访问(0600,位于权限为 0700 的配置目录中),并修复早于此行为生成的文件的权限模式,前提是平台支持 Unix 权限位。在不支持权限位的平台上,目录 ACL 是唯一的保护措施,因此应将该文件视为机密信息。

OIDC 访问令牌的工作方式相同,配置方式为 auth_provider = "oidc.<alias>"。

网关 HTTP API

网关的配置与引导路由(/api/config*、/api/quickstart/*、/api/channels/bind)在结构上强制执行身份验证:由一个路由层中间件统一守护整个路由组,因此没有任何单独的处理函数需要自行携带(或可能遗漏)鉴权检查。该中间件采用与 RPC 路径相同的主体(principal)模型,并通过相同的提供方注册表和解析器工作:

  • paired bearer(Authorization: Bearer zc_...)会解析为拥有完整权限的共享操作员,与之前的行为一致。拒绝访问时仍保持原有的 401 响应格式。
  • 使用 X-ZeroClaw-Auth-Provider: oidc.<alias> 请求头提交的 OIDC bearer 由该提供方验证,并解析为一个限定范围的主体(principal)。提供方的选择是显式的,与 RPC 握手中的 auth_provider 字段保持一致:被指定提供方的拒绝结果具有最终效力,且在不同提供方之间永不回退。
  • CORS 预检请求(OPTIONS)与以往一样无需认证即可通过。除 GET、HEAD、POST、PUT、PATCH 和 DELETE 之外的其他方法均会被拒绝。

受限主体的 Config 授权分两步执行。路由层按 HTTP 方法设置粗粒度下限:读取操作需要 read,其他操作至少需要 create、update 或 delete 之一,因此只读主体永远无法到达变更类处理器。随后,每个变更类处理器在执行第一个副作用之前,都会授权其完整写入集合:该变更将持久化的每个配置路径,按其对配置的影响分类(为新建路径为 create,为删除路径为 delete,其他情况为 update),并与配置档中的 config_write_paths 选择器进行匹配。分类依据的是操作本身,而非 HTTP 方法:通过 POST /api/config/map-key 创建映射键,或通过 PUT 在新别名下隐式创建,都需要 create;JSON Patch 的 remove 和 DELETE /api/config/map-key 需要 delete;重命名需要源路径的 delete 和目标路径的 create;删除或重命名级联改写到其他位置的引用同样属于写入集合。只要有一个成员未获授权,整个变更(包括批量操作或级联操作)就会被拒绝,且不写入任何内容。对于无法预先枚举写入集合的操作(例如文件的 schema 迁移、Quickstart 应用),则必须具备 * 选择器。持久化边界会将即将写入的路径与处理器已授权的路径重新核对,因此处理器无法持久化超出其授权范围的内容。

策略仅在持久化边界处变更:写入配置的处理程序会将由该配置编译出的授权状态发布为下一个已接受的修订版本,每个请求都会根据当前已接受的快照进行验证和解析。请求路径上不会重新编译策略,因此读取配置后、并发持久化之前发出的请求,永远不会用较旧的策略覆盖较新的策略。对提供方验证设置、成员名册或配置档案的已持久化更改,将在下一个请求时生效。守护进程自身的 RPC 接口维护一份独立的实时配置,并通过网关写入标志触发的重新加载与同一状态保持一致。其他网关接口仍按各自处理程序执行配对检查,将在后续版本中采用该层。

凭据生命周期

  • 过期会在截止时间结束连接的授权;客户端需使用新的令牌重新初始化。
  • 内省重新验证:OIDC 内省身份带有重新验证截止时间;超过该时间后,下一次操作会被拒绝,直到客户端重新初始化(重新初始化会与 IdP 重新核验)。
  • 配对撤销会在该连接的下一次操作之前生效。
  • 日志订阅:打开的 logs/subscribe 流在每次投递时都会重新检查,并在凭据过期、配对被撤销或其主体失去 Logs:Read 权限后的第一次投递时结束。
  • 策略变更:保存配置时,若 [oidc]、[users]、[permission_profiles] 和 security.trust_daemon_uid 保持不变,则所有绑定保持原样。对其中任一项的修改都会发布新策略。原生令牌连接和本地连接会就地依据新策略重新解析,但守护进程不保存 OIDC 承载令牌,因此在客户端重新初始化之前,OIDC 连接的下一次操作会被拒绝。
  • tui_id/tui_sig 重连机制仅用于保持连续性:它保留 TUI 的注册表身份,但不授予任何权限。每次 initialize 都需要重新提交凭证。

会话隔离

每个由受限主体创建的会话,都会在运行时存储和磁盘上(聊天后端与 ACP 存储)标记该主体的 ID。受限主体只能看到和操作自己的会话:列表结果会被过滤;读取和修改操作统一返回“未找到或无所有权“的拒绝响应,不会探测会话是否存在;破坏性删除通过以所有者为条件的存储语句执行;进行中的审批请求仅能由其所属会话的所有者处理。此次变更之前创建的会话(或由非受限连接创建的会话)没有所有者:它们对非受限连接保持完全可见,对受限主体则不可见。

每个已认证的主体都获得 PRIVATE 记忆:其记忆操作读写一个按主体划分的 plane,该 plane 的所有者(owner)会出现在每条存储语句中,并与 agent、namespace 和 tenant 维度组合(同一个 key 在两个 agent 下对应两行记录)。plane 跟随主体的身份,而非管理员旁路:具名管理员的记忆就是其自身的私有 plane,因此提升或降级用户都不会隐藏其笔记,也不会改变其写入的目标。只有未认证的共享操作员默认位于共享 plane 上;持有管理员旁路的调用方可以在 memory/* 请求上显式指定 plane = "shared",此操作会被审计,而受限范围(scoped)的主体则不能这样做。

两个平面在两个方向上都互不干扰:共享写入既不能指定私有行的存储键,也不能覆盖私有行;私有写入不会转换共享行;普通导出和 markdown 快照只包含共享行;旧版批量清除也只作用于共享行。私有行则通过携带所有者信息的操作进行导出和清除。

会话由某个主体(principal)创建时,其内存句柄会在该会话的整个生命周期内绑定到该主体的私有平面,无论之后由谁发起提示。管理员恢复已回收的会话时,同样会在持久所有者的平面上恢复。因此,作用域会话中的内存工具和每轮召回从不访问共享平面。不存在任何授权可以向作用域会话开放共享平面。私有写入与共享写入经过相同的内容扫描和策略检查。启用内存审计后,私有操作会连同完整作用域一并记录审计日志。在尚不支持主体的内存后端(目前包括 markdown、lucid、postgres 和 qdrant)上,私有内存会以明确的拒绝信息失败关闭,而不会静默地取消作用域。对于作用域会话而言,这意味着其内存工具会拒绝执行。

从 [security.nevis] 迁移

Nevis IAM 集成已被移除。它从未接入任何认证路径,因此启用它从来不会对任何人进行认证,移除它不会改变任何线上行为。为了让旧的 config.toml 仍能加载,系统仍接受其配置表。守护进程在加载时会丢弃该表中的所有值,记录一条警告并指出替代方案,并在下一次保存时将该表从 config.toml 中删除。无论是完整保存,还是 CLI、仪表盘和 RPC 为单次编辑所使用的增量保存,都是如此。移除操作只影响该表,注释和其他配置段的字节内容保持不变。不会自动进行任何转换:替代方案所需的值(如 audience 和 profile 授权)是旧配置表从未包含的。

升级前,请将 config.toml 复制到受保护的位置。升级后每次保存时,都会在写入期间于该文件旁边生成 config.toml.bak,写入持久化完成后再将其删除,因此 .bak 不是长期有效的备份。你自行保留的任何副本仍包含已弃用的配置表,其中若配置了明文 client_secret,也会一并保存,因此应将这些副本视为机密材料;在不再需要时,请在身份提供方(IdP)处吊销 Nevis 客户端凭据。

Please paste the English strings you want translated, one per field, and I’ll translate each one to zh-CN.

[security.nevis] 字段|Replacement 替换| |-|备注
enabled无存在 [oidc.<alias>] 条目即可启用验证。
instance_url, realm[oidc.<alias>] issuerIdP 发布的发现文档中所声明的确切颁发者 URL;守护进程会拒绝 issuer 与此不一致的发现文档。
client_id[oidc.<alias>] client_id|Also used to build the interactive_clients / service_clients lists that classify who is signing in. 同时用于构建 interactive_clients / service_clients 列表,用来区分登录的客户端类型。| |-|
client_secret[oidc.<alias>] client_secret在启用 [secrets] encrypt 时,该值通过 secret store 加密后存储在磁盘上。validation = "introspection" 以及 client_credentials 服务登录都需要此项。它不会从旧表中复制过来,需要重新设置。
token_validation = "local"validation = "jwks"JWKS URI 来自颁发者的发现文档。
token_validation = "remote"validation = "introspection"需要机密客户端。
jwks_url不支持没有自定义 JWKS 覆盖项:密钥集 URI 必须由已配置颁发者的发现文档以 jwks_uri 形式公布。该 URI 可以指向其他端点;未公布的密钥集 URI 无法进行配置。
(none)[oidc.<alias>] audience必填,且为新增项。 这是身份提供方(IdP)为该守护进程签发的访问令牌中所包含的 aud;此前没有对应的配置项可沿用。
role_mapping[].nevis_role[oidc.<alias>] claim_path + profile_mapclaim_path 指定承载角色的声明(例如 groups);每个 profile_map 的键是声明值,每个值是 [permission_profiles.<alias>] 名称。匹配为精确匹配,不再像之前那样不区分大小写。
role_mapping[].zeroclaw_permissions(工具名称,或 "all")[permission_profiles.<alias>] allowed_tools + grants.tools = ["execute"]Profile 默认拒绝访问:allowed_tools 与粗粒度的 tools = ["execute"] 授权组合使用,其他所有资源类别(sessions、config、memory 等)都必须显式授权。"all" 最接近 admin = true,其范围远大于之前的“所有工具”。建议列出具体的资源授权。
role_mapping[].workspace_access不等价没有按工作区授予的权限。最接近的控制项是 allowed_agents,它将配置文件限定为特定的代理别名。
require_mfa[oidc.<alias>] require_mfa 和/或 required_acr
session_timeout_secsmax_auth_lifetime_secs(JWKS)/ revalidation_secs(introspection)

在重启之前先进行验证,以免因为拼写错误导致所有人被锁定在外(如果确实发生这种情况,恢复方法请参见 Local connections 下的 Recovery)。以下两种途径可以完成验证:

  • 通过守护进程的 RPC 配置方法(zerocode 的配置编辑器)写入新的 [oidc.<alias>] 和 [permission_profiles] 条目。守护进程会在保存或切换任何内容之前校验授权相关的配置段。如果 profile_map 指向不存在的目标,或缺少 audience,守护进程会拒绝该配置并给出原因,之前的策略保持生效。
  • 如果你手动编辑了 config.toml,请先从 CLI 运行 ZEROCLAW_AUTH_TOKEN="$(zeroclaw oidc login <alias>)"。它会加载编辑后的文件,拒绝未通过校验的 [oidc.<alias>] 条目(issuer、audience、校验模式、客户端字段)。成功时,它会使用配置的客户端对 IdP 执行一次真实登录,因此在守护进程基于这些配置重启之前,issuer、客户端 ID 和密钥均已确认有效。该命令只检查条目本身,不检查 profile_map 的目标。如果某个 profile_map 值指向的名称在 [permission_profiles] 中不存在,只有守护进程会发现,随后它会拒绝编译策略,并进入 Recovery 中描述的全部拒绝状态。因此,请在重启前人工核对这些名称,或改用 RPC 途径。

远程连接如果未提供任何凭据,则在所有情况下都会被拒绝;两种途径都不会开启此类连接。

回滚属于配置数据操作,而非代码回退:回退二进制文件只能恢复旧的类型,但已从 config.toml 中删除的表不会因此恢复。请放回升级前受保护的副本(或手动重新添加该表)。此次退役不会改变 schema 版本,因此降级后的二进制文件可以直接加载恢复后的文件,无需迁移步骤。

这一层目前不做的事情(暂未实现)

整合与治理会推导共享平面的数据行,且不会对私有会话运行。针对其他主体私有记忆的管理访问目前尚无可用路径(默认拒绝)。持有 Sops:Read 的主体可通过 sops/runs 和 sops/run-detail 查看每个流程的运行历史,无论这些流程以哪个代理身份运行,这一点与 cron 历史不同。网关 HTTP 路由保留其现有的配对检查,渠道身份不会解析到此主体模型中。

当 security.trust_daemon_uid = true(默认值)且策略编译通过时,守护进程自身的 uid 在 Unix 套接字上保留完全访问权限。因此,对于没有 [users] 名单、认证配置段有效的单操作员安装,其行为与之前保持一致。

权限配置文件用于限制主体通过 RPC 可以执行的操作,但它们并不能隔离主体促使智能体运行的代码。会话轮次、定时任务和 SOP 步骤均以守护进程账户身份运行。在 Unix 上,这些代码可以以守护进程的 uid 连接本地套接字:当 security.trust_daemon_uid = true(默认值)时,该 uid 即为共享操作员;否则,它将获得映射到该 uid 的名册条目所拥有的权限。在没有名册的 Windows 上,命名管道会使其成为共享操作员。这些代码还可以编辑 config.toml,守护进程会在下一次重新加载或重启时应用这些修改。设置 security.trust_daemon_uid = false 并不会改变这两种情况。仅将会话、定时任务或 SOP 的执行或编写权限授予您愿意赋予操作员访问权限的主体。只有能够使智能体进程无法访问套接字和 config.toml 的操作系统级约束,才能隔离这些代码。

有些配置路径本身就带有权限,因此除非 config_write_paths 的授权仅涵盖经过审核的叶子配置项,否则应将其宽泛授权视为运维人员访问权限。例如:

  • 一个能够写入 permission_profiles、users、oidc、security 或 gateway.paired_tokens 的主体可以授予自己任何权限;
  • 一个能够写入 agents、risk_profiles、cron、channels 或 provider 设置的主体,可以改变哪些 agent 运行、使用哪些工具,以及它们可以读写的位置;
  • 能够写入 mcp、mcp_bundles 或 tunnel.custom.start_command 的用户,可以选择由守护进程账户启动的程序。

Config:Update 还会授予 config/reload,它会应用磁盘上 config.toml 中的当前内容。

zerocode 的远程目录选择器会在守护进程的文件系统根目录处打开。没有运营方授权的主体,只有通过策略允许读取 / 的已启用代理(例如非仅限工作区的代理)才能列出该目录。对于其他此类主体,选择器会在该位置报告拒绝访问,直到其在允许的根目录内打开为止。