From 6f38bd6034e76bfd62798b0598f8f18466a854d7 Mon Sep 17 00:00:00 2001 From: thestreamcode Date: Sat, 1 Aug 2026 21:57:56 +0200 Subject: [PATCH 1/2] docs: record CodeQL triage and repository contract Add a static-analysis triage section to the security review covering the 309 open CodeQL alerts. All four critical `hard-coded-cryptographic-value` hits are `#[cfg(test)]` nonce fixtures; the cleartext-transmission hits on the retained upstream backend, feedback, and session-registry clients are unreachable because `REMOTE_SESSION_REGISTRY` forces `StorageMode::Local` and the product policy constants gate the remaining handlers. No alert is dismissed, so a later true positive stays visible. Document the pinned Rust/Node toolchain, the single supported package manager, the artifacts the project produces, the protected assets and generated files, and the repository-visibility rules in AGENTS.md. Co-Authored-By: Claude Opus 5 (1M context) --- AGENTS.md | 41 +++++++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 10 ++++++++++ docs/security-review.md | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 850fbe7..4f6b4b7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,32 @@ The root `Cargo.toml` is generated and read-only. Change the owning crate manifest or generator source. Keep retained `xai-*` crate names stable unless there is an explicit migration or upstream-sync reason. +## Toolchain and package manager + +- Rust is pinned by `rust-toolchain.toml` (currently `1.94.1`, with `rustfmt` + and `clippy`). Do not bypass the pin with an ad-hoc `+toolchain` override. +- Node.js `>=18` is the supported floor (`package.json` `engines`); CI and the + release workflow run Node 22. +- `npm` is the only package manager for the launcher. Do not add a second + package manager or a second lockfile. `Cargo.lock` is committed and every + Cargo command in the gate below uses `--locked`. +- The primary artifact is the Rust binary `chutes-build`. The npm package is a + thin launcher that resolves a prebuilt native binary from one of six + platform-specific optional dependencies; it never compiles Rust and must not + gain an install or post-install lifecycle script. +- One version string covers the npm launcher, all six native packages, and the + lockstepped Cargo manifests. `npm run verify:release` is the authority. + +## Assets and generated files + +- `assets/chutes/screenshot/chutes-build.png` is the README screenshot. Do not + replace, recolor, resize, or re-encode it. +- `docs/ascii-logo-concepts.html` and `docs/chutes-build-promo.html` are design + sources, not runtime dependencies. +- The root `Cargo.toml`, `Cargo.lock`, `THIRD-PARTY-NOTICES`, and `SOURCE_REV` + are generated or inherited. Regenerate them through their owning process + rather than hand-editing. + ## Working rules - Inspect the current worktree before editing. Preserve unrelated local work. @@ -45,6 +71,21 @@ there is an explicit migration or upstream-sync reason. - Avoid destructive Git operations. Do not publish, tag, release, or push without explicit authorization. +## Repository visibility + +This repository is public and Apache-2.0 licensed, and the npm packages it +produces are public. Treat every commit as immediately world-readable: + +- `main` is protected, requires the five CI checks, and forbids force pushes + and non-linear history. Never rewrite published history. +- Nothing reaches npm from ordinary CI. Publication happens only through a + manual `Package release` dispatch with `publish` enabled, gated by the + `npm-release` environment. Follow `docs/releasing.md` in order. +- Documentation, error messages, and commit messages must not name internal + hosts, private endpoints, or unreleased capabilities. +- Never widen the repository's visibility, permissions, or Actions token scope + as a side effect of another change. + ## Upstream changes - Fetch and review `upstream/main`; never merge it wholesale. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f306d0..28c1177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Documentation + +- Recorded the CodeQL static-analysis triage in the security review: current + alert counts, the disposition of each query, and the reachability argument + showing the retained upstream backend client cannot run while + `REMOTE_SESSION_REGISTRY` is `false`. +- Documented the pinned Rust/Node toolchain, the single supported package + manager, the artifacts the project actually produces, the protected assets + and generated files, and the repository-visibility rules in `AGENTS.md`. + ## [0.4.2] - 2026-08-01 ### Added diff --git a/docs/security-review.md b/docs/security-review.md index b01d591..fbba814 100644 --- a/docs/security-review.md +++ b/docs/security-review.md @@ -99,6 +99,45 @@ font stacks, plus a build-only Quick XML version used by Wayland protocol generation. These exceptions remain visible in CI and must be revisited during dependency or upstream synchronization. +## Static analysis triage + +CodeQL default setup reports 309 open alerts against the workspace as of +2026-08-01: 287 `rust/cleartext-logging`, 17 `rust/cleartext-transmission`, +4 `rust/hard-coded-cryptographic-value`, and 1 +`rust/uncontrolled-allocation-size`. None is dismissed, so a later true positive +in the same query stays visible. The categories below record why the current +set does not describe a reachable defect. + +- `rust/hard-coded-cryptographic-value` (reported critical) matches literal + `"nonce123"` and `TEST_NONCE` fixtures. All four sit in test-only code: the + `#[cfg(test)] mod tests` block of `auth/oidc/protocol.rs` and the + `#[cfg(test)]`-gated `auth/oidc/test_helpers.rs`. The shipped authorize flow + derives its nonce at runtime. +- `rust/cleartext-logging` is dominated by pager dispatch test modules and by + CLI/session code that prints or traces a local session identifier. Session + identifiers are local correlation values, not credentials, and the shared + log/trace sanitizer already redacts real secret shapes. +- `rust/cleartext-transmission` flags `reqwest` calls whose URL or body carries + a session identifier. The Chutes-owned clients in `chutes-build-core` + construct their endpoints through `validate_endpoint_url`, which rejects + non-HTTPS schemes and untrusted hosts, and resolve DNS through + `SsrfSafeResolver`. The remaining hits are on the retained upstream backend, + feedback, and session-registry clients, which are unreachable in this + product: `REMOTE_SESSION_REGISTRY` is `false`, so agent initialization forces + `StorageMode::Local` and the only caller that computes `needs_remote` always + resolves it to `false`; `REMOTE_FEEDBACK` and `REMOTE_SESSION_SHARING` gate + their handlers to `method_not_found`. +- `rust/uncontrolled-allocation-size` is `ptyctl`'s scrollback reader reserving + `count.min(history_size())` lines, bounded by the terminal's own buffer. + +`chutes-build serve` deliberately prints its generated server key to the +operator's stderr so the WebSocket URL can be copied. That is interactive +startup output, not persisted logging. + +Re-triage this list whenever the CodeQL query pack, the flagged files, or the +product policy constants change. A new alert outside these categories is a +release blocker until it is analysed. + ## Residual trust boundaries Chutes Build intentionally executes commands, modifies files, invokes hosted From 6345ee2b99d8e42a1b409b317a1cf54852a6e262 Mon Sep 17 00:00:00 2001 From: thestreamcode Date: Sat, 1 Aug 2026 23:58:05 +0200 Subject: [PATCH 2/2] ci: refresh checkout and secret scan fixtures --- .github/workflows/ci.yml | 10 +++++----- .github/workflows/package-release.yml | 8 ++++---- .github/workflows/upstream-watch.yml | 2 +- CHANGELOG.md | 11 +++++++++++ crates/chutes-build-core/src/privacy.rs | 4 ++-- .../src/implementations/chutes/context7.rs | 2 +- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32a9baf..dfa8cab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: timeout-minutes: 15 steps: - name: Check out full history - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false @@ -69,7 +69,7 @@ jobs: timeout-minutes: 60 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Restore Cargo cache @@ -112,7 +112,7 @@ jobs: timeout-minutes: 10 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Node.js @@ -133,7 +133,7 @@ jobs: timeout-minutes: 90 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Restore Cargo cache @@ -164,7 +164,7 @@ jobs: timeout-minutes: 60 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Restore Cargo cache diff --git a/.github/workflows/package-release.yml b/.github/workflows/package-release.yml index 73a6d5f..0b167fb 100644 --- a/.github/workflows/package-release.yml +++ b/.github/workflows/package-release.yml @@ -23,7 +23,7 @@ jobs: timeout-minutes: 10 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Node.js @@ -71,7 +71,7 @@ jobs: package: chutes-build-win32-arm64 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Node.js @@ -119,7 +119,7 @@ jobs: timeout-minutes: 10 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Node.js @@ -168,7 +168,7 @@ jobs: id-token: write steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Node.js diff --git a/.github/workflows/upstream-watch.yml b/.github/workflows/upstream-watch.yml index d53299a..5cdb632 100644 --- a/.github/workflows/upstream-watch.yml +++ b/.github/workflows/upstream-watch.yml @@ -20,7 +20,7 @@ jobs: timeout-minutes: 10 steps: - name: Check out repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Compare reviewed and current upstream state diff --git a/CHANGELOG.md b/CHANGELOG.md index 28c1177..bdfb3cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed + +- Updated the pinned `actions/checkout` workflow dependency to `v7.0.1`, + including its Git argument escaping and pull-request safety fixes. + +### Security + +- Marked the three synthetic secret-detection fixtures explicitly so both + worktree and full-history Gitleaks scans pass without weakening real-secret + detection. + ### Documentation - Recorded the CodeQL static-analysis triage in the security review: current diff --git a/crates/chutes-build-core/src/privacy.rs b/crates/chutes-build-core/src/privacy.rs index a8db2fd..1af17ce 100644 --- a/crates/chutes-build-core/src/privacy.rs +++ b/crates/chutes-build-core/src/privacy.rs @@ -61,9 +61,9 @@ mod tests { #[test] fn catches_secret_shapes_the_local_markers_alone_would_miss() { for (line, label) in [ - ("aws AKIAABCDEFGHIJKLMNOP", "aws access key"), + ("aws AKIAABCDEFGHIJKLMNOP", "aws access key"), // gitleaks:allow ( - "token ghp_0123456789abcdefghijABCDEFGHIJ012345", + "token ghp_0123456789abcdefghijABCDEFGHIJ012345", // gitleaks:allow "github pat", ), ( diff --git a/crates/codegen/xai-grok-tools/src/implementations/chutes/context7.rs b/crates/codegen/xai-grok-tools/src/implementations/chutes/context7.rs index cc07269..aba0f30 100644 --- a/crates/codegen/xai-grok-tools/src/implementations/chutes/context7.rs +++ b/crates/codegen/xai-grok-tools/src/implementations/chutes/context7.rs @@ -206,7 +206,7 @@ mod tests { assert!( reject_sensitive( "tokio", - "see aws AKIAABCDEFGHIJKLMNOP for setup", + "see aws AKIAABCDEFGHIJKLMNOP for setup", // gitleaks:allow "context7_search" ) .is_err()