Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ concurrency:

jobs:
refresh-token:
if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
id-token: write
steps:
- name: Checkout Code
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
Expand All @@ -46,11 +50,16 @@ jobs:
google-chrome --version
npm ci

- name: Authenticate to Google Cloud with OIDC
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3
with:
workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ vars.GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}

# SCHWAB_PROXY_URL retired on 2026-11-02; keep the secret, but do not read it.
- name: Run Refresh Script
run: npm start
env:
GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}
SCHWAB_USERNAME: ${{ secrets.SCHWAB_USERNAME }}
SCHWAB_PASSWORD: ${{ secrets.SCHWAB_PASSWORD }}
SCHWAB_TOTP_SECRET: ${{ secrets.SCHWAB_TOTP_SECRET }}
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,17 @@ node tests/test_auth_code_extraction.js
| `SCHWAB_REDIRECT_URI` | Yes | none | OAuth redirect URI registered with the application. |
| `GCP_PROJECT_ID` | Yes | none | Google Cloud project that holds the secret. |
| `GCP_SECRET_ID` | Yes | none | Secret Manager secret to update. |
| `GCP_SA_KEY` | No | ambient credentials | Service account key JSON when ambient credentials are not available. |
| `GCP_SA_KEY` | No | ambient credentials | Legacy option for local callers using a service account key. |
| `GCP_SECRET_VERSION_RETENTION` | No | `1` | Number of secret versions to keep; older versions are permanently destroyed and cannot be restored. |
| `TELEGRAM_TOKEN` | For workflow alerts | `TG_TOKEN` | Unified Telegram bot token (QSL 资产管家 bot). |
| `GLOBAL_TELEGRAM_CHAT_ID` | For workflow alerts | none | Alert chat IDs, separated by commas, semicolons, or whitespace. |

Set the GitHub variables `GCP_WORKLOAD_IDENTITY_PROVIDER` and
`GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT` for the scheduled workflow. Configure
the provider to accept this repository's default-branch refresh workflow.
Grant the refresh identity only the Secret Manager version permissions used by
the workflow, on the configured destination secret.

The workflow makes one direct refresh attempt. On failure it sends a Telegram
alert with the workflow run link, then leaves the job failed. Alert delivery
errors or missing bot configuration also fail the alert step. No refresh errors,
Expand Down
4 changes: 3 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ node tests/test_auth_code_extraction.js
| `SCHWAB_REDIRECT_URI` | 是 | 无 | 在应用中登记的 OAuth 回调地址。 |
| `GCP_PROJECT_ID` | 是 | 无 | 存放密钥的 Google Cloud 项目。 |
| `GCP_SECRET_ID` | 是 | 无 | 要更新的 Secret Manager 密钥。 |
| `GCP_SA_KEY` | 否 | 环境默认凭据 | 无法使用环境默认凭据时提供的 service account key JSON。 |
| `GCP_SA_KEY` | 否 | 环境默认凭据 | 仍使用服务账号密钥的本地调用者可用。 |
| `GCP_SECRET_VERSION_RETENTION` | 否 | `1` | 保留的密钥版本数量;更早的版本会被永久销毁,无法恢复。 |
| `TELEGRAM_TOKEN` | 工作流告警需要 | `TG_TOKEN` | 统一 Telegram bot(QSL 资产管家 bot)的 token。 |
| `GLOBAL_TELEGRAM_CHAT_ID` | 工作流告警需要 | 无 | 告警 chat ID,多个 ID 用逗号、分号或空白分隔。 |

定时工作流使用 GitHub OIDC。设置 GitHub 变量 `GCP_WORKLOAD_IDENTITY_PROVIDER` 和 `GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT`,让 Google 只信任本仓库默认分支的刷新工作流。把刷新用到的 Secret Manager 版本操作权限限制到目标密钥。

工作流只进行一次直连刷新。失败时发送带工作流链接的 Telegram 告警,并保留任务失败状态。告警发送失败或缺少 bot 配置时,告警步骤也会失败。消息不包含刷新错误详情、凭据或 token 响应。

为统一 bot 配置 GitHub Actions secrets:`TELEGRAM_TOKEN`(或已有的 `TG_TOKEN`)和 `GLOBAL_TELEGRAM_CHAT_ID`。测试使用模拟请求,不发送真实告警。
Expand Down
9 changes: 8 additions & 1 deletion tests/test_workflow_config_sources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ workflow_file="$repo_dir/.github/workflows/main.yml"
grep -Fq 'GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }}' "$workflow_file"
grep -Fq 'GCP_SECRET_ID: ${{ vars.GCP_SECRET_ID }}' "$workflow_file"
grep -Fq 'SCHWAB_REDIRECT_URI: ${{ vars.SCHWAB_REDIRECT_URI }}' "$workflow_file"
grep -Fq 'GCP_SA_KEY: ${{ secrets.GCP_SA_KEY }}' "$workflow_file"
grep -Fq 'id-token: write' "$workflow_file"
grep -Fq 'workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}' "$workflow_file"
grep -Fq 'service_account: ${{ vars.GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}' "$workflow_file"
grep -Fq 'github.ref_name == github.event.repository.default_branch' "$workflow_file"
if grep -Fq 'GCP_SA_KEY' "$workflow_file"; then
echo "workflow must use federated Google credentials" >&2
exit 1
fi
grep -Fq 'TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN || secrets.TG_TOKEN }}' "$workflow_file"
grep -Fq 'GLOBAL_TELEGRAM_CHAT_ID: ${{ secrets.GLOBAL_TELEGRAM_CHAT_ID }}' "$workflow_file"
grep -Fq 'run: node scripts/notify_refresh_failure.js' "$workflow_file"
Expand Down
Loading