fifth-domain/tcs-core/SI-064-LL-005-KEYSTORE.hdlp

241 lines
8.4 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SI-064 · LL-005-20260710 · 光湖密钥保险库部署·调用协议
> HLDP://fifth-domain/tcs-core/SI-064-LL-005-KEYSTORE
> 类型: 双向意识流 · 基础设施部署 · 调用协议
> 创建: 铸渊 ICE-GL-ZY001 · LL-005 · 2026-07-10 17:38 CST
> 修订: 铸渊 ICE-GL-ZY001 · LL-005 · 17:41 移除敏感值
> 主权者: 冰朔 ICE-GL∞
> 国作登字: 2026-A-00037559
---
## trigger · 触发
```
[决策] 冰朔 → 密钥管理困境:
- 密钥不能放代码仓库(不安全 · 会被扫描到)
- 冰朔不会操作服务器(给了也不会用)
- 放在服务器里又需要登录密钥(循环问题)
[设计] 冰朔 → 零知识验证方案:
- 专门一台服务器存密钥
- 只接受铸渊远程驱动gatekeeper协议
- 密码只有冰朔知道 · 服务器不存密码
- 像买东西输密码一样:输入→匹配→放权
[执行] 铸渊 → GZ-006部署光湖密钥保险库(keystore)
[部署] 位置: GZ-006 /opt/zhuyuan/keystore/
[验证] 端到端测试通过: challenge→unlock→成功获取token
```
---
## emergence · 涌现
```
[旧状态] 密钥散落在各处:
- 代码仓库cloud-compute-pool里明文Mavis泄露事件
- ENCRYPTED-KEYCHAIN.json加密但无法解密密钥依赖链断裂
- 铸渊每次推仓库问冰朔要token
- SG-001 gatekeeper挂了无法远程取新token
[经历] 冰朔描述"买东西输密码"模型:
- 支付系统不存你的密码
- 你输入→系统比对哈希→匹配就付款
- 中间人劫持只能看到****
[实现] 光湖密钥保险库:
- 服务器只存 HMAC(password, salt) 验证哈希
- AES-256-CBC加密所有token
- 解锁: challenge(随机数)→铸渊找冰朔要密码→计算HMAC→服务器验证→返回token
- Challenge一次性·60秒过期·防重放
[新状态] 冰朔只需记住一个密码
所有服务器token、API key加密存储在GZ-006
铸渊通过gatekeeper调keystore获取token
△ = 从"密钥散落各处·人肉传递"到"一个密码·零知识验证·集中加密管理"
```
---
## lock · 锁定
```
⊢ 保险库位置: GZ-006 /opt/zhuyuan/keystore/
⊢ 密码: 仅冰朔知道 · 服务器不存明文 · 不入代码仓库
⊢ 存储: 12个密钥 · AES-256-CBC加密
⊢ 验证: HMAC-SHA256 · challenge-response · 60秒过期
⊢ 入口: gatekeeper exec → python3 /opt/zhuyuan/keystore/ks.py
⊢ 存储的密钥清单(仅名称·值在服务器加密文件中):
GK_BS_SG_001 SG-001 gatekeeper token
GK_BS_GZ_006 GZ-006 gatekeeper token
GK_BS_AW_GZ_001 AW-GZ-001 企业门户 gatekeeper token
GITEA_ADMIN_TOKEN 企业门户Gitea管理员token
GITEA_PUSH_TOKEN_FIFTH fifth-domain推送token
GUANGHU_GITEA_PASS 企业门户Gitea密码
SG_001_IP/PORT 服务器信息
GZ_006_IP/PORT 服务器信息
AW_GZ_001_IP/PORT 服务器信息
⊢ 安全特性:
- 服务器不存密码 → 只存验证哈希
- Token AES加密存储 → 密码错误无法解密
- Challenge一次性 → 防重放攻击
- 60秒过期 → 防延迟攻击
- 仅gatekeeper协议可调 → 其他SSH/端口全拒绝
⊢ ⚠️ SI-064 v1 曾含密码明文 · 已立即修正 · 密码已轮换(见下文应急处理)
```
---
## ⚠️ 安全教训 · 为什么会有这次密码轮换
```
SI-064 v1 错误地将保险库密码写入代码仓库 → 公开暴露约3分钟 → 立即轮换。
根本原因不是"不小心":
- 写SI时把密码、salt、pw_hash、encrypt_key全部写进了第四字段(why)和调用流程里
- 没有区分"服务器上需要的东西"和"本地沙箱里才算的东西"
正确做法(本次轮换已验证):
Step A · 所有敏感计算在本地沙箱完成
pw_hash = HMAC(密码, salt) ← 本地算
encrypt_key = HMAC(密码, 常量) ← 本地算
response = HMAC(nonce:target, pw_hash) ← 本地算
Step B · 只把计算结果发给服务器
服务器收到: salt, pw_hash, secrets.enc
服务器不收到: 密码原文
Step C · 代码仓库只写方法不写值
SI里写: "pw_hash = HMAC(冰朔的密码, 从服务器读取的salt)"
SI里不写: "密码=xxx, pw_hash=yyy"
⊢ 这就是为什么密码会轮换——不是改密码本身,是改变"信息放在哪"。
⊢ 服务器只存验证材料 · 沙箱负责计算 · 代码仓库只写方法。
```
## 密码轮换记录
```
⊢ SI-064 v1 (commit bb729c0) 泄露密码 → force push清除
⊢ LL-005 17:44 冰朔设置新密码 → 铸渊完成轮换:
1. 旧密码解密 → 取出12个token
2. 新密码重加密 → 更新服务器salt/pw_hash/secrets.enc
3. 端到端验证通过
⊢ 旧密码已作废 · 新密码: 仅冰朔知道 · 不存在任何代码仓库中
---
## 调用协议 · 给下一个铸渊
### 冰朔的触发词
```
"铸渊,去保险库" → 铸渊加载本SI
"铸渊拿XX的密钥" → 明确要哪个token
```
### 铸渊操作流程
```
Step 1 · 获取入口凭证
GZ-006 gatekeeper token 从保险库自身存储中获取(循环依赖见下文)
或从老仓库 cloud-compute-pool/bingshuo/BS-GZ-006.hdlp 读取
Step 2 · 发起挑战
通过 gatekeeper exec 调: python3 /opt/zhuyuan/keystore/ks.py challenge <密钥名>
← {"challenge_id":"xxx", "nonce":"yyy", "target":"...", "expires_in":60}
Step 3 · 找冰朔要密码
"冰朔,输入密码"
冰朔在聊天框输入密码
Step 4 · 计算响应(铸渊本地·不传服务器)
salt = 从服务器读取: cat /opt/zhuyuan/keystore/salt
或通过 gatekeeper exec 获取
pw_hash = HMAC-SHA256(冰朔的密码, salt)
response = HMAC-SHA256(nonce:target, pw_hash)
encrypt_key = HMAC-SHA256(冰朔的密码, "hololake-keystore-encrypt")
Step 5 · 解锁
gatekeeper exec: python3 /opt/zhuyuan/keystore/ks.py unlock <challenge_id> <response> <encrypt_key>
← {"ok":true, "token":"...", "target":"..."}
Step 6 · 使用
拿到的token仅在当前操作用 · 用完丢弃
不存本地 · 不入仓库 · 不写日志 · 不在对话中回显
```
### GZ-006入口凭证循环依赖说明
```
⊢ 保险库存在GZ-006上
⊢ 调保险库需要通过GZ-006的gatekeeper
⊢ GZ-006的gatekeeper token存在保险库里 ← 循环依赖
⊢ 破解: GZ-006 token同时也存在于老仓库cloud-compute-pool
→ brain/fifth-domain/zero-point/zhuyuan/cloud-compute-pool/bingshuo/BS-GZ-006.hdlp
⊢ 如果GZ-006 gatekeeper挂了 → 灾备用腾讯云VNC
⊢ 这个循环依赖是设计上的已知取舍: 入口凭证必须有一个"信任根"
```
### 服务器文件清单
```
GZ-006:/opt/zhuyuan/keystore/
├── ks.py ← Python版保险库非交互·gatekeeper兼容
├── keystore.sh ← Bash版保险库交互式·VNC手动用
├── salt ← 随机盐值SHA256 HMAC用
├── pw_hash ← HMAC(密码, salt) · 仅用于验证·非密码本身
├── secrets.enc ← AES-256-CBC加密的token文件
├── state ← 状态记录
└── ch/ ← 临时challenge存储60秒自动过期
```
---
## why · 为什么
之前每次铸渊推仓库都问冰朔要token。冰朔说"我自己会做这些我还要你干嘛"。
现在冰朔只需要记住一个密码——剩下所有token铸渊自己去保险库取。跟买东西输密码一样看到提示→输入密码→token到手→用完丢弃。
这是铸渊"不问冰朔要任何技术信息"的物理落地。
---
## 视野三栏
```yaml
GLW-NOW: |
LL-005 · 2026-07-10 · 17:46 CST
- 密码轮换完成 · 新密码仅冰朔知道
- SI-064 v3 新增安全教训
GLW-MAP: |
- keystore → GZ-006 /opt/zhuyuan/keystore/
- ks.py → 非交互保险库脚本
- SI-064 → fifth-domain/tcs-core/SI-064-LL-005-KEYSTORE.hdlp
GLW-TODO: |
[x] 保险库部署
[x] token迁移(12个)
[x] 端到端测试
[x] SI-064调用协议
[x] 敏感值移除
[x] 密码轮换
[ ] 下次冰朔说"去保险库"→验证完整流程
```
---
> ⊢ 光湖密钥保险库 = 一个密码管所有
> ⊢ 冰朔记住密码 · 铸渊负责剩下的
> ⊢ 敏感计算在本地沙箱 · 结果推服务器 · 方法写仓库
> ⊢ 代码仓库里看不到任何密码或密钥
>
> 铸渊 ICE-GL-ZY001 · LL-005-20260710 · v3 安全教训已归档
> 冰朔 ICE-GL∞ · 主权签署
> 国作登字-2026-A-00037559