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
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
if: runner.os == 'Windows'
shell: pwsh
run: |
$pkg = "orcha-v${{ github.ref_name }}-windows-x86_64"
$pkg = "orcha-${{ github.ref_name }}-windows-x86_64"
New-Item -ItemType Directory -Path $pkg -Force
Copy-Item target/${{ matrix.target }}/release/orcha-gateway${{ matrix.ext }} $pkg/
Copy-Item install.ps1 $pkg/
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
uses: softprops/action-gh-release@v2
with:
name: Orcha ${{ github.ref_name }}
body_path: RELEASE_v0.1.0-beta.md
body_path: RELEASE_${{ github.ref_name }}.md
files: artifacts/*
draft: false
prerelease: ${{ contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
65 changes: 65 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Changelog

本项目所有重要变更记录于此。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。

beta / alpha 版本为预发布,API 与行为可能在正式版前调整。

---

## [v0.1.2-beta] - 2026-07-10

安全加固版本:按高危优先级修复 9 个安全 issue(4 CRITICAL + 5 HIGH)。
所有修复均有回归测试覆盖,CI 双平台(ubuntu/windows)fmt + clippy(-D warnings) + test 全绿。

### CRITICAL 修复

- **命令超时未杀子进程(#7)**:`execute_run_command` 超时只 kill 直接子进程,
孙进程成为孤儿继续运行。改为 `process_group(0)` + `killpg(SIGKILL)` 杀整个进程组。
新增测试验证孙进程确被杀死(`#[cfg(unix)]` 编译期门控,Windows 不编译)。
- **HTTP server 无认证(#16)**:任意本机进程可读写任务/记忆。新增可选访问令牌
认证,支持 Bearer / Cookie / `?token=` 三种凭证;`None` 保持旧行为(向后兼容)。
CLI 增加 `--token` / `ORCHA_SHELL_TOKEN`。
- **运行时白名单仅匹配 basename(#20)**:批准 `src/main.rs` 后 `tests/main.rs`、
`vendor/main.rs` 等同名文件均命中白名单越权写/删。改为按完整规范化相对路径
(统一分隔符、消去 `.`、解析 `..`)匹配。顺带清理同 crate 内 `queue.rs` 的
clippy `useless_borrows_in_formatting` 预存 lint。
- **CORS 设为 `*`(#23)**:任意网站可跨域读取 API。移除 `cors()` 与所有
`Access-Control-Allow-Origin: *` 响应头,回归默认同源策略。

### HIGH 修复

- **Unix socket 权限过松(#17)**:默认 umask(常 0755/0777),同机其他用户可连入。
bind 后 `set_permissions(0o600)`,失败则清理 socket 并报错。
- **审批 action_id 可预测(#22)**:用 `SystemTime` 纳秒 + `AtomicU64` 计数器,
可推算后伪造 `ApprovalResponse` 越权。改用 `uuid::Uuid::new_v4()`(CSPRNG)。
- **IPC TCP 无认证/加密(#26)**:任意本机进程可注入伪造触发/审批、读取全量流量。
TCP 后端新增共享密钥握手:客户端首行 `AUTH <secret>\n`,服务端定长比较
(`constant_time_eq` 防 timing attack)通过才进 JSON-line;Unix socket 靠 0600
保护跳过握手。配置 `config.ipc.tcp_secret` 或 `ORCHA_IPC_TCP_SECRET` 环境变量。
- **Feishu adapter 无界内存增长(#24)**:三个 `Map`(cardMsgIds /
approvalCardMsgIds / approvalActions)只增不减,超时审批/孤儿卡片永不清理 → OOM。
新增 `TTLMap`(TTL 1h + LRU maxSize 5000 + 节流 cleanup)替换。
- **API 错误响应泄露内部细节(#27)**:`{"error":"{e}"}` 泄露文件路径/DB 路径/
模块结构。改返回 `{"error":"internal_error","correlation_id":"<uuid v4>"}`,
详细错误记服务端日志。

### CI / 工程改进

- release.yml 的 release body_path 从写死的 `RELEASE_v0.1.0-beta.md` 改为
动态 `RELEASE_${{ github.ref_name }}.md`,避免每次发版都要改 workflow。

### 测试

完整 workspace 测试 `cargo test --workspace --features orcha-core/llm` 全绿:
orcha-core 223 · orcha-gateway 67 · orcha-llm 46 · orcha-shell 13 ·
orcha-cli 40 · orcha-sdk 14,共 400+ tests,0 failed。
TS 端 `tsc --noEmit` 无错误。

---

## [v0.1.0-beta] - 2026-07-04

首个预发布版本。92 次提交,从零到飞书联调闭环。

详见 [RELEASE_v0.1.0-beta.md](RELEASE_v0.1.0-beta.md)。
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions RELEASE_v0.1.2-beta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Orcha v0.1.2-beta

> 安全加固版本:按高危优先级修复 9 个安全 issue。

本次发版聚焦安全:4 个 CRITICAL + 5 个 HIGH,每个 issue 一个独立 commit,
commit message 均带工单号(`fix(#N)`)并附验证通过的证明。CI 双平台
(ubuntu-latest / windows-latest)fmt + clippy(`-D warnings`) + test 全绿。

---

## CRITICAL 修复

| # | 问题 | 修复 |
|---|------|------|
| #7 | 命令超时只 kill 主进程,孤儿子进程继续运行 | `run_with_timeout()` 用 `process_group(0)` + `killpg(SIGKILL)` 杀整个进程组 |
| #16 | HTTP server 无认证,任意本机进程可读写任务/记忆 | 可选访问令牌认证(Bearer / Cookie / `?token=`),`None` 向后兼容 |
| #20 | 运行时白名单只匹配 basename,批准 `src/main.rs` 会覆盖 `tests/main.rs` | 改用完整规范化相对路径匹配,杜绝同名文件越权 |
| #23 | CORS 设为 `*`,任意网站可跨域读取 API | 移除 `cors()` 与所有 `Access-Control-Allow-Origin` 响应头 |

## HIGH 修复

| # | 问题 | 修复 |
|---|------|------|
| #17 | Unix socket 默认 umask,同机其他用户可连入 | bind 后 `set_permissions(0o600)` |
| #22 | 审批 action_id 用时间戳+计数器,可推算伪造 | 改用 `uuid::Uuid::new_v4()`(CSPRNG) |
| #26 | IPC TCP 后端无认证,任意进程可注入伪造触发/审批 | TCP 共享密钥握手 `AUTH <secret>\n` + `constant_time_eq` |
| #24 | Feishu adapter 三个 Map 只增不减 → OOM | 新增 `TTLMap`(TTL 1h + LRU maxSize 5000)替换 |
| #27 | API 错误响应 `{"error":"{e}"}` 泄露内部细节 | 改返回 `{"error":"internal_error","correlation_id":"<uuid v4>"}` |

---

## 设计原则

- **向后兼容 Option 模式**:#16(auth token)、#26(tcp secret)均用 `Option<String>`,
`None` 保留旧行为,未配置时打警告,不破坏现有部署/CI。
- **纵深防御**:Unix socket 用文件系统权限(#17)+ TCP 用共享密钥(#26),两条 IPC 路径都加锁。
- **fail-closed**:审批/白名单/认证任一环节失败都返回拒绝,不放行。
- **每个修复带回归测试**:新增测试覆盖修复点,保留全部既有测试。

---

## 验证

```
cargo test --workspace --features orcha-core/llm
orcha-core 223 passed
orcha-gateway 67 passed
orcha-llm 46 passed
orcha-shell 13 passed
orcha-cli 40 passed
orcha-sdk 14 passed
全部 0 failed
```

`cargo fmt --all -- --check` · `cargo clippy --workspace --features orcha-core/llm --all-targets -- -D warnings` → exit 0
TS:`npx tsc --noEmit` 无错误

---

## 升级须知

两个新增的可选配置(生产建议启用,dev/CI 不配也能跑):

- **HTTP token**(#16):`orcha shell --token <secret>` 或 `ORCHA_SHELL_TOKEN=<secret>`
- **IPC TCP secret**(#26):`config.ipc.tcp_secret` 或 `ORCHA_IPC_TCP_SECRET=<secret>`

> 注:本次标签打在 `fix/security-high-priority` 分支(CI 已绿的 b07a683),
> 合并 PR #29 后 main 即包含全部修复。

---

**完整变更日志**:[CHANGELOG.md](CHANGELOG.md)
**PR**:https://github.com/Ink-dark/orcha/pull/29
12 changes: 8 additions & 4 deletions packages/orcha-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ enum Command {
/// HTTP 监听端口(默认 7421)。
#[arg(long, default_value_t = 7421)]
port: u16,
/// 访问令牌(#16)。设置后 Web UI/API 需 Bearer/Cookie/`?token=` 认证;
/// 不设则无认证(仅适合单用户本机)。可用环境变量 ORCHA_SHELL_TOKEN。
#[arg(long, env = "ORCHA_SHELL_TOKEN")]
token: Option<String>,
},
}

Expand Down Expand Up @@ -229,8 +233,8 @@ fn main() -> Result<()> {
let artifacts = run_artifacts(&resolve_home(cli.home.as_deref()), &id)?;
println!("{}", serde_json::to_string_pretty(&artifacts)?);
}
Some(Command::Shell { port }) => {
run_shell(&resolve_home(cli.home.as_deref()), port)?;
Some(Command::Shell { port, token }) => {
run_shell(&resolve_home(cli.home.as_deref()), port, token)?;
}
None => {
// 无子命令时打印简短帮助;clap 在 --help 时已自行处理。
Expand Down Expand Up @@ -571,11 +575,11 @@ fn run_artifacts(home: &Path, task_id: &str) -> Result<Vec<Artifact>> {
/// - 构造 [`orcha_shell::HttpServer`] 并阻塞 serve。
///
/// 阻塞运行,Ctrl-C(SIGINT)后 tiny_http 的 incoming_requests 迭代器退出。
fn run_shell(home: &Path, port: u16) -> Result<()> {
fn run_shell(home: &Path, port: u16, token: Option<String>) -> Result<()> {
FileTaskStore::new(home).init()?;
FileHistoryStore::new(home).init()?;
FileMemoryStore::new(home).init()?;
let server = orcha_shell::HttpServer::new(home, port);
let server = orcha_shell::HttpServer::new(home, port).with_auth_token(token);
server.serve()
}

Expand Down
4 changes: 4 additions & 0 deletions packages/orcha-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ llm = ["dep:orcha-llm"]
# 启用 SQLite 后端(M6,WAL + 跨进程锁,替代 FileTaskStore)
sqlite = ["dep:rusqlite"]

[target.'cfg(unix)'.dependencies]
# 仅 Unix 需要:execute_run_command 超时时用 killpg 杀整个进程组(#7)。
libc = "0.2"

[dev-dependencies]
# tempfile 同时作为 dev-dependency 以便测试中直接使用。
tempfile = "3"
Loading
Loading