@agentunion/fastaun-browser 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +550 -464
- package/_packed_docs/CHANGELOG-validators.md +147 -0
- package/_packed_docs/CHANGELOG.md +550 -464
- package/_packed_docs/INDEX.md +201 -177
- package/_packed_docs/KITE_DOCS_GUIDE.md +38 -32
- package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +169 -116
- package/_packed_docs/aun-perf-audit-critical-bugs.md +315 -0
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +263 -260
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -2
- package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +1 -1
- package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +39 -16
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +8 -5
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +18 -19
- package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +1 -1
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +139 -746
- package/_packed_docs/protocol/08-AUN-E2EE.md +12 -10
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +117 -171
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +6 -0
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +1 -1
- package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -0
- package/_packed_docs/protocol/README.md +5 -4
- package/_packed_docs/protocol/aun-docs-guide.md +2 -2
- package/_packed_docs/protocol/index.md +12 -7
- package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +1 -1
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +13 -13
- package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +9 -9
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +15 -13
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +26 -18
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +35 -284
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +473 -442
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +11 -7
- package/_packed_docs/sdk/09-collab-rpc-manual.md +581 -550
- package/_packed_docs/sdk/09-group-rpc-manual.md +367 -433
- package/_packed_docs/sdk/09-message-rpc-manual.md +50 -28
- package/_packed_docs/sdk/09-payload-reference.md +3 -3
- package/_packed_docs/sdk/09-storage-rpc-manual.md +57 -20
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +18 -17
- package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +3 -2
- package/_packed_docs/sdk/INDEX.md +25 -24
- package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +6 -2
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +18 -9
- package/dist/agent-md.js.map +1 -1
- package/dist/bundle.js +1661 -1180
- package/dist/client/delivery.d.ts +13 -2
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +251 -46
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +36 -14
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +2 -2
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +1 -0
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +166 -50
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +14 -1
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +376 -126
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +5 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +187 -46
- package/dist/client.js.map +1 -1
- package/dist/collab/client.d.ts +8 -0
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +12 -0
- package/dist/collab/client.js.map +1 -1
- package/dist/errors.d.ts +0 -20
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +8 -51
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +9 -4
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +192 -31
- package/dist/facades.js.map +1 -1
- package/dist/group-fs.d.ts +17 -0
- package/dist/group-fs.d.ts.map +1 -1
- package/dist/group-fs.js +54 -11
- package/dist/group-fs.js.map +1 -1
- package/dist/group-id.d.ts +9 -12
- package/dist/group-id.d.ts.map +1 -1
- package/dist/group-id.js +41 -63
- package/dist/group-id.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +2 -54
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +3 -0
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +65 -0
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +3 -17
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +4 -47
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +1 -64
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +45 -774
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -1
- package/dist/storage/lowlevel.d.ts +9 -1
- package/dist/storage/lowlevel.d.ts.map +1 -1
- package/dist/storage/lowlevel.js +12 -1
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/vfs.d.ts +22 -0
- package/dist/storage/vfs.d.ts.map +1 -1
- package/dist/storage/vfs.js +54 -0
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.js +336 -49
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +2 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +96 -3
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +39 -56
- package/dist/types.d.ts.map +1 -1
- package/dist/v2/session/session.d.ts +2 -0
- package/dist/v2/session/session.d.ts.map +1 -1
- package/dist/v2/session/session.js +58 -22
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts +1 -1
- package/dist/v2/state/commitment.d.ts.map +1 -1
- package/dist/v2/state/commitment.js +5 -3
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/validators.d.ts +35 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +127 -0
- package/dist/validators.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/_packed_docs/collab-gateway-boundary-test-report.md +0 -164
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AID 和 Group ID 格式校验工具。
|
|
3
|
+
*
|
|
4
|
+
* 确保发送到服务端的目标标识符符合 AUN 协议规范,拒绝不合法的格式。
|
|
5
|
+
*
|
|
6
|
+
* 与 Python SDK aun_core.validators 保持等价(零代码共享,仅规范对齐)。
|
|
7
|
+
*/
|
|
8
|
+
import { ValidationError } from './errors.js';
|
|
9
|
+
import { convertToGroupAid } from './group-id.js';
|
|
10
|
+
// AID name 规范:4-64 字符,仅 [a-z0-9_-],首字符不为 -,不以 guest 开头
|
|
11
|
+
const AID_NAME_RE = /^[a-z0-9_][a-z0-9_-]{3,63}$/;
|
|
12
|
+
// Group ID 格式(基于服务端实际实现)
|
|
13
|
+
// Legacy 格式:g- 后接 4-32 位小写字母数字
|
|
14
|
+
const GROUP_ID_LEGACY_PATTERN = /^g-[a-z0-9]{4,32}$/;
|
|
15
|
+
// 新格式 base:5 到 64 位小写字母数字
|
|
16
|
+
const GROUP_ID_NEW_BASE_PATTERN = /^[a-z0-9]{5,64}$/;
|
|
17
|
+
// Group name 格式:4-64 字符,首字符 [a-z0-9],可包含 _-
|
|
18
|
+
const GROUP_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{3,63}$/;
|
|
19
|
+
// 域名基本格式(简化版,不做完整 DNS 校验)
|
|
20
|
+
const DOMAIN_RE = /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/;
|
|
21
|
+
/**
|
|
22
|
+
* 校验 AID 格式是否合法。
|
|
23
|
+
*
|
|
24
|
+
* 格式规范:{name}.{issuer}
|
|
25
|
+
* - name: 4-64 字节,仅 [a-z0-9_-],首字符不能是 -,不能以 guest 开头
|
|
26
|
+
* - issuer: 合法的可注册域名
|
|
27
|
+
*
|
|
28
|
+
* @param aid 待校验的 AID(可能是任意类型)
|
|
29
|
+
* @param paramName 参数名称(用于错误消息)
|
|
30
|
+
* @returns 规范化后的 AID(转小写、去空格)
|
|
31
|
+
* @throws ValidationError AID 格式不合法
|
|
32
|
+
*/
|
|
33
|
+
export function validateAIDFormat(aid, paramName = 'aid') {
|
|
34
|
+
if (aid === null || aid === undefined || (typeof aid === 'string' && aid.trim() === '')) {
|
|
35
|
+
throw new ValidationError(`${paramName} cannot be empty`);
|
|
36
|
+
}
|
|
37
|
+
const aidStr = String(aid).trim().toLowerCase();
|
|
38
|
+
// 检查是否包含点号(必须有 issuer)
|
|
39
|
+
if (!aidStr.includes('.')) {
|
|
40
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': must be in format '{name}.{issuer}'`);
|
|
41
|
+
}
|
|
42
|
+
// 分离 name 和 issuer(仅在第一个点号处分割)
|
|
43
|
+
const dotIdx = aidStr.indexOf('.');
|
|
44
|
+
const name = aidStr.slice(0, dotIdx);
|
|
45
|
+
const issuer = aidStr.slice(dotIdx + 1);
|
|
46
|
+
// 校验 name 部分
|
|
47
|
+
if (!name) {
|
|
48
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': name part cannot be empty`);
|
|
49
|
+
}
|
|
50
|
+
if (!AID_NAME_RE.test(name)) {
|
|
51
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': name '${name}' must be 4-64 characters, `
|
|
52
|
+
+ `only [a-z0-9_-], cannot start with '-'`);
|
|
53
|
+
}
|
|
54
|
+
if (name.startsWith('guest')) {
|
|
55
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': name cannot start with 'guest'`);
|
|
56
|
+
}
|
|
57
|
+
// 校验 issuer 部分
|
|
58
|
+
if (!issuer) {
|
|
59
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': issuer part cannot be empty`);
|
|
60
|
+
}
|
|
61
|
+
if (!DOMAIN_RE.test(issuer)) {
|
|
62
|
+
throw new ValidationError(`Invalid ${paramName} '${String(aid)}': issuer '${issuer}' is not a valid domain`);
|
|
63
|
+
}
|
|
64
|
+
return aidStr;
|
|
65
|
+
}
|
|
66
|
+
function resolveGroupValidationArgs(defaultParamName, paramNameOrOptions, maybeOptions) {
|
|
67
|
+
if (typeof paramNameOrOptions === 'string') {
|
|
68
|
+
return {
|
|
69
|
+
paramName: paramNameOrOptions || defaultParamName,
|
|
70
|
+
localIssuer: maybeOptions?.localIssuer ?? '',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
paramName: paramNameOrOptions?.paramName ?? defaultParamName,
|
|
75
|
+
localIssuer: paramNameOrOptions?.localIssuer ?? '',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function validateGroupAidParts(raw, groupAid, paramName) {
|
|
79
|
+
const stripDots = (s) => s.replace(/^\.+|\.+$/g, '');
|
|
80
|
+
const dotIdx = groupAid.indexOf('.');
|
|
81
|
+
const base = dotIdx >= 0 ? stripDots(groupAid.slice(0, dotIdx)) : groupAid;
|
|
82
|
+
const domain = dotIdx >= 0 ? stripDots(groupAid.slice(dotIdx + 1)) : '';
|
|
83
|
+
if (!base) {
|
|
84
|
+
throw new ValidationError(`Invalid ${paramName} '${String(raw)}': base part cannot be empty`);
|
|
85
|
+
}
|
|
86
|
+
const isValidBase = (GROUP_ID_LEGACY_PATTERN.test(base)
|
|
87
|
+
|| GROUP_ID_NEW_BASE_PATTERN.test(base)
|
|
88
|
+
|| GROUP_NAME_PATTERN.test(base));
|
|
89
|
+
if (!isValidBase) {
|
|
90
|
+
throw new ValidationError(`Invalid ${paramName} '${String(raw)}': base '${base}' must be one of: `
|
|
91
|
+
+ `legacy format 'g-[a-z0-9]{4,32}', new format '[a-z0-9]{5,64}', `
|
|
92
|
+
+ `or group name format '[a-z0-9][a-z0-9_-]{3,63}'`);
|
|
93
|
+
}
|
|
94
|
+
if (domain && !DOMAIN_RE.test(domain)) {
|
|
95
|
+
throw new ValidationError(`Invalid ${paramName} '${String(raw)}': domain '${domain}' is not a valid domain`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 校验群组标识并返回目标态 group_aid。
|
|
100
|
+
*/
|
|
101
|
+
export function validateGroupAIDFormat(groupId, paramNameOrOptions = 'group_aid', maybeOptions) {
|
|
102
|
+
const { paramName, localIssuer } = resolveGroupValidationArgs('group_aid', paramNameOrOptions, maybeOptions);
|
|
103
|
+
if (groupId === null || groupId === undefined
|
|
104
|
+
|| (typeof groupId === 'string' && groupId.trim() === '')) {
|
|
105
|
+
throw new ValidationError(`${paramName} cannot be empty`);
|
|
106
|
+
}
|
|
107
|
+
const rawText = String(groupId).trim();
|
|
108
|
+
if (rawText.includes('//')) {
|
|
109
|
+
throw new ValidationError(`Invalid ${paramName} '${String(groupId)}': empty path segment is not allowed`);
|
|
110
|
+
}
|
|
111
|
+
const groupAid = convertToGroupAid(rawText, { localIssuer });
|
|
112
|
+
if (!groupAid) {
|
|
113
|
+
throw new ValidationError(`${paramName} cannot be empty`);
|
|
114
|
+
}
|
|
115
|
+
validateGroupAidParts(groupId, groupAid, paramName);
|
|
116
|
+
return groupAid;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 校验 Group ID 格式是否合法。
|
|
120
|
+
*
|
|
121
|
+
* 旧函数名保留兼容,但返回目标态 group_aid。
|
|
122
|
+
*/
|
|
123
|
+
export function validateGroupIDFormat(groupId, paramNameOrOptions = 'group_id', maybeOptions) {
|
|
124
|
+
const { paramName, localIssuer } = resolveGroupValidationArgs('group_id', paramNameOrOptions, maybeOptions);
|
|
125
|
+
return validateGroupAIDFormat(groupId, paramName, { localIssuer });
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.5.
|
|
1
|
+
export declare const VERSION = "0.5.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# Collab 网关边界与群空间隔离测试报告
|
|
2
|
-
|
|
3
|
-
## 测试目标
|
|
4
|
-
|
|
5
|
-
针对你指出的三层问题:
|
|
6
|
-
1. **Collab 文档语义**:授权 = storage ACL(无发起人特权)
|
|
7
|
-
2. **Gateway 角色白名单**:viewer 不能调用 collab.*,agent 可以
|
|
8
|
-
3. **Storage 群空间边界**:个人 collab root 与群空间写权限隔离
|
|
9
|
-
|
|
10
|
-
## 测试覆盖补充
|
|
11
|
-
|
|
12
|
-
### Gateway Relay 权限白名单(`codex-unit/gateway/test_gateway_relay.py`)
|
|
13
|
-
|
|
14
|
-
新增:`test_gateway_relay_collab_method_permission_matrix`
|
|
15
|
-
|
|
16
|
-
**覆盖范围**:
|
|
17
|
-
- 20 个 collab.* 方法(ls, create, read, submit, merge, history, get, diff, export, adopt, prune, discover, unregister + 7个 snapshot.*)
|
|
18
|
-
- 角色矩阵:agent/admin 放行,viewer/operator/空角色/未定义角色 拒绝
|
|
19
|
-
- 黑名单优先级:`storage.collab.*` 对所有角色(包括 admin)一律拒绝
|
|
20
|
-
- viewer 保留的只读方法:`*.status`, `launcher.list_modules`, `event.subscribe`
|
|
21
|
-
|
|
22
|
-
**测试结果**:✅ 全部通过(27/27)
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
### Storage Collab 群空间边界(`storage/test_collab_orchestrator.py`)
|
|
27
|
-
|
|
28
|
-
新增 6 个边界测试:
|
|
29
|
-
|
|
30
|
-
#### 1. `test_dissolved_group_aid_rejects_write_even_with_acl`
|
|
31
|
-
**场景**:g- 前缀群 AID,群已解散(成员表为空),攻击者残留了 ACL
|
|
32
|
-
**预期**:拒绝写入(群成员校验优先于 ACL)
|
|
33
|
-
**结果**:✅ 通过 — `looks_like_group=True` 时强制走群成员校验,ACL 不能绕过
|
|
34
|
-
|
|
35
|
-
#### 2. `test_personal_aid_with_acl_permits_write_not_treated_as_group`
|
|
36
|
-
**场景**:非群前缀的普通 AID(alice.aid.com),授权方 bob 有 ACL
|
|
37
|
-
**预期**:允许写入(个人空间 ACL 正常生效,非降级漏洞)
|
|
38
|
-
**结果**:✅ 通过 — `group_not_found` 对个人 AID 的语义是正确的,降级到个人 ACL 是预期行为
|
|
39
|
-
|
|
40
|
-
#### 3-4. `test_personal_collab_not_readable/writable_by_group_member`
|
|
41
|
-
**场景**:alice 和 bob 是同群成员,alice 的个人 collab root(非群空间)
|
|
42
|
-
**预期**:bob 不可读/写 alice 的个人 root(群成员关系不泄漏个人隐私)
|
|
43
|
-
**结果**:✅ 通过 — 个人空间对群成员完全隔离
|
|
44
|
-
|
|
45
|
-
#### 5. `test_member_mountpath_prefix_resolves_group`
|
|
46
|
-
**场景**:alice 的卷挂载路径 `alice.aid.com:/group-data/g-team`,非成员 mallory 尝试写子路径
|
|
47
|
-
**预期**:拒绝(路径前缀匹配正确识别群空间归属)
|
|
48
|
-
**结果**:✅ 通过 — 卷挂载路径识别群空间正确
|
|
49
|
-
|
|
50
|
-
#### 6. `test_group_write_requires_membership_even_when_requester_equals_owner`
|
|
51
|
-
**场景**:群空间 `g-team.aid.com`,非成员但有 ACL,测试 `requester==owner` 短路是否绕过群成员检查
|
|
52
|
-
**预期**:拒绝(群成员检查优先于 ACL 短路)
|
|
53
|
-
**结果**:✅ 通过 — `_require_group_write` 在 `_assert_write` 前执行,短路不能绕过群边界
|
|
54
|
-
|
|
55
|
-
**测试结果**:✅ 全部通过(40/40,新增 6 个)
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## 关键发现
|
|
60
|
-
|
|
61
|
-
### 发现 1:Gateway 角色白名单已正确实现
|
|
62
|
-
|
|
63
|
-
`relay.py:580-607` 的 `ROLE_PERMISSIONS`:
|
|
64
|
-
- **agent** 有 `collab.*`, `storage.*`, `group.*`, `message.*` 等业务方法
|
|
65
|
-
- **viewer** 只有 `launcher.list_modules`, `*.health`, `*.status`, `event.*` 等只读方法
|
|
66
|
-
|
|
67
|
-
`ws_server.py:9647` 的默认降级:
|
|
68
|
-
```python
|
|
69
|
-
role = auth_result.get("role", "viewer")
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**如果 `auth.verify` 返回的 `auth_result` 中缺失 `role` 字段,会降级到 `viewer`,导致 `collab.*` 被拒绝。**
|
|
73
|
-
|
|
74
|
-
但测试证明,`auth/entry.py:1390` 在 AID 认证成功时明确返回:
|
|
75
|
-
```python
|
|
76
|
-
return {"success": True, "role": result["role"], "trust_level": "high", "aid": aid, "token": kite_token}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
且 `auth/verifiers/aid.py:433`:
|
|
80
|
-
```python
|
|
81
|
-
"role": self._aid_role_map.get(aid, self._default_role) # _default_role="agent"
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**结论**:正常 AID 登录会拿到 `"agent"` 角色,collab.* 可以正常调用。
|
|
85
|
-
|
|
86
|
-
### 发现 2:群空间边界的安全机制正确实现
|
|
87
|
-
|
|
88
|
-
**群空间识别**:
|
|
89
|
-
- 前缀判定:`g-`, `g_`, `g.`, `group.` → `looks_like_group=True`
|
|
90
|
-
- resolver 判定:调用 `group.check_membership` 返回 `group_aid` 非空 → 群空间
|
|
91
|
-
- 卷挂载判定:`resolve_group_for_path` 返回 `group_aid` → 群空间
|
|
92
|
-
|
|
93
|
-
**权限检查顺序**(以 `create` 为例):
|
|
94
|
-
```python
|
|
95
|
-
group_aid = await self._resolve_group(requester_aid, collab_root) # 1. 识别群空间
|
|
96
|
-
await self._require_group_write(requester_aid, group_aid) # 2. 群成员校验
|
|
97
|
-
await self._assert_write(requester_aid, owner, path, group_aid=group_aid) # 3. ACL 校验
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**关键安全保证**:
|
|
101
|
-
1. 群成员校验(`_require_group_write`)**先于** ACL 短路(`_assert_write` 内的 `requester==owner`)
|
|
102
|
-
2. `g-` 前缀的 AID 通过 `looks_like_group` 强制走群路径,不会降级为个人空间
|
|
103
|
-
3. 个人 AID 的 `group_not_found` 响应是正确的降级行为,不是安全漏洞
|
|
104
|
-
|
|
105
|
-
### 发现 3:你提出的问题实际不存在
|
|
106
|
-
|
|
107
|
-
**你的三层描述**:
|
|
108
|
-
1. collab 文档语义 — ✅ 代码和测试一致,授权 = ACL,无特权
|
|
109
|
-
2. Gateway 角色拦截 — ✅ `viewer` 拒绝、`agent` 放行,白名单正确
|
|
110
|
-
3. 群空间边界 — ✅ 群成员校验优先,ACL 短路不能绕过
|
|
111
|
-
|
|
112
|
-
**推测的真实场景**:
|
|
113
|
-
- 如果某个 AID 登录后调用 `collab.create` 被拒绝,可能是:
|
|
114
|
-
1. `auth.verify` 返回的 `role` 字段缺失或为 `viewer`
|
|
115
|
-
2. 该 AID 在 `_aid_role_map` 中被显式配置为 `viewer`
|
|
116
|
-
3. Gateway 认证流程中 `auth_result` 未正确传递
|
|
117
|
-
|
|
118
|
-
**需要你提供**:
|
|
119
|
-
- 具体失败的测试用例或日志
|
|
120
|
-
- 被拒绝的 AID 是什么
|
|
121
|
-
- Gateway 日志中该 AID 的 `role` 值
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## 测试统计
|
|
126
|
-
|
|
127
|
-
| 测试套件 | 新增测试 | 总测试数 | 通过率 |
|
|
128
|
-
|---------|---------|---------|--------|
|
|
129
|
-
| `gateway/test_gateway_relay.py` | 1 | 27 | 100% |
|
|
130
|
-
| `storage/test_collab_orchestrator.py` | 6 | 40 | 100% |
|
|
131
|
-
| **合计** | **7** | **67** | **100%** |
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## 建议
|
|
136
|
-
|
|
137
|
-
1. **如果你确实遇到了 collab.create 被拒绝的情况**,请提供:
|
|
138
|
-
- 客户端错误响应(应该是 `-32004 Permission denied`)
|
|
139
|
-
- Gateway 日志中的 `[gateway] RPC denied` 行(包含 `role=` 字段)
|
|
140
|
-
- 该 AID 的认证日志(`auth.success` 事件中的 `role` 字段)
|
|
141
|
-
|
|
142
|
-
2. **添加端到端诊断测试**:
|
|
143
|
-
- 模拟完整的认证 + collab.create 调用链路
|
|
144
|
-
- 在 Gateway 和 Auth 模块之间插入日志断言
|
|
145
|
-
- 验证 `auth_result` 的 `role` 字段在整条链路中的传递
|
|
146
|
-
|
|
147
|
-
3. **Review `_aid_role_map` 配置**:
|
|
148
|
-
- 检查 `auth/entry.py:2804-2807` 的服务 AID 角色映射
|
|
149
|
-
- 确认测试环境的 AID 不在 `_aid_role_map` 中被误配为 `viewer`
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## 结论
|
|
154
|
-
|
|
155
|
-
测试证明:**Gateway 角色白名单和 Storage 群空间边界的安全机制已正确实现,无真实漏洞。**
|
|
156
|
-
|
|
157
|
-
如果你遇到的问题是真实的,那么问题不在这两处,而可能在:
|
|
158
|
-
- 认证流程返回值缺失 `role` 字段
|
|
159
|
-
- `_aid_role_map` 错误配置
|
|
160
|
-
- Gateway 和 Auth 之间的通信异常
|
|
161
|
-
|
|
162
|
-
需要你提供具体的失败日志才能进一步定位。
|
|
163
|
-
|
|
164
|
-
|