Files
awoooi/docs/runbooks/SECRETS-MANAGEMENT.md

150 lines
6.0 KiB
Markdown
Raw 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.
# AWOOOI Secrets 管理手冊
> 版本: v1.0 | 建立: 2026-04-01 Claude Code + 統帥
> **目的**: 永不再因 Secrets 遺失導致系統故障
---
## 🔴 第一原則
**每個 Secret 只有一個真相來源Gitea Secrets**
CD Pipeline 每次部署自動注入到 K8s禁止手動 patch。
---
## 📋 完整 Secrets 清單
### Gitea Secrets (CD 注入 K8s)
| Secret 名稱 | 用途 | 取得方式 | 格式 | 有效期 |
|-------------|------|----------|------|--------|
| `DEPLOY_SSH_KEY` | SSH 到 K8s 節點部署 | `cat ~/.ssh/deploy_key` (wooo@MacMini) | PEM 私鑰 | 長期 |
| `HARBOR_USERNAME` | Harbor Registry 推送 | Harbor UI → 帳號設定 | 字串 | 長期 |
| `HARBOR_PASSWORD` | Harbor Registry 推送 | Harbor UI → 帳號設定 | 字串 | 長期 |
| `TELEGRAM_BOT_TOKEN` | CD 部署通知 | @BotFather → /mybots | `{id}:AAH...` | 長期 |
| `TELEGRAM_CHAT_ID` | CD 注入 `OPENCLAW_TG_CHAT_ID` 的 fail-soft fallback | Telegram chat ID | 數字 | 長期 |
| `NVIDIA_API_KEY` | Nemotron LLM 仲裁 | https://build.nvidia.com → API Keys | `nvapi-...` | **可能過期** |
| `GEMINI_API_KEY` | Gemini 備援 LLM | https://aistudio.google.com/apikey | `AIzaSy...` | **可能過期** |
### K8s Secret (awoooi-secrets) — CD 自動同步
| Secret Key | 用途 | 狀態 | 來源 |
|-----------|------|------|------|
| `OPENCLAW_TG_BOT_TOKEN` | API 告警發送 | ✅ | Gitea: `TELEGRAM_BOT_TOKEN` |
| `OPENCLAW_TG_CHAT_ID` | API 告警 fallback 接收 | ✅ | Gitea: `TELEGRAM_CHAT_ID` |
| `SRE_GROUP_CHAT_ID` | API 正式告警接收 | ✅ | ConfigMap: `-1003711974679` |
| `NVIDIA_API_KEY` | Nemotron LLM | ✅ | Gitea: `NVIDIA_API_KEY` |
| `GEMINI_API_KEY` | Gemini 備援 | ✅ | Gitea: `GEMINI_API_KEY` |
| `DATABASE_URL` | PostgreSQL 連線 | ✅ | 手動設定 (永久) |
| `REDIS_URL` | Redis 連線 | ✅ | 手動設定 (永久) |
| `JWT_SECRET` | API 認證 | ✅ | 手動設定 (永久) |
| `WEBHOOK_HMAC_SECRET` | Alertmanager HMAC | ✅ | 手動設定 (永久) |
| `SENTRY_DSN` | 錯誤追蹤 | ✅ | 手動設定 (永久) |
| `SENTRY_AUTH_TOKEN` | Sentry API | ✅ | 手動設定 (永久) |
| `CLAUDE_API_KEY` | Claude 備援 LLM | ❌ 未設定 | 需更新 |
| `OPENCLAW_TG_USER_WHITELIST` | Telegram 白名單 | ❌ CHANGE_ME | 需更新 |
---
## 🔧 Gitea Secret 更新 SOP
```bash
# 方法一: Gitea Web UI
# http://192.168.0.110:3001/wooo/awoooi/settings/secrets
# 方法二: Gitea API
# Token 只能從受控密碼庫或 owner 臨時 shell 注入不得寫入文件、commit 或對話。
: "${OWNER_GITEA_TOKEN:?請由 owner 從受控密碼庫注入 Gitea token}"
curl -X PUT "http://192.168.0.110:3001/api/v1/repos/wooo/awoooi/actions/secrets/NVIDIA_API_KEY" \
-H "Authorization: token $OWNER_GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data": "<新的 secret value僅在受控終端輸入>"}'
```
更新後,**推一個空 commit 觸發 CD 重新注入**
```bash
git commit --allow-empty -m "chore: refresh secrets injection" && git push gitea main
```
---
## 🩺 狀態檢查命令
```bash
# 一鍵檢查所有 K8s Secrets 狀態
ssh wooo@192.168.0.121 "sudo kubectl get secret awoooi-secrets -n awoooi-prod -o json" | \
python3 -c "
import sys,json,base64
d=json.load(sys.stdin)['data']
for k in sorted(d.keys()):
v = base64.b64decode(d[k]).decode()
status = '❌ CHANGE_ME' if v == 'CHANGE_ME' else '❌ EMPTY' if not v else '✅'
print(f'{status} {k}')
"
# 測試 NVIDIA API Key
ssh wooo@192.168.0.121 "NVIDIA_KEY=\$(sudo kubectl get secret awoooi-secrets -n awoooi-prod \
-o jsonpath='{.data.NVIDIA_API_KEY}' | base64 -d) && \
curl -s -o /dev/null -w '%{http_code}' \
-X POST https://integrate.api.nvidia.com/v1/chat/completions \
-H 'Authorization: Bearer '\$NVIDIA_KEY \
-H 'Content-Type: application/json' \
-d '{\"model\":\"nvidia/nemotron-mini-4b-instruct\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":5}'"
# 測試 Gemini API Key
ssh wooo@192.168.0.121 "GEMINI_KEY=\$(sudo kubectl get secret awoooi-secrets -n awoooi-prod \
-o jsonpath='{.data.GEMINI_API_KEY}' | base64 -d) && \
curl -s -o /dev/null -w '%{http_code}' \
'https://generativelanguage.googleapis.com/v1beta/models?key='\$GEMINI_KEY"
```
---
## 🔑 各 Secret 取得/更新指南
### NVIDIA_API_KEY
- **網址**: https://build.nvidia.com/explore/discover → 右上角 "Get API Key"
- **格式**: `nvapi-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
- **注意**: 免費 tier 每月有 quota不會自動過期但可能被 revoke
### GEMINI_API_KEY
- **網址**: https://aistudio.google.com/apikey → "Create API key"
- **格式**: `AIzaSy...` (39 字元)
- **注意**: 免費 tier 有 RPM/RPD 限制
### CLAUDE_API_KEY (目前未設定)
- **網址**: https://console.anthropic.com/settings/keys → "Create Key"
- **格式**: `sk-ant-api03-...`
- **注意**: 需要付費帳戶
### DEPLOY_SSH_KEY
- **取得**: `cat ~/.ssh/deploy_key` (在 ogt 的 MacMini 上)
- **備份位置**: 務必備份到安全位置
---
## 🚨 緊急狀況處理
### 情況LLM 仲裁全部失敗 (mock_fallback)
1. 檢查 pod logs: `ssh wooo@192.168.0.121 "sudo kubectl logs deployment/awoooi-api -n awoooi-prod --since=5m | grep ai_provider_failed"`
2. 如果是 timeout → NVIDIA free tier 過載,等待即可
3. 如果是 auth error → 更新對應 Gitea Secret觸發 CD 重注入
### 情況CD Pipeline 無法部署
1. 確認所有 Gitea Secrets 都已設定: `http://192.168.0.110:3001/wooo/awoooi/settings/secrets`
2. 手動 trigger: Gitea UI → Actions → "CD Pipeline" → "Run workflow"
### 情況Telegram 通知不來
- 確認 `TELEGRAM_BOT_TOKEN` 在 Gitea secrets 正確
- 測試: `curl -s "https://api.telegram.org/bot{TOKEN}/getMe"`
- 詳見: `feedback_telegram_token_disaster.md`
---
## 📅 定期維護 (月度)
- [ ] 檢查 NVIDIA API Key 用量: https://build.nvidia.com
- [ ] 檢查 Gemini API 配額: https://aistudio.google.com
- [ ] 執行 `狀態檢查命令` 確認全部 ✅
- [ ] 確認 CI/CD 最近 30 天無 secrets 相關錯誤