Skip to content

feat(config): YAML 配置面整体迁移至 Dashboard Config 页(config.db + 热切换 + 密钥加密) - #288

Merged
ThreeFish-AI merged 8 commits into
feature/1.x.xfrom
feature-migrate-yaml-config
Nov 14, 2026
Merged

ThreeFish-AI merged 8 commits into
feature/1.x.xfrom
feature-migrate-yaml-config

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

变更摘要

将 config.default.yaml 及用户 YAML 承载的全部配置迁移至 Dashboard Config 页(/dashboard?tab=config)在线管理,YAML 不再是运行时配置来源。

  • 存储:新增 ~/.coding-proxy/config.db(sqlite3、0600、secure_delete、per-section revision 乐观并发)为唯一配置存储;config.default.yaml 退化为随包发布的默认值基线,存储只保存与默认 diff 后的最小覆盖,未改动的部分跟随版本升级(消除旧版首启整份复制导致的默认值冻结)。
  • 迁移:首次 start 自动一次性导入现有 YAML(-c 路径或 ~/.coding-proxy/config.yaml),导入前跑等价门校验(新旧加载产物 ProxyConfig 全等,含 ¥ 币种),不过则不建库、本次按旧 YAML 只读运行;源文件不改名不改写,marker 记 sha256,此后漂移拒启;./config.yaml 不自动导入。
  • 密钥保密:密钥按稳定路径独立存表并 Fernet 加密(master.key 0600 或 CODING_PROXY_MASTER_KEY 覆写 + key-check canary);API 只写不读(Stored / Env / Empty 三态 + 尾 4 位提示);vendor 目标地址(base_url / token_url)变更自动清空关联密钥;HTTP 写入含 ${ 的字面量与控制字符一律拒绝;校验错误永不回显输入值。
  • 生效方式:保存即进程内 generation 热切换(preflight 构建 → lifespan 独立 task → 原子切换 → 旧代排空后关闭),无停机、长流式请求跑完;启用失败保留旧配置;启动失败进入 degraded 模式(/v1/* 503,Config 页可修复并在线恢复)。
  • 管理面安全:admin token(~/.coding-proxy/admin_token 0600,X-Coding-Proxy-Admin 头 + 常量时间比较);全局跨站(Sec-Fetch-Site/Origin)拦截 + Host 白名单(loopback + 本机 IP + server.allowed_hosts);uvicorn proxy_headers=False 防 XFF 伪造;/docs /redoc 关闭;非 Dashboard 响应加 sandbox CSP + nosniff;修复 Dashboard 两处存量 XSS 汇点;流式/非流式异常日志收敛为类型 + 帧栈(杜绝密钥经错误响应或日志外泄)。
  • CLI:新增 coding-proxy config path/export/import/set/reset/set-secret/token;bootstrap 字段(server.host/port/allowed_hosts、logging.*、database.*、auth.token_store_path)仅 CLI 可改(UI 只读);顺带修复 usage --db 被误当配置路径的问题。
  • 前端:8 个分区 + 9 供应商子页全字段编辑(英文 label 1/12 宽 + ⓘ 中文说明 + 固定 px 列宽 token)、密钥三态控件、单一 Save 与确认框(运行时影响 / 将清空密钥)、409/422/423 定位到字段、dirty 跟踪;admin token 经 #admin= fragment 一次性解锁;Chart.js SRI + CSP,CDN 不可达时页签仍可用。

动机

原有 YAML 配置链路存在四类结构性问题:默认值多写漂移、首启整份复制把存量用户冻结在旧默认、管理 API 无鉴权(跨站 CSRF / 同机进程可滥用)、密钥明文散落在 YAML 与 ${VAR} 展开结果中(见 docs/.agents/issue.md I-001)。

验证结果

  • 全量测试 1998 passed(≈44s,< 3 min),ruff check / format 干净;新增 store/加密/三态/最小化不动点/导入等价矩阵(含历史全量拷贝、legacy flat、alias key、¥ 定价、NATIVE_* env、-c 路径)/CLI/安全 guard 矩阵/API 脱敏/generation swap/degraded/registry 覆盖门/前端 DOM harness 等测试。
  • 实现经四轮多 Agent 流水线(理解 → 设计对抗评审 → 分层实现 + 独立核验 → 集成对抗评审),处置 30+ 问题,含 2 个集成级 major(控制字符密钥经 SSE/日志回显、文档面滞后),均已修复并附回归测试。
  • 浏览器实机验证(隔离实例 + scratch home):首启 YAML 一次性导入 → Config 页各 section 编辑 → 设密钥(Stored ••••4321,DOM/日志/config.db 均无明文)→ 保存热切换即时生效(/api/status 顺序变化无需重启)→ 422 行内报错 → 跨站 403、Sec-Fetch-Site: none(真实地址栏输入)放行。
  • 兼容性:升级后首个 start 自动导入并打印提示;用户现有 3392 实例(v0.5.2)不受影响。

风险点

🤖 Generated with Claude Code

新增 $CODING_PROXY_HOME/config.db(sqlite3 0600、secure_delete、per-section revision 乐观并发)作为唯一配置存储:config.default.yaml 退化为随包基线,存储仅保存与默认 diff 后的最小覆盖,未触碰 section 跟随包升级。密钥按稳定路径独立存表并以 Fernet 加密(master.key 0600 / CODING_PROXY_MASTER_KEY 覆写 + key_check canary,key 不匹配绝不重生成),HTTP/CLI 统一只写不读;vendor 目标地址变更自动清空关联密钥,HTTP 写入含 ${ 的字面量与控制字符一律拒绝。resolver 提供 defaults ⊕ overrides ⊕ secrets → $tmpl 展开 → ProxyConfig 的纯解析;importer 实现旧 YAML 一次性导入(等价门:新旧 loader 产物全等,不过则不建库、legacy 只读运行),源文件不改名、marker 记 sha256、漂移拒启;首启整份复制行为移除,所有 ~/.coding-proxy 字面量路径统一由 proxy_home() 推导。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
config path/export/import/set/reset/set-secret/token 覆盖 bootstrap 字段修改与密钥三态管理;start 经 boot() 完成一次性导入与漂移检查并打印带 admin token 的 Dashboard 链接;usage --db 修复为真正覆盖 database.path(此前被误当配置路径传入 load_config);auth 子命令读取新解析路径,auto-login 行为保持不变。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
SecurityMiddleware 双 L 防护(L1 全局跨站/Origin 拦截、L2 Host 白名单 + 本机 IP + allowed_hosts),/api/config* 强制 X-Coding-Proxy-Admin(常量时间比较)且只写不读、422 永不回显输入、响应 no-store;uvicorn proxy_headers=False 防 XFF 伪造 loopback;/docs /redoc 关闭;流式与非流式异常日志收敛为类型+帧栈(杜绝密钥经 SSE/日志外泄)。GenerationManager 实现无停机热切换:preflight 构建 → lifespan 独立 task → 原子切换 → 旧代排空 600s 后关闭,in-flight 覆盖流式/断连,reauth 跨代交接;启动失败回退 degraded 模式(/v1 503、Config 页可修复并在线恢复);create_app 移除 legacy YAML 回退。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
8 个 section pills + 9 供应商子页 + 全字段表单(英文 label 1/12 宽 + ⓘ 中文说明同行、固定 px 列宽 token、密钥三态控件)、单一 Save 汇总与确认框(运行时影响/将清空密钥)、409/422/423 定位到字段、dirty 跟踪与 beforeunload;admin token 经 #admin= fragment 解锁仅存 localStorage;静态资源内容 hash 缓存、Chart.js SRI + CSP,CDN 不可达时页签仍可用;修复图表 tooltip 与 vendor 名两处 XSS 汇点。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
conftest 全局隔离(HOME/CODING_PROXY_HOME/CWD 指向 tmp + audit hook 守护真实 ~/.coding-proxy);覆盖 store/加密/三态/最小化不动点/导入等价矩阵(含历史全量拷贝、legacy flat、alias、¥ 定价、NATIVE_* env)/CLI/安全 guard 矩阵/API 脱敏/generation swap/degraded/registry 覆盖门/前端 DOM harness;既有 test_config_init 重写为不再复制语义。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
config-reference(SSOT:解析与存储、密钥、一次性导入)重写并以 A 档四件套图(dataflow/showcase,双主题 SVG)替换 mermaid 块;quickstart/cli-reference/dashboard(含 Config 页章节与实操截图)/api-reference(§11 配置端点)/monitoring/user-guide/README 及 zh-CN 镜像/framework/knowledge-map 同步;CHANGELOG 新增 [Unreleased];issue.md 迁移为索引表 + I-xxx 双层结构并登记 I-001;.gitignore 收敛 .archify/。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
服务端:目标地址清空规则收紧为「新目标 ≠ 包内默认端点才清空」(reset/改回默认保留密钥,兑现 Reset 不丢密钥承诺);HTTP 写 vendors 内联密钥字段由静默剥离改为 422;CLI set 拒绝 legacy flat/alias 死配置;list 形态 session_policies 归一为 dict 落库(消除 Config 页死区);-c 显式路径缺失 fail-fast 不再固化空 marker;cwd config.yaml 与 home 无关 YAML 分别纳入写入前置拦截与导入源过滤;ensure_home/create_private_file 的 OSError 映射为 StoreAccessError 并补齐三处调用方降级捕获;no-op 热切换判定改用 pin 后 prepared 配置(bootstrap 漂移后空保存不再整代换代);logging.file 空串真正禁用文件日志。
前端:predictClearedSecrets 与服务端规则三方对齐(recorded / 新建覆盖物化 / empty 记录 / 默认端点豁免均不误报);list 排序展开态随条目平移;409 定向重载失败链路修正(提示如实、重试限定范围、401 不叠 fatal 视图)。
文档:config-reference/api-reference/cli-reference/quickstart/user-guide/vendors/testing/issue.md/CHANGELOG 同步以上语义(含 strict 拒启精确口径、allowed_hosts 与 logging.file 字段行、secrets 载荷 recorded/default_env、Archify 链接锚点修复、issue.md 双层结构与完成日期回填)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
GITHUB_ACTIONS 环境变量会让 typer 强制输出彩色 rich 帮助信息,
--port 被拆成带转义的分片,先剥离 ANSI 转义再断言。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI
ThreeFish-AI merged commit cae901d into feature/1.x.x Nov 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant