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
91 changes: 64 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,89 @@
# SchwabTokenAutoRefresher

[Chinese README](README.zh-CN.md)
A scheduled utility that refreshes the Charles Schwab OAuth token and stores it in Google Cloud Secret Manager.

SchwabTokenAutoRefresher is a QuantStrategyLab credential automation utility. It runs the Schwab OAuth token refresh flow on a schedule and syncs the refreshed credentials to Google Cloud Secret Manager, so other platform services always have a valid token without manual renewal. It supports the system but does not decide which strategy should go live: strategy eligibility stays with the strategy and snapshot repositories, and broker execution stays with the platform repositories.
English | [简体中文](README.zh-CN.md)

> Investing involves risk. This project does not provide investment advice and is for education, research, and engineering review only.
## Status

## Design boundary
Experimental. Use at your own risk. This project is not financial advice and
does not guarantee any trading result. It handles broker credentials on behalf
of other services, so a misconfiguration can stop those services from
authenticating. It does not place orders.

- Keep contracts stable and versioned where downstream repositories depend on them.
- Prefer backward-compatible changes unless a coordinated migration is planned.
- Keep secrets and environment-specific settings outside the shared library code.
- Document changes that affect multiple platforms or strategy packages.
## What this is

## Repository layout
SchwabTokenAutoRefresher refreshes a Charles Schwab OAuth token on a schedule
and writes the refreshed credentials to Google Cloud Secret Manager, so
dependent services keep a valid token without manual renewal. It uses Playwright
to complete the broker login, including TOTP two-factor authentication, and can
route the login through an outbound HTTP proxy. It runs on Node.js 20.

## What this is not

- `tests/`: unit, contract, and regression tests.
- `.github/workflows/`: CI, scheduled jobs, release, or deployment workflows.
It does not place, modify, or cancel orders. It does not decide which strategies
are eligible to run. It is not a general-purpose secret manager, and it does not
replace the broker platform that consumes the token.

## Quick start

Requires Node.js 20.x and npm.

```bash
npm ci
```

## Useful docs
The refresher reads credentials from the environment and needs a browser
session, so run it under a headless X server as the `start` script does:

- No separate `docs/` directory yet; start with this README and the workflow files.
```bash
npm start
```

## QSL architecture role
The unit tests are plain Node scripts; they do not contact the broker:

- **Layer**: `platform-tooling`.
- **Responsibility**: Schwab OAuth token refresh automation utility.
- **Owns**: token refresh flow and Secret Manager sync behavior.
- **Consumes**: Schwab auth endpoints, Google Secret Manager, CharlesSchwabPlatform.
- **Must not**: decide strategy eligibility or log sensitive token values.
```bash
node tests/test_auth_retry.js
node tests/test_proxy_config.js
node tests/test_auth_code_extraction.js
```

## Configuration

| Variable | Required | Default | Purpose |
|---|---|---|---|
| `SCHWAB_USERNAME` | Yes | none | Broker login name. |
| `SCHWAB_PASSWORD` | Yes | none | Broker login password. |
| `SCHWAB_TOTP_SECRET` | Yes | none | Base32 secret used to generate TOTP codes. |
| `SCHWAB_API_KEY` | Yes | none | OAuth application key. |
| `SCHWAB_APP_SECRET` | Yes | none | OAuth application secret. |
| `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_SECRET_VERSION_RETENTION` | No | `1` | Number of secret versions to keep; older versions are permanently destroyed and cannot be restored. |
| `SCHWAB_PROXY_URL` | No | none | HTTP proxy for the login flow. |
| `SCHWAB_FORCE_PROXY_FIRST` | No | disabled | Use the proxy before a direct connection when set to `true`. |

## Repository layout

```
main.js scheduled refresh entrypoint
lib/ proxy, OAuth, and retry helpers
tests/ unit tests (use installed dependencies)
prompts/ review prompt text
scripts/ operator helpers
```

## QSL compatibility
## Contributing

- `qsl.toml` records `tier`, `upgrade_ring`, and `compat.bundle` for compatibility checks.
- This Node.js token refresh utility uses `npm` for dependency installation.
See [CONTRIBUTING.md](CONTRIBUTING.md).

## Community and security
## Security

- See [CONTRIBUTING.md](CONTRIBUTING.md) for pull request scope, local verification, and documentation expectations.
- Follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for maintainer and contributor conduct.
- Report credential, automation, broker, exchange, or cloud-resource vulnerabilities through [SECURITY.md](SECURITY.md); do not open public issues for secrets or live-execution risk.
See [SECURITY.md](SECURITY.md). Do not open a public issue for a vulnerability.
Never commit credentials or token material.

## License

See [LICENSE](LICENSE).
MIT. See [LICENSE](LICENSE).
80 changes: 53 additions & 27 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,78 @@
# SchwabTokenAutoRefresher

[English README](README.md)
按计划刷新 Charles Schwab OAuth token,并写入 Google Cloud Secret Manager 的工具。

SchwabTokenAutoRefresher 是 QuantStrategyLab 的凭据自动化工具,按计划刷新 Schwab OAuth token,并把刷新后的凭据同步到 Google Cloud Secret Manager,让其他平台服务随时能拿到有效凭据,不需要人工续期。它支撑系统运行,但不决定哪个策略应该 live:策略资格由策略仓和 snapshot 仓负责,券商执行由平台仓负责。
[English](README.md) | 简体中文

> 投资有风险。本项目不构成投资建议,仅用于学习、研究和工程审阅。
## 状态

## 设计边界
实验性项目,使用风险自负。本项目不构成投资建议,也不保证任何交易结果。它代替其他服务管理券商凭据,配置错误会导致这些服务无法完成认证。它不提交订单。

- 下游仓库依赖的契约要保持稳定,必要时做版本化。
- 除非有协同迁移计划,否则优先保持向后兼容。
- 密钥和环境专属配置不要写进共享库代码。
- 会影响多个平台或策略包的改动,需要在文档中说明。
## 简介

## 仓库结构
SchwabTokenAutoRefresher 按计划刷新 Charles Schwab OAuth token,并把刷新后的凭据写入 Google Cloud Secret Manager,让依赖它的服务无需人工续期即可持有有效 token。它用 Playwright 完成券商登录,包括 TOTP 双因素认证,并支持通过出站 HTTP 代理访问。运行环境为 Node.js 20。

## 不适用范围

- `tests/`:单元测试、契约测试和回归测试。
- `.github/workflows/`:CI、定时任务、发布或部署 workflow。
它不提交、修改或撤销订单。它不决定哪些策略可以运行。它不是通用的密钥管理服务,也不替代消费该 token 的平台仓库。

## 快速开始

需要 Node.js 20.x 和 npm。

```bash
npm ci
```

## 延伸文档
刷新器从环境变量读取凭据,并且需要浏览器会话,因此在无显示环境下要像 `start` 脚本那样用 headless X server 运行:

- 暂无独立 `docs/` 目录;请先阅读本 README 和 workflow 文件。
```bash
npm start
```

## QSL 架构角色
单元测试是普通的 Node 脚本,不会访问券商:

- **层级**:`平台工具`。
- **职责**:Schwab OAuth token refresh 自动化工具。
- **事实源/归属**:token refresh flow 和 Secret Manager sync 行为。
- **消费对象**:Schwab auth endpoints、Google Secret Manager、CharlesSchwabPlatform。
- **禁止事项**:决定策略 eligibility 或记录敏感 token 值。
```bash
node tests/test_auth_retry.js
node tests/test_proxy_config.js
node tests/test_auth_code_extraction.js
```

## 配置

| 变量 | 必填 | 默认值 | 用途 |
|---|---|---|---|
| `SCHWAB_USERNAME` | 是 | 无 | 券商登录名。 |
| `SCHWAB_PASSWORD` | 是 | 无 | 券商登录密码。 |
| `SCHWAB_TOTP_SECRET` | 是 | 无 | 生成 TOTP 验证码的 Base32 密钥。 |
| `SCHWAB_API_KEY` | 是 | 无 | OAuth 应用 key。 |
| `SCHWAB_APP_SECRET` | 是 | 无 | OAuth 应用 secret。 |
| `SCHWAB_REDIRECT_URI` | 是 | 无 | 在应用中登记的 OAuth 回调地址。 |
| `GCP_PROJECT_ID` | 是 | 无 | 存放密钥的 Google Cloud 项目。 |
| `GCP_SECRET_ID` | 是 | 无 | 要更新的 Secret Manager 密钥。 |
| `GCP_SA_KEY` | 否 | 环境默认凭据 | 无法使用环境默认凭据时提供的 service account key JSON。 |
| `GCP_SECRET_VERSION_RETENTION` | 否 | `1` | 保留的密钥版本数量;更早的版本会被永久销毁,无法恢复。 |
| `SCHWAB_PROXY_URL` | 否 | 无 | 登录流程使用的 HTTP 代理。 |
| `SCHWAB_FORCE_PROXY_FIRST` | 否 | 关闭 | 设为 `true` 时优先经代理连接,再尝试直连。 |

## 仓库结构

```
main.js 定时刷新入口
lib/ 代理、OAuth 和重试辅助模块
tests/ 单元测试(使用已安装的依赖)
prompts/ 审阅提示词
scripts/ 运维脚本
```

## QSL 兼容性
## 参与贡献

- `qsl.toml` 记录 `tier`、`upgrade_ring` 和 `compat.bundle`,用于兼容性检查。
- 这个 Node.js token 刷新工具通过 `npm` 安装依赖。
见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## 社区和安全
## 安全

- 贡献前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md),确认 PR 范围、本地校验和文档要求。
- 讨论、issue 和 review 请遵守 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)。
- 涉及密钥、自动化、券商/交易所或云资源的漏洞请按 [SECURITY.md](SECURITY.md) 私密报告;不要为 secret 或实盘风险开公开 issue。
见 [SECURITY.md](SECURITY.md)。安全漏洞不要开公开 issue,也不要把凭据或 token 提交到仓库。

## 许可证

详见 [LICENSE](LICENSE)。
MIT,见 [LICENSE](LICENSE)。
Loading