fix(ci): StepSecurity hardening + CodeRabbit corrections (supersedes #106)#108
fix(ci): StepSecurity hardening + CodeRabbit corrections (supersedes #106)#108Steffen025 merged 2 commits intomainfrom
Conversation
Applies the StepSecurity security improvements from PR #106 and fixes all 6 CodeRabbit findings on top. StepSecurity changes (from PR #106 by StepSecurity Bot): - dependabot.yml: daily automated dependency updates for GitHub Actions and all npm workspaces in the repo - ci.yml / code-quality.yml: pinned actions to SHA, added harden-runner - codeql.yml: new CodeQL SAST workflow (JavaScript/TypeScript + Python) - dependency-review.yml: new dependency vulnerability scan on every PR - opencode.yml: pinned anomalyco/opencode/github to SHA, harden-runner - scorecards.yml: new OpenSSF Scorecard workflow for supply-chain scoring - upstream-sync-*.yml: pinned github-script to SHA, harden-runner - upstream-sync-pai.yml: added top-level permissions: contents: read - .pre-commit-config.yaml: pre-commit hooks for detect-secrets, end-of-file-fixer, trailing-whitespace, check-yaml, check-json, check-merge-conflict CodeRabbit corrections (6 findings, all valid): 1. codeql.yml line 38: replaced ['javascript', 'python', 'typescript'] with ['javascript-typescript', 'python'] — CodeQL requires the combined identifier 'javascript-typescript' for JS/TS; separate entries are invalid and would cause the analyze step to error. 2. opencode.yml line 40: updated comment from '# latest' to '# pinned to 77fc88c8' to accurately describe that the action is pinned to a specific commit SHA, not a mutable 'latest' tag. 3. upstream-sync-opencode.yml: added workflow-level permissions block (contents: read, issues: write) before the jobs section. The workflow calls actions/github-script to read releases and create issues but had no top-level permissions block, risking default overly-broad GITHUB_TOKEN scopes. 4. upstream-sync-pai.yml job permissions: the job-level block only had issues: write, causing actions/checkout to lack repository read access. Added contents: read alongside issues: write. 5. ci.yml: added top-level permissions: contents: read before jobs to prevent the CI job from inheriting the default write-all token scope. 6. code-quality.yml: added top-level permissions: contents: read before jobs for the same reason as ci.yml (Biome check doesn't need write access). Credit: StepSecurity Bot opened PR #106 (app.stepsecurity.io) at the request of @Steffen025. Coderabbit findings applied on top.
📝 WalkthroughWalkthroughThis pull request introduces security hardening and automation infrastructure across the GitHub Actions workflows and local development environment. It adds Dependabot configuration for automated dependency updates, establishes pre-commit hooks for local code quality, deploys new security scanning workflows (CodeQL, dependency review, and supply-chain scorecard), and hardens existing workflows by restricting permissions, adding egress policy auditing, and pinning action versions to specific commits. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/upstream-sync-opencode.yml (1)
39-44:⚠️ Potential issue | 🟠 MajorAdd
persist-credentials: falseto the checkout step.This workflow only performs read-only operations (fetch, log checks, and API reads) with no git pushes. Disabling credential persistence reduces the token exposure window since it's not needed after the initial checkout.
Suggested patch
- name: Checkout fork uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: repository: ${{ env.FORK_REPO }} token: ${{ secrets.UPSTREAM_SYNC_TOKEN }} fetch-depth: 0 + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/upstream-sync-opencode.yml around lines 39 - 44, The checkout step named "Checkout fork" currently uses actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with a token and fetch-depth; add persist-credentials: false under the with block for that step to prevent the checked-out token from being persisted in the workspace (update the step referencing actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 accordingly).
🧹 Nitpick comments (1)
.github/workflows/scorecards.yml (1)
17-18: Narrow default token scope instead ofread-all.Line 18 sets a broad default permission baseline. Since this workflow has a single job with explicit permissions, prefer a minimal top-level default like
contents: read(or omit top-level defaults and rely only on job-level permissions) to keep least-privilege intent crisp.Suggested change
-# Declare default permissions as read only. -permissions: read-all +# Declare minimal default permissions. +permissions: + contents: read🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/scorecards.yml around lines 17 - 18, The top-level workflow permission "permissions: read-all" is overly broad; update the default scope to follow least-privilege by replacing "permissions: read-all" with a narrower default such as "permissions: contents: read" or remove the top-level "permissions" entry entirely and rely on the explicit job-level "permissions" already defined in the workflow; modify the single declaration "permissions: read-all" accordingly so the workflow no longer grants full read access by default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 32-35: The CI step named "Setup Bun" currently sets bun-version:
latest which makes builds non-deterministic; update the action step that uses
oven-sh/setup-bun (the "Setup Bun" step) to set a specific bun-version (for
example "1.1.0" or a minor range like "1.1.x") instead of "latest", and apply
the same change to the corresponding "Setup Bun" step in
.github/workflows/code-quality.yml so both CI workflows pin Bun to a fixed
release.
In @.github/workflows/code-quality.yml:
- Around line 26-30: Replace the non-reproducible bun-version: latest with an
explicit pinned version string for the oven-sh/setup-bun action; update the
bun-version field (and any other occurrences of bun-version: latest) to a
specific release (e.g., "2.2.0" or the exact tag/sha used in the uses line) so
the setup step uses a fixed Bun release instead of latest.
In @.pre-commit-config.yaml:
- Around line 14-22: Add the baseline pre-commit checks to
.pre-commit-config.yaml so malformed YAML/JSON and merge conflict markers are
caught: in the existing pre-commit-hooks repo block (the one listing
end-of-file-fixer and trailing-whitespace) add hooks with id: check-yaml,
check-json, and check-merge-conflict (keep the existing end-of-file-fixer and
trailing-whitespace entries), and ensure the pylint repo block (id: pylint)
remains unchanged; this will register the missing baseline guards.
---
Outside diff comments:
In @.github/workflows/upstream-sync-opencode.yml:
- Around line 39-44: The checkout step named "Checkout fork" currently uses
actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with a token and
fetch-depth; add persist-credentials: false under the with block for that step
to prevent the checked-out token from being persisted in the workspace (update
the step referencing actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
accordingly).
---
Nitpick comments:
In @.github/workflows/scorecards.yml:
- Around line 17-18: The top-level workflow permission "permissions: read-all"
is overly broad; update the default scope to follow least-privilege by replacing
"permissions: read-all" with a narrower default such as "permissions: contents:
read" or remove the top-level "permissions" entry entirely and rely on the
explicit job-level "permissions" already defined in the workflow; modify the
single declaration "permissions: read-all" accordingly so the workflow no longer
grants full read access by default.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6761bf2e-f028-4af0-9091-4439bcf72bc3
📒 Files selected for processing (10)
.github/dependabot.yml.github/workflows/ci.yml.github/workflows/code-quality.yml.github/workflows/codeql.yml.github/workflows/dependency-review.yml.github/workflows/opencode.yml.github/workflows/scorecards.yml.github/workflows/upstream-sync-opencode.yml.github/workflows/upstream-sync-pai.yml.pre-commit-config.yaml
| - name: Setup Bun | ||
| uses: oven-sh/setup-bun@v2 | ||
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | ||
| with: | ||
| bun-version: latest | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Workflow Bun settings:"
rg -nP 'bun-version:\s*' .github/workflows/code-quality.yml .github/workflows/ci.yml
echo
echo "Declared packageManager versions (if present):"
fd -a package.json | xargs -I{} sh -c 'printf "%s -> " "{}"; jq -r ".packageManager // \"<missing>\"" "{}"'Repository: Steffen025/pai-opencode
Length of output: 308
Pin Bun to an explicit version instead of latest.
bun-version: latest makes runs non-reproducible and can introduce sudden CI failures. This issue appears in both .github/workflows/code-quality.yml (line 29) and .github/workflows/ci.yml (line 35).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/code-quality.yml around lines 26 - 30, Replace the
non-reproducible bun-version: latest with an explicit pinned version string for
the oven-sh/setup-bun action; update the bun-version field (and any other
occurrences of bun-version: latest) to a specific release (e.g., "2.2.0" or the
exact tag/sha used in the uses line) so the setup step uses a fixed Bun release
instead of latest.
…eleases
CodeRabbit round 2 fixes (5 findings, all valid):
1. ci.yml + code-quality.yml: pin bun-version from 'latest' to '1.x'
to prevent non-deterministic builds if Bun 2.x ships a breaking
change. '1.x' resolves to the latest 1.x patch (currently 1.3.10),
giving reproducibility without requiring manual version bumps on
every Bun patch release.
2. .pre-commit-config.yaml: add check-yaml, check-json,
check-merge-conflict hooks to the existing pre-commit-hooks block.
These baseline guards catch malformed config files and accidental
merge conflict markers before they reach CI.
3. upstream-sync-opencode.yml: add persist-credentials: false to the
'Checkout fork' step. Prevents the checked-out UPSTREAM_SYNC_TOKEN
from being persisted in the workspace after checkout, reducing the
token's blast radius if a subsequent step is compromised.
4. scorecards.yml: narrow top-level permissions from 'read-all' to
'permissions: contents: read'. The job-level block already grants
the specific scopes the Scorecard analysis job actually needs
(security-events: write, id-token: write, etc.). The broad
'read-all' at workflow level was unnecessary and over-privileged.
Release automation — release-please (ships alongside this PR):
Three files added to enable automated GitHub Releases + CHANGELOG
updates using Google's release-please-action v4:
- release-please-config.json: release-type 'node' (updates package.json
version on each release), changelog-path CHANGELOG.md, minor/patch
bumping enabled pre-1.0.
- .release-please-manifest.json: baseline version {'.' : '3.0.0'} so
the first automated release will be v3.0.x or higher — not v1.0.0.
- .github/workflows/release-please.yml: triggers on push to main,
creates/updates a 'Release PR' that accumulates all conventional
commits. Merging the PR creates the GitHub Release, updates
CHANGELOG.md, and bumps package.json. No Node.js setup step needed
(pure GitHub Action).
Conventional commit → SemVer mapping (no changes needed to commit style):
feat(scope): → minor bump (v3.x.0 → v3.(x+1).0)
fix(scope): → patch bump (v3.0.x → v3.0.(x+1))
feat!: / BREAKING CHANGE: → major bump (v3.x.0 → v4.0.0)
chore: / docs: / refactor: → no release PR
Also:
- package.json version: 2.0.0 → 3.0.0 (aligned with manifest baseline)
- CHANGELOG.md: [3.0.0] - Unreleased → [3.0.0] - 2026-04-12 (ready to
ship; release-please will own CHANGELOG formatting from v3.0.1 onward)
Summary
Applies the StepSecurity security hardening from PR #106 (by @step-security-bot) with all CodeRabbit corrections applied on top — plus release-please for automated v3.0+ releases.
Closes
What PR #106 added (StepSecurity Bot)
.github/dependabot.yml.github/workflows/ci.ymlactions/checkout+oven-sh/setup-bunto SHA; addedstep-security/harden-runner.github/workflows/code-quality.yml.github/workflows/codeql.yml.github/workflows/dependency-review.yml.github/workflows/opencode.ymlpermissions: contents: read; harden-runner.github/workflows/scorecards.yml.github/workflows/upstream-sync-*.ymlactions/github-script+actions/checkoutto SHA; harden-runner.pre-commit-config.yamlCodeRabbit Round 1 corrections (6 findings)
codeql.yml—["javascript", "python", "typescript"]→["javascript-typescript", "python"]opencode.yml— comment# latest→# pinned to 77fc88c8on the pinned SHAupstream-sync-opencode.yml— added workflow-levelpermissions: contents: read+issues: writeupstream-sync-pai.yml— addedcontents: readto job permissions alongsideissues: writeci.yml— added top-levelpermissions: contents: readcode-quality.yml— added top-levelpermissions: contents: readCodeRabbit Round 2 corrections (5 findings, commit
ac6bceb)ci.yml+code-quality.yml—bun-version: latest→bun-version: "1.x"to pin to a stable major and prevent non-deterministic builds if Bun 2.x introduces breaking changes.pre-commit-config.yaml— addedcheck-yaml,check-json,check-merge-conflicthooks to the existingpre-commit-hooksblockupstream-sync-opencode.yml— addedpersist-credentials: falseto the Checkout fork step to prevent theUPSTREAM_SYNC_TOKENfrom being persisted in the workspacescorecards.yml— narrowed top-levelpermissions: read-alltopermissions: contents: read(job-level block grants all the specific scopes actually needed)scorecards.ymlnitpick — applied as well for least-privilege hygieneRelease automation — release-please (new, same commit)
Three files added to automate GitHub Releases and CHANGELOG updates using release-please-action v4:
release-please-config.jsonrelease-type: node,changelog-path: CHANGELOG.md.release-please-manifest.json{"." : "3.0.0"}— next automated release will be ≥ v3.0.1.github/workflows/release-please.ymlHow it works from here:
Conventional commit → SemVer mapping (no changes to current commit style needed):
feat(scope): ...fix(scope): ...feat!:orBREAKING CHANGE:footerchore:/docs:/refactor:Also:
package.jsonversion bumped2.0.0→3.0.0(aligned with manifest baseline), andCHANGELOG.md[3.0.0] - Unreleased→[3.0.0] - 2026-04-12(ready to ship; release-please will own CHANGELOG formatting from v3.0.1 onward).After merge: Ship v3.0.0
Since the manifest baseline is
3.0.0, after this PR merges:gh release create v3.0.0 --title "PAI-OpenCode v3.0.0" --notes-file <(sed -n '/## \[3.0.0\]/,/## \[2.0.0\]/p' CHANGELOG.md | sed '$d')feat:orfix:pushed to main automatically accumulates in a Release PR — merge it when you're ready to ship the next version.