Skip to content

feat(RAN-54): land OpenSSF Best Practices passing + Scorecard hardening#1

Merged
aksOps merged 1 commit intomainfrom
RAN-54-openssf-best-practices
Apr 26, 2026
Merged

feat(RAN-54): land OpenSSF Best Practices passing + Scorecard hardening#1
aksOps merged 1 commit intomainfrom
RAN-54-openssf-best-practices

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented Apr 26, 2026

Summary

Replicates the codeiq RAN-46 (B) OSS-CLI security recipe on snipIT, adapted for a single-file PowerShell 7.5+ project on .NET 9. Closes RAN-54.

PowerShell-specific delta (carried into shared/runbooks/engineering-standards.md so future PowerShell repos inherit it):

  • PSScriptAnalyzer is the language-lint slot in security.yml — codeiq's SpotBugs equivalent.
  • OSV-Scanner is intentionally omitted — snipIT has zero external runtime deps (no npm / Maven / pip lockfile to scan). Trivy filesystem scan is the SCA channel; Dependabot covers the GitHub Actions ecosystem.
  • Semgrep runs p/security-audit + p/owasp-top-ten (no p/powershell pack ships in Semgrep registry today).
  • jscpd format set to powershell, --min-tokens 100, scoped to SnipIT.ps1.

Files

New

  • .github/workflows/scorecard.ymlossf/scorecard-action@v2.4.3, push-to-main + Mondays 06:00 UTC, SARIF → Security tab. Hardened runner, all actions SHA-pinned.
  • .github/workflows/security.yml — Trivy + Semgrep + PSScriptAnalyzer + Gitleaks + jscpd + SBOM. Top-level permissions: read-all; jobs scope up only when needed.
  • .github/dependabot.ymlgithub-actions ecosystem only (sole versioned dep surface), weekly + grouped.
  • SECURITY.md — private-disclosure policy, supported versions, scope, hardening references.
  • .bestpractices.json — OpenSSF Best Practices self-assessment for project_id 12647.
  • CLAUDE.md — agent brief: layout / build / test / run / conventions / OpenSSF Scorecard baseline + target / gotchas.
  • shared/runbooks/engineering-standards.md — PowerShell variant of the company canonical runbook.
  • scripts/setup-git-signed.sh — one-shot signed-commit setup (ssh / openpgp / x509).

Modified

  • .github/workflows/test.yml — pin actions/checkout by SHA, add top-level permissions: read-all, drop the PSScriptAnalyzer job (moved to security.yml per AC).
  • README.md — OpenSSF Best Practices + Scorecard + Security workflow badges added at top.

Acceptance criteria status

  • PowerShell-specific linting added to security.yml: PSScriptAnalyzer in addition to the (B) OSS-CLI stack.
  • shared/runbooks/engineering-standards.md updated to document the PowerShell variant (PSScriptAnalyzer addition). The company canonical runbook also gets the per-language linter row updated so future PowerShell repos inherit the convention.
  • .github/workflows/scorecard.yml lands (ossf/scorecard-action, push to main + weekly cron, SARIF → Security tab) with actions pinned by SHA.
  • .github/workflows/security.yml mirroring codeiq's (B) OSS-CLI stack (Semgrep, Trivy, Gitleaks, jscpd, anchore/sbom-action), language-adapted (PSScriptAnalyzer added; OSV-Scanner omitted — no lockfiles to scan).
  • SECURITY.md at repo root.
  • OpenSSF Best Practices badge at top of README.md.
  • .bestpractices.json at repo root (project_id 12647, target = passing).
  • OpenSSF Scorecard baseline + target documented in repo CLAUDE.md (baseline pending — first scoreboard score after this PR merges; will be filled in the next PR per the table).

Out-of-band actions (handled in the next heartbeat after merge)

  • PATCH Paperclip Project snipIT codebase.repoUrl to https://github.com/RandomCodeSpace/snipIT.git.
  • Enable signed-commits branch protection on main with the new required-status-check set.
  • Enable repo-level Dependabot security updates.
  • Mark Best Practices criteria Met on https://www.bestpractices.dev/en/projects/12647 — board admin OAuth required (.bestpractices.json already reflects passing-level answers).

Out of scope (explicit per AC)

  • Functional / feature work on snipIT.
  • Migrating off the (B) OSS-CLI stack.
  • Self-hosted infra (no SonarQube self-host, no GHAS-paid CodeQL).

Test plan

  • pwsh -NoProfile -File ./Test-SnipIT.ps1 — 84/84 pass
  • Invoke-ScriptAnalyzer -Path ./SnipIT.ps1 -Severity Error — 0 errors (49 warnings, non-blocking)
  • python3 -c 'import yaml; yaml.safe_load(...)' on every workflow + dependabot — clean
  • python3 -c 'import json; json.load(...)' on .bestpractices.json — clean
  • bash -n scripts/setup-git-signed.sh — clean
  • CI: test.yml (Linux + Windows headless tests + Windows AST parse) green
  • CI: security.yml (six jobs) green
  • CI: scorecard.yml runs on first push to main and posts SARIF
  • First Scorecard score recorded into CLAUDE.md table in a follow-up PR

Follow-ups (not blocking this PR)

  • README test-count badge says tests-82/82 but the suite now has 84 tests — file a chore to update the badge in step with the suite.
  • After branch protection lands, configure required status checks: Pure-logic tests (pwsh 7.5+), Parse SnipIT.ps1 on Windows (no execution), Trivy (filesystem + container scan), Semgrep (SAST), PSScriptAnalyzer (Error severity gate), Gitleaks (secret scan), jscpd (duplication < 3% on touched code), SBOM (SPDX + CycloneDX).

🤖 Generated with Claude Code

Replicates the codeiq RAN-46 (B) OSS-CLI security recipe on snipIT, adapted for
a single-file PowerShell 7.5+ project on .NET 9. PowerShell-specific delta:
PSScriptAnalyzer added as the language-lint slot in security.yml (codeiq's
SpotBugs equivalent); OSV-Scanner omitted because snipIT has zero external
runtime deps (no npm / Maven / pip lockfile to scan).

New files
  - .github/workflows/scorecard.yml  ossf/scorecard-action v2.4.3, push to main
                                     + Mondays 06:00 UTC, SARIF -> Security tab
  - .github/workflows/security.yml   trivy / semgrep / psscriptanalyzer /
                                     gitleaks / jscpd (powershell, --min-tokens
                                     100) / SBOM (SPDX + CycloneDX). All actions
                                     SHA-pinned per Scorecard
                                     `Pinned-Dependencies`; top-level
                                     `permissions: read-all`.
  - .github/dependabot.yml          github-actions ecosystem only (the only
                                     versioned dep surface in the repo today),
                                     weekly + grouped
  - SECURITY.md                     private-disclosure policy, supported
                                     versions, scope, hardening references
  - .bestpractices.json             OpenSSF Best Practices self-assessment for
                                     project_id 12647
  - CLAUDE.md                       agent brief: layout, build/test/run,
                                     conventions, OpenSSF Scorecard baseline +
                                     target, gotchas
  - shared/runbooks/engineering-standards.md  PowerShell variant of the company
                                     canonical runbook
  - scripts/setup-git-signed.sh     one-shot signed-commit setup (ssh / openpgp /
                                     x509)

Modified
  - .github/workflows/test.yml      pin actions/checkout by SHA, add
                                     `permissions: read-all`, drop the
                                     PSScriptAnalyzer job (moved to security.yml)
  - README.md                       OpenSSF Best Practices + Scorecard +
                                     Security workflow badges added at top

Out of band (PR description tracks):
  - PATCH Paperclip Project `snipIT` codebase.repoUrl
  - Enable branch protection + Dependabot security updates on main
  - Mark Best Practices criteria `Met` on bestpractices.dev/projects/12647
    (board admin OAuth required; .bestpractices.json already passing-level).

Verified locally: yaml + json parse clean, headless tests 84/84 pass,
PSScriptAnalyzer Error gate passes (49 Warning-severity findings — non-blocking
per AC).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@aksOps aksOps merged commit 179e701 into main Apr 26, 2026
12 checks passed
@aksOps aksOps deleted the RAN-54-openssf-best-practices branch April 26, 2026 02:41
aksOps added a commit that referenced this pull request Apr 26, 2026
…schema (#3)

Strip the custom group structure (status/evidence/audit) — bestpractices.dev
autofill ignores it — and replace with the canonical flat per-criterion
key/value schema from coreinfrastructure/best-practices-badge `criteria.yml`
'0' block (passing badge): 43 MUST + 10 SHOULD + 14 SUGGESTED, each with
`<key>_status` ("Met" / "Unmet" / "N/A" / "?") and `<key>_justification`,
plus `<key>_url` for the eight criteria where upstream sets
`met_url_required: true`.

Per-criterion evidence reuses what shipped in PR #1 (RAN-54): security.yml
gates (Trivy / Semgrep / PSScriptAnalyzer / Gitleaks / jscpd / SBOM),
scorecard.yml, dependabot.yml, signed-commit branch protection,
SECURITY.md disclosure SLA, engineering-standards.md quality gates.

Honest N/A statuses on `na_allowed: true` MUSTs where the criterion does
not apply to a single-script PowerShell tool: crypto_* (project does not
use cryptography), build_* (no compile/build step — .ps1 is the
deliverable), release_notes / release_notes_vulns (no tagged release
flow yet — head-of-main delivery via `git clone`),
dynamic_analysis_fixed (no dynamic analysis tool integrated; PowerShell
on .NET is memory-safe so valgrind/ASAN-class tools do not apply).

This unblocks bestpractices.dev autofill on the project edit page for
project 12647 — board admin OAuth login still required to flip the
badge to passing.

Co-authored-by: Paperclip <noreply@paperclip.ing>
aksOps added a commit that referenced this pull request Apr 26, 2026
…ersioning evidence (#8)

CHANGELOG.md
- [Unreleased] → [v0.1.0] - 2026-04-26 with full Added / Changed / Fixed / Security
  subsections covering PR #1 (RAN-54 baseline + Scorecard hardening), PR #3 (RAN-59
  canonical-schema rewrite), PRs #4/#5 (RAN-64 CHANGELOG + docs/ index), PR #6
  (5 SUGGESTED criteria flips), PR #7 (CONTRIBUTING.md + conventional-URL retargets).
- Fresh empty [Unreleased] section opened at top per Keep-a-Changelog 1.1.0.
- Link refs now point at compare/v0.1.0...HEAD and releases/tag/v0.1.0.

.bestpractices.json
- version_unique_url + release_notes_vulns_url added (both pointing at the v0.1.0
  GitHub Release) so the bestpractices.dev autofill bot has a concrete URL to
  verify alongside _status: Met.
- 5 versioning justifications refreshed to cite the concrete v0.1.0 tag instead of
  forward-looking commitments: version_unique, version_semver, version_tags,
  release_notes, release_notes_vulns. These are the criteria the autofill bot
  verifies by checking actual GitHub Releases / git tags exist.

Once the v0.1.0 signed tag + GitHub Release land post-merge, autofill should flip
release_notes to Met (currently Unmet pending evidence) and the 4 SUGGESTED
versioning criteria stay Met with concrete tag-backed URLs.

Co-authored-by: Paperclip <noreply@paperclip.ing>
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.

1 participant