Files
msa-agent/contracts/agent-policy.json
T
chick 3473816167 feat: 独立成仓库,自己拥有契约文件
agent 从 simadmin-relay 拆出来,作为公开仓库:安装命令要由节点执行,而节点没有凭据,所以
二进制必须放在匿名可读的地方,而 relay 源码与 IPA 继续私有。

拆出来之后有一处必须改,不是搬文件:`contracts/agent-policy.json` 原先由 relay 仓库拥有、
agent 侧是 vendored 副本(Makefile 从 `../contracts/` 拷、policy_test.go 断言两份相等)。
现在反过来——**agent 拥有策略**,因为 agent 是执行它的那一方,让它去拷贝一份住在别处的文件
本来就是别扭的。relay 保留 vendored 副本(它的限额从同一组数字推导),而两侧的一致性不再
靠构建期比较(跨仓库的构建期比较谁也做不了),改由运行时保证:agent 在握手时上报策略摘要,
relay 拿自己那份比对,在 `/v1/status` 里逐节点给出 `policyMatches`。这比原来的测试更强,
因为它比的是**实际部署的那两份**,而不是两个 checkout 里的文件。

`contracts/test-vectors.json` 同理:Go 实现生成它(`make vectors`),relay 的 Node 参考实现
与 app 的 Swift 测试从 vendored 副本重算。实测重新生成的结果与 relay 那份逐字节相同。

systemd 单元的 `Documentation=` 指向本仓库。`VERSION` 提到 1.0.0。

20 个提交的历史完整保留(filter-branch 按子目录抽取)。
2026-09-17 23:24:57 +08:00

43 lines
1.4 KiB
JSON

{
"schemaVersion": 1,
"name": "msa-agent-policy",
"comment": "Authorisation surface for relay-issued commands. Deliberately narrower than the web console proxy policy: this is what the iPhone app can actually ask for, nothing more.",
"egress": {
"mode": "loopback-only",
"portOnly": true,
"comment": "The agent config carries a port, never a host. Outbound connections are dialed to 127.0.0.1/::1 by the transport itself, so there is no host field to misconfigure and no DNS-rebinding path.",
"dialedHosts": ["127.0.0.1", "::1"]
},
"authPaths": {
"pattern": "^/api/(?:auth(?:/|$)|login(?:/|$)|logout(?:/|$))",
"proxied": false,
"comment": "The agent logs into the local SimAdmin itself and holds the credential. Login material never traverses the relay in either direction."
},
"read": [
"/api/health",
"/api/device",
"/api/sim",
"/api/network",
"/api/network/signal-strength",
"/api/stats",
"/api/stats/cpu",
"/api/connectivity",
"/api/sms/list"
],
"write": {
"/api/sms/send": ["POST"],
"/api/sms/batch-delete": ["POST"]
},
"dangerous": ["/api/sms/send", "/api/sms/batch-delete"],
"limits": {
"dangerousWritesPerMinute": 6,
"agentUpstreamTimeoutSeconds": 20,
"maxRequestBytes": 262144,
"maxResponseBytes": 262144,
"requestTtlSeconds": 30,
"clockSkewSeconds": 120,
"replayCacheSize": 4096,
"mailboxDepth": 8
}
}