102 lines
2.8 KiB
Markdown
102 lines
2.8 KiB
Markdown
|
|
# 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 |
|