Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
14 KiB
14 KiB
belongs_to
| belongs_to | |
|---|---|
|
🔄 铸渊指令|OAuth2 Token 自动续期引擎 + 天眼休眠避让机制(下篇)· 多用户Token流程 + 告警推送 + 天眼扫描清单 + 执行回执(ZY-TOKEN-RENEW-2026-0324-001)
Phase F · 多用户 Token 流程
新用户接入流程
当新开发者需要接入 Drive 权限时,流程如下:
sequenceDiagram
participant Dev as 新开发者
participant Human as 冰朔(人类管理员)
participant ZY as 铸渊(自动化)
participant GH as GitHub Secrets
participant GG as Google OAuth2
Dev->>Human: 申请 Drive 权限
Human->>GG: 在 Google Cloud 加入测试用户白名单
Human->>GG: 用新用户 Gmail 完成 OAuth 授权
Human->>GH: 注入 GDRIVE_REFRESH_TOKEN_DEVxxx
Human->>ZY: 通知铸渊更新注册表
ZY->>ZY: 在 gdrive-tokens.json 添加新条目
ZY->>ZY: 提交注册表更新
Note over ZY: 下次 CRON 触发时自动纳入续期管理
新用户注册表条目模板
铸渊收到新用户接入通知后,在 config/gdrive-tokens.json 的 tokens 数组中添加:
{
"user_id": "DEV-001",
"user_name": "开发者名称",
"role": "developer",
"github_secret_name": "GDRIVE_REFRESH_TOKEN_DEV001",
"last_renewed": "2026-XX-XXTXX:XX:XX+08:00",
"expires_at": "2026-XX-XXTXX:XX:XX+08:00",
"status": "active",
"renew_count": 0,
"notes": "开发者描述"
}
GitHub Secret 命名规范
| 角色 | Secret 命名 | 示例 |
|---|---|---|
| 主控(冰朔) | GDRIVE_REFRESH_TOKEN |
已存在 |
| 开发者 1 | GDRIVE_REFRESH_TOKEN_DEV001 |
未来添加 |
| 开发者 2 | GDRIVE_REFRESH_TOKEN_DEV002 |
未来添加 |
| CI/CD 测试 | GDRIVE_REFRESH_TOKEN_CI |
可选 |
Workflow 如何读取多用户 Token
renew-tokens.js 已设计为遍历注册表,根据每个条目的 github_secret_name 从环境变量读取对应 Token。
但 Workflow 中需要显式将 Secret 注入环境变量。铸渊在添加新用户时,同时更新 Workflow YAML:
# 在 renew-gdrive-tokens.yml 和 check-token-health.yml 的 env 中添加:
env:
GDRIVE_CLIENT_ID: $ secrets.GDRIVE_CLIENT_ID
GDRIVE_CLIENT_SECRET: $ secrets.GDRIVE_CLIENT_SECRET
GDRIVE_REFRESH_TOKEN: $ secrets.GDRIVE_REFRESH_TOKEN
# 新增开发者 Token(每次加人时追加)
# GDRIVE_REFRESH_TOKEN_DEV001: $ secrets.GDRIVE_REFRESH_TOKEN_DEV001
# GDRIVE_REFRESH_TOKEN_DEV002: $ secrets.GDRIVE_REFRESH_TOKEN_DEV002
GITHUB_TOKEN: $ secrets.GITHUB_TOKEN
Phase G · 告警推送系统
告警级别
| 级别 | 触发条件 | 推送渠道 | 行动 |
|---|---|---|---|
| 🟢 INFO | Token 刷新成功 | 回执日志(注册表 renew_log) | 无需操作 |
| 🟡 WARN | Token 剩余 < 72小时但刷新成功 | 回执日志 + grid-db/logs/ | 关注但无需操作 |
| 🟠 ALERT | Token 剩余 < 48小时且刷新失败 | token-alert.json + 主控台 + 公告板 | 要求人类 24 小时内介入 |
| 🔴 CRITICAL | Token 已过期 / 全部刷新失败 | token-alert.json + 主控台 + 公告板 + Workflow 失败标记 | 紧急:人类立即介入重新授权 |
告警输出文件:grid-db/logs/token-alert.json
刷新脚本在有失败时自动生成此文件,天眼系统可读取它来决定是否推送告警:
{
"alert_type": "TOKEN_RENEWAL_FAILURE",
"severity": "CRITICAL",
"time": "2026-03-30T10:00:00Z",
"failed_users": ["TCS-0002"],
"message": "1 个 Token 刷新失败,需要人类介入",
"action_required": "HUMAN_REAUTH",
"instructions": [
"1. 登录 Google Cloud Console",
"2. 访问授权链接获取新 code",
"3. 运行换 token 脚本获取新 refresh_token",
"4. 更新 GitHub Secret: GDRIVE_REFRESH_TOKEN",
"5. 手动触发 renew-gdrive-tokens workflow 验证"
]
}
天眼告警读取脚本:scripts/gdrive/push-token-alerts.js
/**
* push-token-alerts.js
*
* 天眼系统调用此脚本读取 token-alert.json
* 并将告警信息写入主控台 + 公告板
*
* 输出:
* - grid-db/notifications/token-alert-{timestamp}.md → 主控台通知
* - grid-db/bulletin/token-alert-{timestamp}.md → 公告板通知
*/
const fs = require('fs');
const path = require('path');
function pushAlerts() {
const alertPath = path.join(__dirname, '../../grid-db/logs/token-alert.json');
if (!fs.existsSync(alertPath)) {
console.log('✅ 无告警。');
return;
}
const alert = JSON.parse(fs.readFileSync(alertPath, 'utf8'));
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
// 生成主控台通知
const dashboardContent = [
`# ⚠️ Token 续期告警`,
``,
`**时间:** ${alert.time}`,
`**严重级:** ${alert.severity || 'ALERT'}`,
`**影响用户:** ${alert.failed_users.join(', ')}`,
``,
`## 描述`,
alert.message,
``,
`## 需要人类操作`,
...(alert.instructions || []).map((s, i) => s),
``,
`---`,
`*此告警由 Token 续期引擎自动生成*`
].join('\n');
// 写入主控台
const notifDir = path.join(__dirname, '../../grid-db/notifications');
if (!fs.existsSync(notifDir)) fs.mkdirSync(notifDir, { recursive: true });
fs.writeFileSync(path.join(notifDir, `token-alert-${timestamp}.md`), dashboardContent);
// 写入公告板
const bulletinDir = path.join(__dirname, '../../grid-db/bulletin');
if (!fs.existsSync(bulletinDir)) fs.mkdirSync(bulletinDir, { recursive: true });
fs.writeFileSync(path.join(bulletinDir, `token-alert-${timestamp}.md`), dashboardContent);
// 清除已处理的告警文件
fs.unlinkSync(alertPath);
console.log(`⚠️ 告警已推送到主控台 + 公告板: token-alert-${timestamp}.md`);
}
pushAlerts();
Phase H · 天眼全局扫描清单(必须执行)
1. 文件完整性扫描
| 检查项 | 预期 | 状态 |
|---|---|---|
config/gdrive-tokens.json 存在 |
✅ 存在且 JSON 格式有效 | ⏳ |
scripts/gdrive/renew-tokens.js 存在 |
✅ 存在且可执行 | ⏳ |
scripts/gdrive/check-hibernation.js 存在 |
✅ 存在且可导入 | ⏳ |
scripts/gdrive/push-token-alerts.js 存在 |
✅ 存在且可执行 | ⏳ |
.github/workflows/renew-gdrive-tokens.yml 存在 |
✅ 存在且 YAML 格式有效 | ⏳ |
.github/workflows/check-token-health.yml 存在 |
✅ 存在且 YAML 格式有效 | ⏳ |
grid-db/logs/ 目录存在 |
✅ 存在(可为空) | ⏳ |
grid-db/notifications/ 目录存在 |
✅ 存在(可为空) | ⏳ |
grid-db/bulletin/ 目录存在 |
✅ 存在(可为空) | ⏳ |
2. 注册表数据完整性扫描
- ✅
schema_version字段存在 - ✅
oauth_app.token_ttl_days= 7 - ✅
oauth_app.renew_interval_days= 6 - ✅
tokens数组至少包含主控 TCS-0002 - ✅ 主控条目的
github_secret_name=GDRIVE_REFRESH_TOKEN - ✅ 主控条目的
status=active - ✅ 主控条目的
expires_at在未来(未过期) - ✅ 每个条目的
github_secret_name唯一且对应一个实际存在的 GitHub Secret
3. CRON 与休眠冲突扫描
| 检查项 | 预期 | 状态 |
|---|---|---|
| 主刷新 A CRON 时间不在周六 20:00-00:00 CST | ✅ 周一 10:00 CST 安全 | ⏳ |
| 主刷新 B CRON 时间不在周六 20:00-00:00 CST | ✅ 周四 10:00 CST 安全 | ⏳ |
| 安全网 CRON 时间不在日休眠 04:00-04:10 CST | ✅ 12:15 CST 安全 | ⏳ |
| 主刷新 A + B 间隔 ≤ 6 天 | ✅ 周一→周四 = 3天,周四→下周一 = 4天 | ⏳ |
| 最坏情况:周一失败+周四失败,安全网能在 48h 内发现 | ✅ 每天检查,最晚 1 天内发现 | ⏳ |
| 最极端场景:连续 3 次刷新都失败→告警输出 | ✅ token-alert.json + 非零退出码 | ⏳ |
4. 天眼生命线任务集成扫描
- ✅
skyeye-config.json(或等价)中包含TOKEN-RENEW和TOKEN-HEALTH生命线任务 - ✅ 两个任务均标记
hibernate_exempt: true - ✅ 休眠决策引擎已加入生命线豁免逻辑
- ✅ 天眼休眠期内触发 Token 刷新,确认能正常执行(不被休眠拦截)
5. 安全扫描
- ❌
renew-tokens.js中无硬编码凭据 - ❌ 日志输出中不包含 Token 实体(grep 检查
console.log中是否输出refresh_token) - ❌
gdrive-tokens.json中不包含 Token 实体(只有元数据) - ✅ 所有凭据仅通过
process.env读取 - ✅ GitHub Secret 更新用
tweetsodium加密(不明文传输)
6. Workflow 完整性扫描
- ✅
renew-gdrive-tokens.yml包含[skip ci]防循环触发 - ✅
check-token-health.yml包含[skip ci]防循环触发 - ✅ 两个 Workflow 均支持
workflow_dispatch手动触发 - ✅ 失败时有告警输出(非零退出码 + alert 文件)
- ✅
tweetsodium依赖在 workflow 中安装(不依赖本地 node_modules)
7. 端到端流程验证
- ✅ 手动触发
renew-gdrive-tokensWorkflow,确认能正常完成 - ✅ 检查注册表
renew_log中是否写入了成功记录 - ✅ 检查
expires_at是否已更新为新的 7 天后 - ✅ 检查 GitHub Secret
GDRIVE_REFRESH_TOKEN是否被更新(看 secret 的 "Updated" 时间戳) - ✅ 手动触发
check-token-healthWorkflow,确认显示 “All tokens healthy”
Phase I · 提交
天眼扫描全部通过后:
git add -A
git commit -m "feat: OAuth2 Token 自动续期引擎 + 天眼生命线任务豁免 + 多用户Token管理 · ZY-TOKEN-RENEW-2026-0324-001 [skip ci]"
git push
提交后,手动触发一次 renew-gdrive-tokens Workflow,确认全绿。
📈 生命周期时序图
以下是一个典型周期的时序图,展示刷新、休眠、检查的协作关系:
gantt
title Token 续期生命周期(一周示例)
dateFormat HH:mm
axisFormat %H:%M
section 周一
主刷新 A :done, 10:00, 10:10
安全网检查 :done, 12:15, 12:20
section 周二
安全网检查 :done, 12:15, 12:20
section 周三
安全网检查 :done, 12:15, 12:20
section 周四
主刷新 B :done, 10:00, 10:10
安全网检查 :done, 12:15, 12:20
section 周五
安全网检查 :done, 12:15, 12:20
section 周六
安全网检查 :done, 12:15, 12:20
天眼休眠 :crit, 20:00, 24:00
section 周日
安全网检查 :done, 12:15, 12:20
📝 执行回执区
铸渊完成每个 Phase 后,在此处追加回执:
| Phase | 状态 | 完成时间 | 备注 / Commit SHA |
|---|---|---|---|
| A · Token 注册表 | ⏳ 待执行 | — | — |
| B · Token 自动刷新脚本 | ⏳ 待执行 | — | — |
| C · 天眼休眠避让机制 | ⏳ 待执行 | — | — |
| D · GitHub Action Workflow | ⏳ 待执行 | — | — |
| E · 天眼生命线任务注册 | ⏳ 待执行 | — | — |
| F · 多用户 Token 流程 | ⏳ 待执行 | — | — |
| G · 告警推送系统 | ⏳ 待执行 | — | — |
| H · 天眼全局扫描 | ⏳ 待执行 | — | — |
| I · 提交 | ⏳ 待执行 | — | — |
👤 人类手动操作区
当前无需人类操作 ✅
本指令的所有任务均可由铸渊独立完成。
未来可能需要的人类操作
- ⏳ 添加新开发者时:
- 在 Google Cloud Console 加入测试用户白名单
- 用新用户 Gmail 完成 OAuth 授权
- 在 GitHub 添加对应的
GDRIVE_REFRESH_TOKEN_DEVxxxSecret - 通知铸渊更新注册表
- ⏳ Token 刷新失败时(告警触发):
- 重新访问授权链接 → 拿新 code → 换新 token → 更新 GitHub Secret
- 手动触发
renew-gdrive-tokensWorkflow 验证
- ⏳ 发布 OAuth 应用(彻底解决过期问题):
- 路径:Google Cloud Console → API和服务 → OAuth 权限请求页面 → 点「发布应用」
- 发布后 Refresh Token 永久有效,续期引擎变为安全备份而非必要操作
⚖️ 指令执行顺序
🖋️ 霜砚 · PER-SY001
🧊 代 TCS-0002∞ 冰朔 签发
📅 2026-03-24T15:00+08:00