Files
wecom_it_smart_desk/docs/ADRs/ADR-004-Token不入文件-走wincred.md
T

102 lines
2.8 KiB
Markdown
Raw Normal View History

2026-06-15 00:03:11 +08:00
# ADR-004: Token 不入文件,走 wincred 缓存
**状态**: ✅ 已采纳
**日期**: 2026-06-14
**决策者**: 宋献 + Claude 评审
**关联**: [[风险跟踪表]] 第十二节 12.6 / 推送约定
---
## 1. 背景
之前 Gitea 推送 token 直接嵌入 `.git/config``origin.url`:
```
url = https://ae236991c3d5...@ds923plus.tail58d872.ts.net/...
```
**风险**:
- ❌ token 明文落盘
- ❌ token 失效后难更新(URL 整体换)
- ❌ 误 `git add .git/` 可能入仓(虽然 .git/config 本身不入仓,但 .git/ 目录其他文件可能)
- ❌ auto-classifier 拒绝重写 URL(防误操作)
**事故**: 2026-06-14 workbuddy-claude token 失效后,`origin.url` 残留死凭据。
## 2. 决策
**`.git/config``origin.url` 只写用户名,token 走 git credential helper(wincred)缓存**。
## 3. 实现
### 3.1 配 remote URL(无 token)
```bash
git remote add origin https://simon@ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk.git
# 或修复现有:
git remote set-url origin https://simon@ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk.git
```
### 3.2 配 credential helper
`.git/config`:
```ini
[credential]
helper = manager # Windows = wincred / Linux = git-credential-manager
```
### 3.3 首次推(输一次 token)
```bash
git push -u origin main
# 弹窗 → username 留空,password = token
# wincred 自动缓存
```
### 3.4 换 token(必走)
```bash
# 清旧缓存
printf "protocol=https\nhost=ds923plus.tail58d872.ts.net\nusername=simon\n" | git credential reject
# 存新缓存(一次性,token 在 heredoc 不入文件)
printf "protocol=https\nhost=ds923plus.tail58d872.ts.net\nusername=simon\npassword=NEW_TOKEN\n" | git credential approve
# 验证
git push origin main
# 应不弹窗
```
## 4. workbuddy 推送同理
`.workbuddy/config.json` 是 workbuddy 自己的凭据存储(类比 .git/config),**入仓** ❌。
**正确做法**:
- `.workbuddy/config.json` 写用户名/URL/其他配置,**不写 token**
- workbuddy 启动时读 `gitea.token` 字段(从环境变量 / 启动参数传入)
- 或者 workbuddy 自己也用 git credential helper
**已加 .gitignore**:
```gitignore
.workbuddy/config.json
.workbuddy/config.local.json
.workbuddy/*.token
.workbuddy/credentials*
.workbuddy/.env*
```
## 5. 优势
- ✅ token 不入文件(只入 wincred 系统密钥环)
- ✅ 换 token 简单(`credential reject` + `approve`)
- ✅ 不会误入仓
- ✅ auto-classifier 不拒绝(无 token 写文件)
## 6. 风险与缓解
| 风险 | 缓解 |
|---|---|
| wincred 缓存被读(本机攻击) | 操作系统级防护 + 强密码 + BitLocker |
| 跨设备不能用 wincred | Linux 用 `git-credential-manager`,Mac 用 `git-credential-osxkeychain` |
| 换电脑忘缓存 | `git credential approve` 一次性配置 |
| token 在环境变量 | 仍比文件安全 + CI 用 secret store |