Skip to content

Every change passes a security scan before it lands - #5

Open
DeyangChan wants to merge 1 commit into
mainfrom
ci/security-scans
Open

Every change passes a security scan before it lands#5
DeyangChan wants to merge 1 commit into
mainfrom
ci/security-scans

Conversation

@DeyangChan

Copy link
Copy Markdown
Contributor

What this changes

Installing this plugin runs its code on a stranger's machine, so the pipeline now proves more than that the tests pass.

.github/workflows/security.yml adds four scans, on every pull request, on every push to main, and weekly:

Scan Tool What it enforces
Static analysis CodeQL, security-and-quality Injection, path traversal, unsafe DOM construction in the servers and the pages
Secret scan Gitleaks No credential in any commit, read over the full history rather than the working tree
Workflow audit zizmor Token permissions, credential persistence, untrusted input reaching a run block
Code quality SonarQube Cloud Bugs, security hotspots, and maintainability on new code

A Security gates job depends on all four and fails unless each one reports success, so a skipped or cancelled scan blocks a merge the same way a failing one does.

.github/workflows/scorecard.yml runs OpenSSF Scorecard weekly and on main, and publishes the score the README badge reads.

Supply chain:

  • Every action across all four workflows is pinned by commit SHA with its version in a trailing comment. A tag moves; a moved tag runs code nobody reviewed.
  • .github/dependabot.yml moves those pins weekly, after a seven-day cooldown so a freshly compromised release is not picked up on publication day.
  • The one unpinned install, the Claude Code CLI used to validate the manifests, carries a zizmor: ignore with the reason beside it: that job has to run the validator a marketplace reviewer would run today.

Documentation follows the existing split. SECURITY.md owns what each gate enforces and the pinning rule. CONTRIBUTING.md says how to run two of the scans locally. CLAUDE.md and the pull request checklist reference them.

The SonarQube job skips itself where SONAR_TOKEN is not set, which is the case until the project is imported on SonarQube Cloud, and on every pull request from a fork. Its badges are held out of the README until then.

How it was tested

No skill or plugin asset changed, so there was nothing to drive end to end. What was run locally:

  • gitleaks git --no-banner --redact --verbose — 85 commits scanned, no leaks.
  • uvx zizmor@1.29.0 .github/workflows/ .github/dependabot.yml, offline and with online audits — no findings. Both findings from the first run were addressed rather than silenced, apart from the documented ad-hoc install.
  • The three test suites and build-shell.mjs check — all pass.
  • Every badge URL, for its current response.

Checklist

  • Installed the plugin from this branch and drove the affected skill end to end. — n/a, no skill or asset changed
  • Nothing writes outside the user's project, and nothing transmits anywhere, unless that is the skill's stated purpose.
  • Per-machine state resolves through lib/workdir.mjs and lands under .vstack/local/<tool>/.
  • Pages stay self-contained. No external requests at runtime.
  • Edited lib/shell/ rather than a stamped region — n/a, no page changed
  • Added or renamed a plugin — n/a
  • Renamed a tool — n/a
  • Every security scan passes, and no finding was silenced instead of fixed.
  • Added a step that uses an action, and pinned it by commit SHA with the version in a trailing comment.

🤖 Generated with Claude Code

Installing this plugin runs its code on a stranger's machine, so the pipeline
now proves more than that the tests pass.

- CodeQL, Gitleaks over the full history, and a zizmor audit of the workflows
  themselves run on every pull request, on main, and weekly. A gates job fails
  unless all of them report success, so a skipped scan blocks a merge too.
- A SonarQube Cloud scan runs where SONAR_TOKEN is set, and reports a skip
  rather than failing where it is not.
- OpenSSF Scorecard runs weekly on main and publishes the score the README
  badge reads.
- Every action is pinned by commit SHA with its version in a trailing comment,
  and Dependabot moves the pins weekly after a seven-day cooldown.

SECURITY.md owns what each gate enforces; CONTRIBUTING.md and the pull request
checklist say what a contributor has to do about it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@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.

@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment thread .github/workflows/ci.yml
# reviewer would run today, and there is no lockfile to pin it against.
- name: Install Claude Code
run: npm install --global @anthropic-ai/claude-code
run: npm install --global @anthropic-ai/claude-code # zizmor: ignore[adhoc-packages]
Comment thread .github/workflows/ci.yml
# reviewer would run today, and there is no lockfile to pin it against.
- name: Install Claude Code
run: npm install --global @anthropic-ai/claude-code
run: npm install --global @anthropic-ai/claude-code # zizmor: ignore[adhoc-packages]
set -euo pipefail
cd "$RUNNER_TEMP"
release="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}"
curl -fsSL -O "${release}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
cd "$RUNNER_TEMP"
release="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}"
curl -fsSL -O "${release}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
curl -fsSL -O "${release}/gitleaks_${GITLEAKS_VERSION}_checksums.txt"
- cron: '23 5 * * 1'

permissions:
contents: read
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