security: pin GitHub Actions, add gitleaks CI, harden permissions (v0.4.2) (#23)
* security: pin GitHub Actions to commit SHAs, add gitleaks CI - Pin all 5 actions (checkout, setup-bun, upload-artifact, download-artifact, action-gh-release) to commit SHAs across 3 workflow files - Add permissions: contents: read to test.yml and e2e.yml - Add gitleaks secret scanning job to test.yml - Pin openclaw install to v2026.4.9 in e2e.yml Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: add .gitleaks.toml config Allowlists test fixtures, example env files, and skill documentation to prevent false positives from the gitleaks CI step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add GitHub Actions SHA maintenance rule to CLAUDE.md Instructs /ship and /review to check for stale SHA pins and update them, keeping action versions fresh without manual effort. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add S3 Sig V4 TODO from CSO audit Deferred from security audit. S3 storage backend accepts credentials but sends unsigned requests. Implement when S3 becomes a real deployment path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.4.2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
13
.github/workflows/e2e.yml
vendored
13
.github/workflows/e2e.yml
vendored
@@ -9,6 +9,9 @@ on:
|
||||
- cron: '0 6 * * *' # Nightly at 6am UTC
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
tier1:
|
||||
name: Tier 1 (Mechanical)
|
||||
@@ -28,8 +31,8 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- run: bun install
|
||||
@@ -58,13 +61,13 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- run: bun install
|
||||
- name: Install OpenClaw
|
||||
run: npm install -g openclaw
|
||||
run: npm install -g openclaw@2026.4.9
|
||||
- name: Configure OpenClaw MCP
|
||||
run: |
|
||||
mkdir -p ~/.openclaw
|
||||
|
||||
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -20,14 +20,14 @@ jobs:
|
||||
artifact: gbrain-linux-x64
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- run: bun install
|
||||
- run: bun test
|
||||
- run: bun build --compile --target=${{ matrix.target }} --outfile bin/${{ matrix.artifact }} src/cli.ts
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: ${{ matrix.artifact }}
|
||||
path: bin/${{ matrix.artifact }}
|
||||
@@ -36,11 +36,11 @@ jobs:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
path: artifacts
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
|
||||
with:
|
||||
files: |
|
||||
artifacts/gbrain-darwin-arm64/gbrain-darwin-arm64
|
||||
|
||||
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
@@ -6,12 +6,25 @@ on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
gitleaks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: gitleaks/gitleaks-action@dcedce43c6f43de0b836d1fe38946645c9c638dc # v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- run: bun install
|
||||
|
||||
11
.gitleaks.toml
Normal file
11
.gitleaks.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
title = "GBrain gitleaks config"
|
||||
|
||||
[allowlist]
|
||||
paths = [
|
||||
'''.env\.testing\.example''',
|
||||
'''.env\.example''',
|
||||
'''test/''',
|
||||
'''skills/''',
|
||||
'''.claude/skills/''',
|
||||
'''GBRAIN_SKILLPACK\.md''',
|
||||
]
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -2,6 +2,21 @@
|
||||
|
||||
All notable changes to GBrain will be documented in this file.
|
||||
|
||||
## [0.4.2] - 2026-04-10
|
||||
|
||||
### Changed
|
||||
|
||||
- All GitHub Actions pinned to commit SHAs across test, e2e, and release workflows. Prevents supply chain attacks via mutable version tags.
|
||||
- Workflow permissions hardened: `contents: read` on test and e2e workflows limits GITHUB_TOKEN blast radius.
|
||||
- OpenClaw CI install pinned to v2026.4.9 instead of pulling latest.
|
||||
|
||||
### Added
|
||||
|
||||
- Gitleaks secret scanning CI job runs on every push and PR. Catches accidentally committed API keys, tokens, and credentials.
|
||||
- `.gitleaks.toml` config with allowlists for test fixtures and example files.
|
||||
- GitHub Actions SHA maintenance rule in CLAUDE.md so pins stay fresh on every `/ship` and `/review`.
|
||||
- S3 Sig V4 TODO for future implementation when S3 storage becomes a deployment path.
|
||||
|
||||
## [0.4.1] - 2026-04-09
|
||||
|
||||
### Added
|
||||
|
||||
14
CLAUDE.md
14
CLAUDE.md
@@ -118,6 +118,20 @@ reads this during upgrades to suggest new schema additions without re-suggesting
|
||||
things the user already declined. The setup skill writes the initial state during
|
||||
Phase C/E. Never modify a user's custom directories or re-suggest declined ones.
|
||||
|
||||
## GitHub Actions SHA maintenance
|
||||
|
||||
All GitHub Actions in `.github/workflows/` are pinned to commit SHAs. Before shipping
|
||||
(`/ship`) or reviewing (`/review`), check for stale pins and update them:
|
||||
|
||||
```bash
|
||||
for action in actions/checkout oven-sh/setup-bun actions/upload-artifact actions/download-artifact softprops/action-gh-release gitleaks/gitleaks-action; do
|
||||
tag=$(grep -r "$action@" .github/workflows/ | head -1 | grep -o '#.*' | tr -d '# ')
|
||||
[ -n "$tag" ] && echo "$action@$tag: $(gh api repos/$action/git/ref/tags/$tag --jq .object.sha 2>/dev/null)"
|
||||
done
|
||||
```
|
||||
|
||||
If any SHA differs from what's in the workflow files, update the pin and version comment.
|
||||
|
||||
## Skill routing
|
||||
|
||||
When the user's request matches an available skill, ALWAYS invoke it using the Skill
|
||||
|
||||
15
TODOS.md
15
TODOS.md
@@ -16,3 +16,18 @@
|
||||
**Implementation sketch:** `src/core/embedding-queue.ts` with a Promise-based semaphore. Workers `await queue.submit(chunks)` which resolves when the queue has room. Queue flushes to OpenAI in batches of 100 with max 2-3 concurrent API calls. Track source file per chunk for error propagation.
|
||||
|
||||
**Depends on:** Part 5 (parallel import with per-worker engines) -- already shipped.
|
||||
|
||||
## P2
|
||||
|
||||
### Implement AWS Signature V4 for S3 storage backend
|
||||
**What:** Replace the unsigned `signedFetch()` in `src/core/storage/s3.ts` with proper AWS Signature V4 request signing.
|
||||
|
||||
**Why:** The current S3 implementation accepts `accessKeyId` and `secretAccessKey` but never signs requests. It only works with public buckets or pre-signed URLs. Private S3 buckets return 403.
|
||||
|
||||
**Pros:** Enables private S3/R2/MinIO bucket support. Users can store files securely without relying on public bucket access.
|
||||
|
||||
**Cons:** AWS Sig V4 is complex (canonical request, string to sign, signing key derivation). Could use a lightweight library instead of rolling from scratch. Medium implementation effort.
|
||||
|
||||
**Context:** Identified during CSO security audit (2026-04-10). The code explicitly comments this as "simplified" and not production-ready. Nobody uses S3 storage today (Supabase Storage is the default). Only implement when S3 becomes a real deployment path.
|
||||
|
||||
**Depends on:** Nothing. Self-contained change to `src/core/storage/s3.ts`.
|
||||
|
||||
Reference in New Issue
Block a user