第六支柱 · 访问控制(阀门)
父级:key-designs
谁能看到什么、能做什么——这是测试最重的一根支柱(acl-* 端到端测试矩阵)。入口通过访问码(access code,即邀请码、二维码);访问码针对某个角色签发,该角色的 RoleSnapshot 在签发时冻结(会话内规则不再漂移)。授权由三层的纯 AND 收窄组合而成——global(实时)∧ role(冻结)∧ ¬code-deny(冻结)——访问码只能做减法,不能重新放行(稀疏拒绝表,没有三态)。身份走中立的 _meta 侧信道;owner 身份是一个 Ed25519 密钥对(私钥永不进入 domain 层);BYOAI 模式允许访客在一个信封(envelope)约束下带自己的模型进来。
状态: 已落地(全局层已上线;角色/访问码拒绝表按 2026-06-23 定稿的设计实现)。
数据模型(ER)
结合三层来读这张图:capability_settings 是实时的全局层;从 roles 可达的一切都会在签发时冻结进 RoleSnapshot;code_*_denials 系列表(capability / skill / corpus——corpus 这张 2026-07-16 落地,6395374b0,backend/db/schema.sql 的 code_corpus_denials)是冻结的、只做减法的第三层。
时序故事——每一层控制在何时起作用
子节点
- access-control-diagram-coverage — 图示覆盖台账。
- acl-and-quota-granularity — 三层纯 AND 模型;稀疏拒绝表。
- role-snapshot-frozen — 签发时冻结 vs 实时的全局层。
- trusted-identity-via-meta — 通过中立的
_meta侧信道传递身份。 - byoai-envelope · byoai-browser-vault — 访客自带模型,被约束在信封内。
- owner-keypair-auth —
/mcp/*上的 Ed25519 Sigv1:私钥 PEM 只返回一次,±5 分钟窗口 + 一次性 nonce;⚠ 签名绑定的是调用方,不是请求本身。 - embed-credential-never-carries-the-code — 上一条的 embed 版:每-embed 的 Ed25519 EdDSA JWT 鉴权 widget 会话,让 code 留在服务端;折进绑定 origin +
exp+ 一次性jti。已实现 2026-09-01(2098975db,backend/internal/access/usecase/embed_token.go);Turnstilecnf绑定是唯一仍延后的一层。 - owner-sessions-and-abuse-controls — 小阀门:退出真会撤销的 Redis owner 会话 + 活动会话面板、密钥对最后使用的设备/ip、按 IP 的邀请码失败锁定(
codefail:ip:,15 分钟内 10 次)与banned_ips、无码层的 gas 计量、每收件人每小时 30 封的邮件节流、APP_BIND_HOST+Referrer-Policy。已实现 2026-08-31 → 2026-09-06。 - coded-landing-and-code-rotation — 一张 code 的三个部分:行 id(关联的键)、snowflake slug →
/c/<slug>(定位符,永远不是凭据;?code=在首次绘制时就被吸收出 URL)、以及 64 位的 code 字符串——codes.rotate唯一替换的部分,杀掉每一份已打印副本和活会话,而 embed/application 存活。2026-09-06 → 07 上线(c6c54ce88、505b3fc4f、backend/internal/access/usecase/codes.go)。