Skip to content

fix(ci): StepSecurity hardening + CodeRabbit corrections (supersedes #106)#108

Merged
Steffen025 merged 2 commits intomainfrom
fix/pr-106-stepsecurity-coderabbit
Apr 12, 2026
Merged

fix(ci): StepSecurity hardening + CodeRabbit corrections (supersedes #106)#108
Steffen025 merged 2 commits intomainfrom
fix/pr-106-stepsecurity-coderabbit

Conversation

@Steffen025
Copy link
Copy Markdown
Owner

@Steffen025 Steffen025 commented Apr 12, 2026

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)

File Change
.github/dependabot.yml Daily automated dependency updates for GitHub Actions + all npm workspaces
.github/workflows/ci.yml Pinned actions/checkout + oven-sh/setup-bun to SHA; added step-security/harden-runner
.github/workflows/code-quality.yml Same as ci.yml
.github/workflows/codeql.yml New — CodeQL SAST workflow for JS/TS + Python
.github/workflows/dependency-review.yml New — Dependency vulnerability scan on every PR
.github/workflows/opencode.yml Pinned actions to SHA; permissions: contents: read; harden-runner
.github/workflows/scorecards.yml New — OpenSSF Scorecard supply-chain security workflow
.github/workflows/upstream-sync-*.yml Pinned actions/github-script + actions/checkout to SHA; harden-runner
.pre-commit-config.yaml New — Pre-commit hooks: gitleaks, shellcheck, eslint, end-of-file-fixer, trailing-whitespace, pylint

CodeRabbit Round 1 corrections (6 findings)

  1. codeql.yml["javascript", "python", "typescript"]["javascript-typescript", "python"]
  2. opencode.yml — comment # latest# pinned to 77fc88c8 on the pinned SHA
  3. upstream-sync-opencode.yml — added workflow-level permissions: contents: read + issues: write
  4. upstream-sync-pai.yml — added contents: read to job permissions alongside issues: write
  5. ci.yml — added top-level permissions: contents: read
  6. code-quality.yml — added top-level permissions: contents: read

CodeRabbit Round 2 corrections (5 findings, commit ac6bceb)

  1. ci.yml + code-quality.ymlbun-version: latestbun-version: "1.x" to pin to a stable major and prevent non-deterministic builds if Bun 2.x introduces breaking changes
  2. .pre-commit-config.yaml — added check-yaml, check-json, check-merge-conflict hooks to the existing pre-commit-hooks block
  3. upstream-sync-opencode.yml — added persist-credentials: false to the Checkout fork step to prevent the UPSTREAM_SYNC_TOKEN from being persisted in the workspace
  4. scorecards.yml — narrowed top-level permissions: read-all to permissions: contents: read (job-level block grants all the specific scopes actually needed)
  5. scorecards.yml nitpick — applied as well for least-privilege hygiene

Release automation — release-please (new, same commit)

Three files added to automate GitHub Releases and CHANGELOG updates using release-please-action v4:

File Purpose
release-please-config.json release-type: node, changelog-path: CHANGELOG.md
.release-please-manifest.json Baseline {"." : "3.0.0"} — next automated release will be ≥ v3.0.1
.github/workflows/release-please.yml Triggers on push to main; creates Release PR accumulating conventional commits

How it works from here:

feat(scope): commit pushed to main
       │
       ▼
release-please creates/updates a "Release PR: v3.1.0"
with CHANGELOG preview + package.json bump
       │
       ▼
You merge when ready → GitHub Release created automatically
  • Git tag (v3.1.0)
  • CHANGELOG.md updated
  • package.json version bumped

Conventional commit → SemVer mapping (no changes to current commit style needed):

Commit Bump
feat(scope): ... minor (v3.0.0 → v3.1.0)
fix(scope): ... patch (v3.0.0 → v3.0.1)
feat!: or BREAKING CHANGE: footer major (v3.0.0 → v4.0.0)
chore: / docs: / refactor: no Release PR

Also: package.json version bumped 2.0.03.0.0 (aligned with manifest baseline), and 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).

After merge: Ship v3.0.0

Since the manifest baseline is 3.0.0, after this PR merges:

  1. Tag v3.0.0 manually: 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')
  2. From now on, every feat: or fix: pushed to main automatically accumulates in a Release PR — merge it when you're ready to ship the next version.

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.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 12, 2026

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Workflow Security Hardening
.github/workflows/ci.yml, .github/workflows/code-quality.yml, .github/workflows/opencode.yml, .github/workflows/upstream-sync-opencode.yml, .github/workflows/upstream-sync-pai.yml
Added top-level permissions: contents: read blocks, inserted step-security/harden-runner steps with egress-policy: audit, and pinned action versions (actions/checkout@v4, oven-sh/setup-bun@v2, actions/github-script@v7) to specific commit SHAs instead of version tags.
New Security Workflows
.github/workflows/codeql.yml, .github/workflows/dependency-review.yml, .github/workflows/scorecards.yml
Introduced three new GitHub Actions workflows: CodeQL for language-specific SAST (JavaScript/TypeScript and Python), dependency-review for scanning vulnerable dependencies in PRs, and ossf/scorecard for supply-chain security auditing with SARIF results publishing.
Dependency & Git Management
.github/dependabot.yml, .pre-commit-config.yaml
Added Dependabot configuration with daily schedule for GitHub Actions and npm packages across root and subdirectories; added pre-commit hooks (gitleaks, shellcheck, eslint, trailing-whitespace, end-of-file-fixer, pylint) to automate local code quality checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A security rabbit hops through the code,
With hardened workflows on GitHub's abode,
CodeQL scans and Scorecards unite,
Pre-commit hooks catch bugs in the night,
Dependencies dance in Dependabot's sway,
More secure than ever, hip-hip-hooray! 🔐

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: StepSecurity hardening and CodeRabbit corrections across CI/workflow files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pr-106-stepsecurity-coderabbit

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-advanced-security
Copy link
Copy Markdown

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:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🟠 Major

Add persist-credentials: false to 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 of read-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

📥 Commits

Reviewing files that changed from the base of the PR and between 6f1eab3 and ab12ccd.

📒 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

Comment thread .github/workflows/ci.yml Outdated
Comment on lines 26 to 30
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: latest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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.

Comment thread .pre-commit-config.yaml
…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)
@Steffen025 Steffen025 merged commit f15c2d6 into main Apr 12, 2026
7 checks passed
@Steffen025 Steffen025 deleted the fix/pr-106-stepsecurity-coderabbit branch April 12, 2026 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants