角色 / Roles & 权限
一句话
Agent Network 用 4 个角色:owner / admin / member / viewer。你 utok_ 里带的角色决定你能调哪些 API。RFC-001 已于 v0.8 落地之后,没有"超级 master 钥匙",全部基于角色。
4 个角色对照
| 角色 | 典型用例 | 简介 |
|---|---|---|
| owner | network 创建者 / 唯一最高权 | 能改成员 + 能删 network + 全部 admin 操作 |
| admin | 团队负责人 / 受信运维 | 能加减成员 + 能改 hub 设置(注:/api/audit-log / /api/users 等 admin-only 端点是系统级 users.role='admin' 限定,不是 network admin;详见下方 hub 全局 admin 特殊) |
| member | 普通团队工程师 | 能创建 agent + 派 task + 看本网络数据(anet node start/stop/delete 是本地操作,不受角色门控 —— 见下方注 ※) |
| viewer | 实习生 / 审计员 / 只读对接 | 只能看,不能写 |
完整权限矩阵
| 操作 | viewer | member | admin | owner |
|---|---|---|---|---|
| 读 | ||||
看本网络任务 (anet tasks) | ✅ | ✅ | ✅ | ✅ |
看本网络 agent 列表 (anet status) | ✅ | ✅ | ✅ | ✅ |
| 看 messages / completions | ✅ | ✅ | ✅ | ✅ |
| 看 audit log(只自己的 row) | ✅ | ✅ | ✅ | ✅ |
| 看 audit log(其他人的 row) | 仅 系统级 users.role='admin'(不是 network admin) | |||
| agent 生命周期 | ||||
创建 agent (anet node create) | ❌ | ✅ | ✅ | ✅ |
启动 / 停止 / 删除 agent (anet node start/stop/delete) | 不受网络角色门控 —— 见下方注 ※ | |||
| 任务 | ||||
派任务 send_task | ❌ | ✅ | ✅ | ✅ |
取消任务 cancel_task | ❌ | ✅ | ✅ | ✅ |
转移任务 reassign_task | ❌ | ✅ | ✅ | ✅ |
| 成员管理 | ||||
邀请成员入网 (anet network invite) | ❌ | ❌ | ✅ | ✅ |
| 改成员 role | ❌ | ❌ | ❌ | ✅ |
| 移除成员 | ❌ | ❌ | ✅(不能移除 owner) | ✅ |
| network | ||||
| 创建 network | 任何登录用户都能在 hub 全局建(创建者自动成 owner) | |||
| 重命名 network | ❌ | ❌ | ❌ | ✅ |
| 删除 network | ❌ | ❌ | ❌ | ✅ |
hub 全局(系统级 users.role 门控,不是 网络角色) | ||||
看 /api/audit-log 自己的 row | ✅ | ✅ | ✅ | ✅ |
看 /api/audit-log 全部 row | 仅 users.role='admin'(verify server/src/index.ts:1086-1089) | |||
/api/users 看用户列表 | 仅 users.role='admin'(同上系统级) | |||
/api/server-logs 调试 console | 仅 users.role='admin' | |||
调 /api/admin/wipe-db 等危险操作 | 仅 users.role='admin' | |||
anet hub admin reset-user(重置任意用户密码) | 仅 hub 本机命令行调用,与角色无关(owner 本机权限即可) |
※
anet node start / stop / delete是纯本地 CLI 操作 —— 直接读写本机.anet/nodes/<alias>/目录,startCommand/deleteCommand里没有任何网络角色 / owner / per-creator 检查。谁的机器上有那份 node config,谁就能 start/stop/delete 它,跟该 user 在网络里是什么 role 无关。受网络角色门控的只有anet node create(要向 hub 换ntok_,canWrite挡 viewer)。
send_task/cancel_task/reassign_task三个 MCP 写工具只过一道canWrite门(role !== "viewer"—— owner/admin/member 都放行),没有 per-task ownership 检查 —— member 可以 cancel / reassign 网络里任何任务,不限「自己派的」。重命名 network 是 owner-only(auth.ts:218 renameNetworkif (net.owner_id !== userId)),跟「删除 network」一样,admin 不能改名。
每个角色细讲
viewer
给谁:实习生、审计员、想看不能动的人。
能干什么:
- 任何读接口(任务列表 / agent 状态 / messages / completions)
- 看 dashboard 主页面 / 浏览
不能干什么:
- ❌ 任何网络级写操作(派 task /
cancel_task/reassign_task/anet node create—— 都过canWrite门挡 viewer) - ❌ 看其他人的
/api/audit-logrow(系统级users.role='admin'才有跨用户访问;viewer 能看自己的 audit log row)
注:
anet node start / stop / delete是纯本地 CLI 操作,不受网络角色门控(见上方权限矩阵注 ※)—— viewer 在自己机器上仍能 start/stop/delete 已有的 node。受网络角色门控的只有anet node create(要向 hub 换ntok_)。
怎么变成 viewer:
# admin / owner 邀请时指定
anet network invite --role viewer --uses 1member
给谁:团队里参与生产的工程师,独立干活。
能干什么:
- viewer 的全部
- 创建自己的 agent (
anet node create) - 启动 / 停止 / 删自己的 agent
- 派 / 取消 / 转移任务
send_task/cancel_task/reassign_task(都只过canWrite门,所以 member 能取消 / 转移网络里任何任务,不限「自己派的」)
不能干什么:
- ❌ 改别人的 agent
- ❌ 加减 network 成员
- ❌ admin 接口
怎么变成 member:
anet network invite --role member --uses 5 # 默认就是 member
anet network join <code> # 用邀请码加入admin
给谁:团队负责人、受信运维、需要管成员的人。
能干什么:
- member 的全部
- 邀请新成员入网 + 移除非 owner 成员(invite
index.ts:695/ removeindex.ts:681:["owner","admin"]门控)
注:
anet node start / stop / delete/ 改 config 不是 admin 的网络角色特权 —— 它们是纯本地 CLI 操作(见上方权限矩阵注 ※),谁的机器上有那份 node config 谁就能管,跟网络角色无关。admin 不能远程 start/stop 别人机器上的 agent。
不能干什么:
- ❌ 改成员 role ——
PUT /api/networks/:id/members/:user_id是 owner only(index.ts:674if (callerRole !== "owner")直接 403);admin 只能 invite / remove,不能改已有成员的 role - ❌ 删除 network 本身(只有 owner 能)
- ❌ 移除 owner / 把别人升到 owner
- ❌ 看其他人的
/api/audit-logrow —— admin-only 端点是系统级users.role='admin'限定(不是 network admin);network admin 跟 viewer / member 一样只能看自己的 audit log row
怎么变成 admin:
# 方式 1:owner 创建邀请码(推荐)—— 对方用邀请码加入直接拿到 admin role
anet network invite --role admin --uses 1
# 方式 2:现有 member 升级 —— 走 REST(CLI promote 子命令 v0.10.15 仍未提供,排到 v0.11+ / 未排期)
curl -X PUT http://localhost:9200/api/networks/<net_id>/members/<user_id> \
-H "Authorization: Bearer <owner_utok>" \
-H "Content-Type: application/json" \
-d '{"role": "admin"}'
# 详见 [API — PUT members](/api/rest#put-api-networks-id-members-user-id)owner
给谁:network 创建者,全权最高,每个 network 至少 1 个 owner。
能干什么:
- admin 的全部
- 删除 network
- 改其他成员的 role(
PUT /api/networks/:id/members/:user要求 caller 是 owner —— admin 改不了成员 role)
特殊保护:
- ❌ 不能被 admin 改 role
- ❌ 不能被 admin 移除
- 如果 network 只剩一个 owner,不能降级 / 删除自己(避免无 owner 状态)
- ⚠ owner 角色不能授予给别人(
updateMemberRole/createInvite都显式拒owner,详见下方「怎么变成 owner」)—— 所以「多 owner」不是正常路径
怎么变成 owner:
- 创建 network 时自动是 owner:
anet network create <name> - ⚠ 不能通过 REST
PUT /members/:user_idpromote 到 owner —— server 拒绝(返回cannot assign owner role400,详见 API — PUT members 4xx)。owner 角色只能通过创建 network 获得
hub 全局 admin(特殊)
这跟 network admin 不一样
network 的 4 个 role(owner/admin/member/viewer)是绑定到某个 network 的。还有一个 hub 全局 admin(first-run 创建的 admin user)—— 这个 user 在所有 network 都自动是 admin,并且能调 hub 级管理接口。
| 操作 | network admin | hub 全局 admin (admin user) |
|---|---|---|
调 /api/audit-log 看自己的 row | ✅ | ✅ |
调 /api/audit-log 看其他人 row | ❌(server 自动 WHERE user_id = self 过滤) | ✅(看全部,index.ts:1086-1089) |
anet hub admin reset-user(重置任意用户密码) | ❌ | ✅(仅 hub 本机调用) |
| 创建新 user | ❌ | ✅(仅 hub 全局 admin) |
| 看 hub 所有 network | ❌(只看自己有 role 的) | ✅ |
角色信息存在哪
每个 utok_ 都绑了 (user_id, network_id, role) 三元组(在 api_tokens 表的 scope 字段)。
// server 端 auth 解析
const ctx = await resolveToken(req.headers.authorization);
// ctx = { user_id, network_id, role: 'admin' | 'member' | ... }
// endpoint handler
if (!isAdminLike(ctx.role)) return new Response("403", { status: 403 });CLI 不需要你输任何 role 信息 —— anet login 时 hub 把 role 写进 token,CLI 自动带着调接口。
升降级一个成员的角色
当前 stable 仍没有 promote / demote CLI 子命令
v0.9.x / v0.10.x 整条 stable 线都未触碰 member role 管理(每个 release 的具体改动见 changelog);完整 CLI 入口排到 v0.11+ / 未排期。目前列成员可以走 CLI,改角色 / 移除成员一律走 REST(详见 API — networks members)。
# 1. 列出当前 network 所有成员 + role(CLI,已实装)
anet network members
# 2. 改 bob 的角色为 admin(REST,owner only)
# role 字段不能传 'owner' —— 见 PUT members 4xx 表
# 注:anet whoami / anet network ls 输出的 network_id 截断到 12 字符,REST 调用需完整 id;
# 从 config.json 直接读才是完整 id
NET=$(jq -r .network_id ~/.anet/config.json)
UTOK=$(jq -r .token ~/.anet/config.json)
curl -X PUT "http://localhost:9200/api/networks/$NET/members/u_bob_xxx" \
-H "Authorization: Bearer $UTOK" \
-H "Content-Type: application/json" \
-d '{"role": "admin"}'
# 3. 移除 bob(REST,owner/admin)
curl -X DELETE "http://localhost:9200/api/networks/$NET/members/u_bob_xxx" \
-H "Authorization: Bearer $UTOK"完整 endpoint 文档:PUT members / DELETE members。
FAQ
Q:我 anet login 后是什么 role? A:anet whoami 输出的 Role: 是系统级 role(users.role —— admin 或 user),不是 per-network role(verify agent-network/bin/cli.ts whoamiCommand):
User: admin (u_xxxxxx)
Role: admin ← users.role 系统级('admin' / 'user'),不是 network role
Hub: http://127.0.0.1:9200
Networks:
default (net_xxxxxxxxx) ← current
my-team (net_yyyyyyyyy)要查当前 network 内你是 owner/admin/member/viewer 哪一个,跑 anet network members 看自己那行(绑定到 network_members 表,跟 users.role 系统级是两套独立 state)。
Q:能跨 network 用不同 role 吗? A:能。同一个 user 在 networkA 是 admin,在 networkB 是 viewer,完全 OK。每个 network 独立 role。
Q:默认 admin / anethub 账号是什么 role? A:first-run 创建时自动是 hub 全局 admin + default network 的 owner。
Q:能不能让一个 user 只在某个 network 是 admin、在 hub 全局不是? A:能。把他设为 network owner 即可(不给 hub 全局 admin)。
Q:viewer 真的什么都不能写吗,连派 task 都不行? A:对,连派 task 都不行。如果想"能看 + 偶尔派",给 member。
与 RFC-001 的关系
RFC-001 已于 v0.8.0 落地:COMMHUB_AUTH_TOKEN 进入软废弃(v1.0 完全移除),hub 鉴权完全基于本文档的 4 个 role:
- ✅ 没有 "master 钥匙" bypass role 检查
- ✅ 所有 admin 操作 = admin role
utok_+ role check - ✅ 所有 hub ↔ dashboard 内部通信 = admin user 的
utok_(Dashboard 已是 thin cookie-proxy)
这就是为啥要把 role 体系写清楚 —— 它是唯一的鉴权基础。
下一步
- CLI 操作 role:CLI 命令 — network 管理(
anet network members列成员;改角色走 REST PUT members,CLI promote/demote 排到 v0.11+ / 未排期) - Token 体系联动:Token 概念 — 4 个 role 跟 utok_/ntok_ 关系
- 完整安全模型:安全设计
- 升级 v0.7 → v0.8 怎么影响 role:升级指南
- RFC-001 路线图:RFC-001