Skip to content

fix: address OpenSSF Scorecard findings#22

Merged
don-petry merged 3 commits intomainfrom
scorecard-fixes
Mar 28, 2026
Merged

fix: address OpenSSF Scorecard findings#22
don-petry merged 3 commits intomainfrom
scorecard-fixes

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Mar 27, 2026

Summary

Closes #18, #19, #20, #21

Test plan

  • Verify CI passes on this PR
  • Verify CodeQL runs on push to main
  • Verify no workflow permission errors
  • Re-run OpenSSF Scorecard to confirm improved scores

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added a security policy describing supported versions, private vulnerability reporting, required report details, and response timelines (48‑hour ack, 5 business days assessment, 30 days for fixes).
  • Chores

    • Tightened CI workflow permission defaults and restored explicit job-level permissions where required.
    • Pinned third‑party actions to specific revisions for more reproducible workflows.
    • Adjusted an action input key used for an AI/code helper integration.

- Add SECURITY.md (#18)
- Scope workflow token permissions to read-all with per-job overrides (#19)
- Pin all GitHub Action dependencies to commit SHAs (#20)
- Ensure SAST (CodeQL) runs on all push commits to main (#21)

Closes #18, #19, #20, #21

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 27, 2026 20:44
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5e7a3924-3f0b-4ff6-9e39-92be96de61b3

📥 Commits

Reviewing files that changed from the base of the PR and between 73a4c22 and ccb56fa.

📒 Files selected for processing (1)
  • .github/workflows/claude.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/claude.yml

📝 Walkthrough

Walkthrough

Top-level GitHub Actions workflow permissions were set to empty (permissions: {}) across workflows with job-level permissions restored where required; several workflow action references were pinned to specific commit SHAs; and a new SECURITY.md was added defining vulnerability reporting and response timelines.

Changes

Cohort / File(s) Summary
Workflows — claude
.github/workflows/claude.yml
Added top-level permissions: {}; renamed Claude action input from anthropic_api_keyclaude_code_oauth_token; job-level permissions unchanged.
Workflows — codeql
.github/workflows/codeql-analysis.yml
Added top-level permissions: {}; pinned actions/checkout@v4 and github/codeql-action/*@v3 steps to commit SHAs; retained analyze job-level permissions.
Workflows — dependabot
.github/workflows/dependabot-automerge.yml
Replaced workflow-level permissions with permissions: {} and reintroduced job-scoped permissions for dependabot; pinned dependabot/fetch-metadata and actions/create-github-app-token to commit SHAs.
Workflows — sonarcloud
.github/workflows/sonarcloud.yml
Set workflow-level permissions: {} and added job-level permissions for the sonarcloud job (contents: read, pull-requests: read).
Security policy
SECURITY.md
Added project security policy with reporting channels (email and private GitHub reports), required report contents, supported versions, and response timeline targets (48h ack, 5 business days assessment, 30 days to fix).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Changes to Claude workflow action input naming (anthropic_api_key → claude_code_oauth_token) appear unrelated to OpenSSF Scorecard findings or the linked issue #18 about security policy. Explain the rationale for the Claude workflow input change or move it to a separate PR focused on that specific fix.
Linked Issues check ❓ Inconclusive The PR addresses issue #18 by adding a SECURITY.md file; however, the raw_summary and PR description mention addressing issues #19, #20, and #21, but only issue #18 is provided in the linked_issues section for validation. Confirm that workflow permission scoping, action pinning, and SAST enablement changes (related to issues #19-#21) align with their stated requirements, or clarify which issues are in scope for this PR.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: address OpenSSF Scorecard findings' accurately summarizes the main objective of the PR, which is to implement fixes for OpenSSF Scorecard findings related to security policies, workflow permissions, action pinning, and SAST enablement.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch scorecard-fixes

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

Comment thread .github/workflows/claude.yml Fixed
Comment thread .github/workflows/codeql-analysis.yml Fixed
Comment thread .github/workflows/dependabot-automerge.yml Fixed
Comment thread .github/workflows/sonarcloud.yml Fixed
Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (6)
SECURITY.md (2)

5-8: Make the support matrix explicit instead of using latest.

Using latest is ambiguous for security response scope. Prefer explicit major/minor ranges (and optionally EOL dates) so reporters know what is in-support.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SECURITY.md` around lines 5 - 8, Replace the ambiguous "latest" entry in the
security support matrix table in SECURITY.md with explicit version identifiers
and ranges (e.g., "1.4 - 2.x" or "2.0 (EOL 2026-12-31)") and/or EOL dates so the
"Version | Supported" row clearly enumerates supported major/minor versions and
their support status; update the table row that currently reads "| latest |
:white_check_mark: |" to one or more rows that list concrete version ranges or
specific versions and corresponding support indicators.

26-28: Good SLA targets; consider “target” wording for complex cases.

The timelines are clear. Optional tweak: phrase as targets (with status updates when timelines slip) to avoid over-committing on high-complexity incidents.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SECURITY.md` around lines 26 - 28, Update the three SLA bullets that
currently state firm deadlines ("We will acknowledge receipt of your report
within 48 hours.", "We will provide an initial assessment within 5 business
days.", "We aim to release a fix within 30 days of confirming the
vulnerability.") to describe them as targets (e.g., prefix or rephrase with
"Target:" or "We aim to... and will provide status updates if timelines slip")
and add a short clause indicating that for complex incidents the team will
provide regular status updates if targets cannot be met; ensure the edited lines
preserve the same timeline values but use the word "target" and include a note
about status updates.
.github/workflows/sonarcloud.yml (1)

9-10: Use zero default permissions at workflow scope.

Line 9 uses read-all, which is broader than needed. With explicit job permissions already present, set workflow default to {}.

Suggested change
-permissions: read-all
+permissions: {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/sonarcloud.yml around lines 9 - 10, The workflow's global
permissions are too broad: replace the top-level "permissions: read-all" setting
with an empty permissions object "{}" so the default workflow scope is
zero-permissions while leaving your existing explicit job-level permissions
intact; locate the "permissions: read-all" entry in the sonarcloud.yml workflow
and change it to "permissions: {}" to enforce least privilege.
.github/workflows/claude.yml (1)

12-12: Tighten default workflow token permissions.

Line 12 sets a broad default (read-all). Since this workflow already grants explicit job permissions, switch the workflow default to none to prevent future jobs from inheriting unintended scopes.

Suggested change
-permissions: read-all
+permissions: {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 12, The workflow default permission is
set to the overly-broad value "permissions: read-all"; change the top-level
default to "permissions: none" so jobs do not inherit unintended scopes, while
keeping any explicit job- or step-level permissions intact (update the
occurrence of permissions: read-all to permissions: none and verify existing
explicit job permissions remain as intended).
.github/workflows/codeql-analysis.yml (1)

13-14: Reduce workflow-level permission blast radius.

Line 13 introduces read-all; with explicit job-level permissions already in place, defaulting to {} is safer and keeps least-privilege stricter for future jobs.

Suggested change
-permissions: read-all
+permissions: {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/codeql-analysis.yml around lines 13 - 14, The workflow
sets a broad workflow-level permission ("permissions: read-all") which increases
blast radius; change it to the least privileged default by removing or replacing
that top-level "permissions: read-all" with an empty permissions object
("permissions: {}") and rely on the existing explicit job-level permissions,
ensuring no job inherits unnecessary read-all privileges.
.github/workflows/dependabot-automerge.yml (1)

8-8: Avoid broad workflow defaults for GITHUB_TOKEN.

Line 8 sets read-all globally. Since the dependabot job already declares the required write scopes, prefer a zero default at workflow level.

Suggested change
-permissions: read-all
+permissions: {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dependabot-automerge.yml at line 8, The workflow currently
sets a broad default for GITHUB_TOKEN with "permissions: read-all"; change the
workflow-level permission to a zero default (e.g., "permissions: none") and rely
on the existing explicit permissions declared on the dependabot job so only the
job gets the write scopes it needs; update/remove the "permissions: read-all"
entry and verify the dependabot job still declares its required write
permissions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@SECURITY.md`:
- Line 15: Replace the ambiguous phrase "send an email to the repository
maintainers" in SECURITY.md with a concrete contact address or link (for example
a dedicated mailbox like security@yourdomain.tld or a link to contact
instructions), and optionally include instructions for encrypted reports (PGP
key fingerprint) and expected response time so reporters have a guaranteed,
secure reporting path; update the sentence that currently reads "Instead, please
send an email to the repository maintainers or use [GitHub's private
vulnerability reporting]..." to reference the explicit contact address or link
and any encryption guidance.

---

Nitpick comments:
In @.github/workflows/claude.yml:
- Line 12: The workflow default permission is set to the overly-broad value
"permissions: read-all"; change the top-level default to "permissions: none" so
jobs do not inherit unintended scopes, while keeping any explicit job- or
step-level permissions intact (update the occurrence of permissions: read-all to
permissions: none and verify existing explicit job permissions remain as
intended).

In @.github/workflows/codeql-analysis.yml:
- Around line 13-14: The workflow sets a broad workflow-level permission
("permissions: read-all") which increases blast radius; change it to the least
privileged default by removing or replacing that top-level "permissions:
read-all" with an empty permissions object ("permissions: {}") and rely on the
existing explicit job-level permissions, ensuring no job inherits unnecessary
read-all privileges.

In @.github/workflows/dependabot-automerge.yml:
- Line 8: The workflow currently sets a broad default for GITHUB_TOKEN with
"permissions: read-all"; change the workflow-level permission to a zero default
(e.g., "permissions: none") and rely on the existing explicit permissions
declared on the dependabot job so only the job gets the write scopes it needs;
update/remove the "permissions: read-all" entry and verify the dependabot job
still declares its required write permissions.

In @.github/workflows/sonarcloud.yml:
- Around line 9-10: The workflow's global permissions are too broad: replace the
top-level "permissions: read-all" setting with an empty permissions object "{}"
so the default workflow scope is zero-permissions while leaving your existing
explicit job-level permissions intact; locate the "permissions: read-all" entry
in the sonarcloud.yml workflow and change it to "permissions: {}" to enforce
least privilege.

In `@SECURITY.md`:
- Around line 5-8: Replace the ambiguous "latest" entry in the security support
matrix table in SECURITY.md with explicit version identifiers and ranges (e.g.,
"1.4 - 2.x" or "2.0 (EOL 2026-12-31)") and/or EOL dates so the "Version |
Supported" row clearly enumerates supported major/minor versions and their
support status; update the table row that currently reads "| latest |
:white_check_mark: |" to one or more rows that list concrete version ranges or
specific versions and corresponding support indicators.
- Around line 26-28: Update the three SLA bullets that currently state firm
deadlines ("We will acknowledge receipt of your report within 48 hours.", "We
will provide an initial assessment within 5 business days.", "We aim to release
a fix within 30 days of confirming the vulnerability.") to describe them as
targets (e.g., prefix or rephrase with "Target:" or "We aim to... and will
provide status updates if timelines slip") and add a short clause indicating
that for complex incidents the team will provide regular status updates if
targets cannot be met; ensure the edited lines preserve the same timeline values
but use the word "target" and include a note about status updates.
🪄 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: f0f1de7c-a7a4-4d8f-8f80-5b1f6d7cdca1

📥 Commits

Reviewing files that changed from the base of the PR and between 1184c97 and 68e147f.

📒 Files selected for processing (5)
  • .github/workflows/claude.yml
  • .github/workflows/codeql-analysis.yml
  • .github/workflows/dependabot-automerge.yml
  • .github/workflows/sonarcloud.yml
  • SECURITY.md

Comment thread SECURITY.md Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the repository’s security posture in response to OpenSSF Scorecard findings by adding a security policy and tightening GitHub Actions configurations (token permissions, dependency pinning, and SAST coverage).

Changes:

  • Add SECURITY.md to document a vulnerability reporting policy.
  • Restrict GitHub Actions workflow/job token permissions using workflow defaults plus per-job overrides.
  • Pin GitHub Actions dependencies to specific commit SHAs and ensure CodeQL runs on push to main.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
SECURITY.md Introduces a security policy and vulnerability reporting guidance.
.github/workflows/sonarcloud.yml Moves to workflow-level permissions defaults + job-level least-privilege; pins actions.
.github/workflows/dependabot-automerge.yml Adds workflow/job permission scoping; pins actions used by the workflow.
.github/workflows/codeql-analysis.yml Ensures CodeQL runs on push to main, scopes permissions, and pins actions.
.github/workflows/claude.yml Adds workflow-level permissions default and keeps explicit job-level permissions; pins action.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/codeql-analysis.yml
Comment thread .github/workflows/dependabot-automerge.yml
- Replace permissions: read-all with permissions: {} (deny-by-default)
- Add concrete security contact email to SECURITY.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
SECURITY.md (1)

5-8: Clarify supported-version scope beyond latest.

Using only latest is a bit ambiguous during triage. Consider listing concrete supported release lines (or main/release branches) so reporters can clearly determine support status.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SECURITY.md` around lines 5 - 8, Update the SECURITY.md supported-versions
table to replace the ambiguous "latest" entry with explicit supported release
lines or branches (for example "main", "v1.x", "v2.x" or specific supported
tags) and clearly mark each as supported or EOL; edit the table row that
currently shows "| latest | :white_check_mark: |" to list the concrete
branches/tags and their support status so reporters can unambiguously determine
whether their version is supported.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@SECURITY.md`:
- Around line 5-8: Update the SECURITY.md supported-versions table to replace
the ambiguous "latest" entry with explicit supported release lines or branches
(for example "main", "v1.x", "v2.x" or specific supported tags) and clearly mark
each as supported or EOL; edit the table row that currently shows "| latest |
:white_check_mark: |" to list the concrete branches/tags and their support
status so reporters can unambiguously determine whether their version is
supported.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f72d4435-d239-4efe-b18a-939ef8d57302

📥 Commits

Reviewing files that changed from the base of the PR and between 68e147f and 73a4c22.

📒 Files selected for processing (5)
  • .github/workflows/claude.yml
  • .github/workflows/codeql-analysis.yml
  • .github/workflows/dependabot-automerge.yml
  • .github/workflows/sonarcloud.yml
  • SECURITY.md
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/sonarcloud.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/claude.yml
  • .github/workflows/dependabot-automerge.yml

The action has separate inputs for API keys vs OAuth tokens.
CLAUDE_CODE_OAUTH_TOKEN is an OAuth token, not an API key.
@sonarqubecloud
Copy link
Copy Markdown

@don-petry don-petry merged commit dc68091 into main Mar 28, 2026
13 of 14 checks passed
@don-petry don-petry deleted the scorecard-fixes branch March 28, 2026 13:30
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.

Scorecard: Security-Policy (0/10)

3 participants