From ad8545377472480da7f23760901acebbff2cc41e Mon Sep 17 00:00:00 2001 From: secbolt/crew/goldwasser Date: Sat, 12 Sep 2026 20:20:13 -0700 Subject: [PATCH] release: v0.10.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unblocks rf-f5is. #250 merged to a PUBLIC main on 2026-09-11 and the registries have served 0.10.3 ever since — a fix disclosed and not shipped, for an EXTERNALLY reported finding. Cutting the disclosure line from the PR body did not undo the disclosure: merging to a public repo publishes a diff naming exactly which key shapes were undetected and at what lengths. CONTENTS 6839663 #250 rf-f5is OpenAI + Supabase rules in the regex engine 14eb1c6 #246 rf-3n1i command_policy.allowed_patterns in python, under the policy floor, plus two allowlist bypasses closed SCOPE OF THE BUMP — four files, found by searching for the current version rather than by trusting the validator's list, because #238 exists precisely because a partial bump PASSED validation once: node/package.json python/pyproject.toml node/resources/rafter-security-skill.md (gated ClawHub manifest) python/rafter_cli/resources/rafter-security-skill.md (gated ClawHub manifest) DELIBERATELY NOT BUMPED. The repo carries six other SKILL.md files with their own frontmatter versions — rafter-code-review at 0.7.0, rafter-secure-design, rafter-skill-review and rafter at 0.1.0/0.7.0. Those are independently versioned skill resources, not package-version mirrors; moving them to 0.10.4 would be wrong, and "every manifest" does not mean every file with a version. The two that ARE package mirrors are the two validate-release gates. VERIFIED by running validate-release's own checks locally rather than trusting the edit: node and python versions match at 0.10.4, and both gated skill manifests match the package version. Plus the check validate-release does NOT do and which is the one that actually bites — 0.10.4 is not already on the registry. main's version equalling the published version is what made the last two gaps unpublishable: validation passes and the publish job fails later, at the registry, with an error that does not say "you forgot the bump". Does not push prod. PR #251 (main -> prod) is open and is Rome's to merge. --- CHANGELOG.md | 10 ++++++++++ node/package.json | 2 +- node/resources/rafter-security-skill.md | 2 +- python/pyproject.toml | 2 +- python/rafter_cli/resources/rafter-security-skill.md | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e9f465..68c0177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.10.4] - 2026-09-12 + +### Security + +- **OpenAI and Supabase keys are detected by the hook's Write gate** (rf-f5is; external report se-wagv). The Write gate is regex-only and `secret-patterns` carried **no OpenAI rule at all**, so `sk-proj-`, `sk-svcacct-`, `sk-admin-` and legacy `sk-…T3BlbkFJ…` keys were allowed straight through at any length — while `rafter secrets` caught them via betterleaks. Two engines disagreeing, and the one guarding writes was the blind one. `sb_secret_` (Supabase) was caught by neither, at any length. Three rules added to both runtimes, matched case-sensitively in line with the other prefixed vendor tokens (`ghp_`, `AKIA`, `AIza`, `xox`); lower-casing them would add false positives and catch nothing real. Verified against the published 0.10.3 artifact before the fix, with controls, so the miss was evidence rather than an empty result. + +- **`command_policy.allowed_patterns` works in Python, and cannot be granted by a project** (rf-3n1i). The key was documented in `shared-docs/CLI_SPEC.md` and implemented in Node only — for every Python user it parsed to nothing and enforced nothing, which is worse than an absent key because the operator believes the allowlist is on. Implementing it exposed a second problem: an allowlist is a **grant**, so unlike `blocked_patterns` and `require_approval` — which are unioned, because contributing to them can only add restriction — a project `.rafter.yml` must not contribute to it. Otherwise a cloned repo shipping `allowed_patterns: [".*"]` waves through every non-critical command, defeating the policy floor. The owner's list stands; a project's is refused unless `allowProjectOverride` is set. + +- **Two allowlist bypasses closed** (rf-3n1i). A newline was not treated as a statement separator by the allowlist's chain check, so with `^git push origin feature/` allowlisted a second line ran unclassified; the check now asks the tokenizer, which has treated a newline as a separator since rf-6pqx, rather than keeping a second narrower definition. And a scalar-string `allowedPatterns` was iterated **character by character**, so a leading `^` matched every command and the allowlist allowed everything — the shape `rafter agent config set` actually writes. Guarded at the validator and at the consumer, in both runtimes. + ## [0.10.3] - 2026-09-11 ### Security diff --git a/node/package.json b/node/package.json index c0e84ca..03fe643 100644 --- a/node/package.json +++ b/node/package.json @@ -1,6 +1,6 @@ { "name": "@rafter-security/cli", - "version": "0.10.3", + "version": "0.10.4", "type": "module", "repository": { "type": "git", diff --git a/node/resources/rafter-security-skill.md b/node/resources/rafter-security-skill.md index 1a3e579..87f879c 100644 --- a/node/resources/rafter-security-skill.md +++ b/node/resources/rafter-security-skill.md @@ -1,7 +1,7 @@ --- name: rafter-security description: Security toolkit for AI workflows. Use when scanning code or repos for vulnerabilities, auditing third-party skills/MCPs/agent configs before installing, evaluating shell commands before running them, or generating secure design questions for new features. Provides `rafter run` (remote SAST + SCA, needs RAFTER_API_KEY), `rafter secrets` (offline secrets-only), `rafter agent exec --dry-run` (command-risk classification), and `rafter skill review`. -version: 0.10.3 +version: 0.10.4 homepage: https://rafter.so metadata: openclaw: diff --git a/python/pyproject.toml b/python/pyproject.toml index 041bbd1..77d2e7d 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "rafter-cli" -version = "0.10.3" +version = "0.10.4" description = "Rafter CLI — the default security agent for AI workflows. Free for individuals and open source." authors = ["Rafter Team "] license = "MIT" diff --git a/python/rafter_cli/resources/rafter-security-skill.md b/python/rafter_cli/resources/rafter-security-skill.md index 1a3e579..87f879c 100644 --- a/python/rafter_cli/resources/rafter-security-skill.md +++ b/python/rafter_cli/resources/rafter-security-skill.md @@ -1,7 +1,7 @@ --- name: rafter-security description: Security toolkit for AI workflows. Use when scanning code or repos for vulnerabilities, auditing third-party skills/MCPs/agent configs before installing, evaluating shell commands before running them, or generating secure design questions for new features. Provides `rafter run` (remote SAST + SCA, needs RAFTER_API_KEY), `rafter secrets` (offline secrets-only), `rafter agent exec --dry-run` (command-risk classification), and `rafter skill review`. -version: 0.10.3 +version: 0.10.4 homepage: https://rafter.so metadata: openclaw: