Skip to content

feat(v3): token 吊销 CLI + at-rest 哈希(§11.3)#208

Open
raysonmeng wants to merge 1 commit into
feat/v3-room-passwordfrom
feat/v3-token-revoke
Open

feat(v3): token 吊销 CLI + at-rest 哈希(§11.3)#208
raysonmeng wants to merge 1 commit into
feat/v3-room-passwordfrom
feat/v3-token-revoke

Conversation

@raysonmeng

Copy link
Copy Markdown
Owner

背景 / Why

§11.3 两项安全硬化:① broker store 里的 PSK token 此前明文存储——collab.db 泄漏即暴露可直接用的 token;② 没有吊销手段——invite/issue 重复签发会累积有效 token,无法作废。

改了什么 / What

  • at-rest 哈希:token 以 SHA-256 哈希存(backbone/token-hash.ts)。raw token 只存在于 edge 的 <state>/auth-token(0600);broker store 只有 digest。对认证完全透明:raw 进 → hash 存 → 边机presented raw → broker resolveToken 内部 hash 查 → 命中。
  • 老库迁移SqliteStore 构造器把任何非 64-hex 的 legacy raw token 行原地 re-hash(幂等;迁移后 edge 持的 raw 仍能认证)。
  • abg auth revoke --id <id>(broker 机运行):revokeTokens 删除该身份全部 token、返回计数。旧 token 重连即被 broker 拒(4401)。
  • 全库把「raw PSK tokens / 吊销 CLI 在 backlog / §11.3 是 future」等过时安全注释统一更新为「hashed at rest §11.3」。

安全边界 / Security

  • 选型:token 是 128-bit 随机 randomUUID(高熵、无猜测面)→ 快哈希 SHA-256 即可(2^122 彩虹表不可行),且让 broker 热路径廉价;对比房间口令(人选低熵)必须 scrypt+salt。还顺带消除了原始 raw 查找的时序面。
  • 吊销限制(诚实标注):auth 仅在 hello 时校验,故 revoke 只挡重连——已在线连接保持到自然断开。要立刻踢出,配合 abg room remove(成员制在投递时强制)。三处标注(IdentityService 注释 / CLI 输出 / --help)+ 集成测试钉死。
  • revoke 不存在身份返回 0(幂等 + 不泄露身份存在性)。

测试 / Tests

  • token-hash.test.ts 5(哈希 + at-rest(sqlite/memory)+ revoke + 老库迁移 + 二次 reopen 幂等)+ broker-token-revoke.test.ts 1(吊销后重连被拒、live 连接存活)+ cli-auth.test.ts authRevoke + store-contract.ts(at-rest 哈希 + revokeTokens 契约,sqlite+memory)。
  • bun run check 全绿(1889 测试)。
  • Cross-review:2 opus(核心逻辑/安全双 0)+ 多轮 sonnet 修文档漂移(全库 grep 零残留)+ 终审双 0 收敛。

栈 / Stack

base = feat/v3-room-password#207)。at-rest 哈希与 token 流程同源,叠在其上。

🤖 Generated with Claude Code

- backbone/token-hash.ts:hashToken(SHA-256;高熵 randomUUID 用快哈希即可,对比房间口令的 scrypt)+ looksHashedToken
- Store at-rest 哈希:issueToken/resolveToken 存/查 hashToken;raw token 只在 edge 0600 文件,broker store 仅有 digest(DB 泄漏不暴露可用 token)。3 实现一致。
- sqlite 老库迁移:构造器把非 64-hex 的 legacy raw token 行原地 re-hash,idempotent;迁移后 edge 持的 raw token 仍能认证(resolveToken(raw)=hash 查命中)
- revokeTokens(identityId):按身份删全部 token + 返回计数;`abg auth revoke --id <id>`(broker 机运行)。旧 token 重连即被拒(4401);已在线连接保持到自然断开——配合 abg room remove 立刻踢(投递时强制成员制,三处诚实标注)
- 顺带把全库「raw PSK tokens / 吊销 CLI 在 backlog / §11.3 是 future」过时安全注释更新为「hashed at rest §11.3」

安全:哈希对所有 token 认证透明(raw 进→hash 存→raw 验→hash 查);unsalted SHA-256 对 122-bit 随机 token 足够(无字典面、2^122 彩虹表不可行),且消除了原 raw 查找的时序面;revoke 不存在身份返回 0(幂等 + 不泄露存在性)。

测试:token-hash 5(含老库迁移 + 二次 reopen 幂等)+ broker-token-revoke 1(吊销后重连拒、live 连接存活)+ cli-auth authRevoke + store-contract(at-rest 哈希 + revokeTokens 契约,sqlite+memory)。bun run check 全绿。

cross-review:2 opus(核心逻辑/安全双 0)+ 多轮 sonnet 修文档漂移(全库 grep 零残留),终审双 0 收敛。

feat(v3): token revocation CLI + at-rest hashing (§11.3)

Tokens are SHA-256-hashed at rest (a DB leak exposes only digests); the raw token lives only in the
edge's 0600 file. `abg auth revoke --id <id>` deletes an identity's tokens so old ones can't reconnect.
A legacy-raw-token migration re-hashes existing rows in place (idempotent). Hashing is transparent to
all token auth (raw in → hash stored → raw presented → hash looked up).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012rhWKm1VUSnEVxmjpYwNfc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant