Skip to content

Commit bce5f30

Browse files
feat(security): OpenSSF Best Practices + Scorecard scaffolding (RAN-55, RAN-60) (#1)
* checkpoint: pre-yolo 2026-04-20T09:09:19 * feat(security): land OpenSSF Best Practices + Scorecard scaffolding (RAN-55) Adapt the codeiq RAN-46/RAN-52 recipe to vigil's PowerShell + WPF tree: - Add CLAUDE.md (architecture, conventions, OpenSSF observability target) - Add SECURITY.md (private disclosure, scope, hardening references) - Add AGENTS.md (agent collaborator entry-point) - Add .bestpractices.json (project_id 12648, level: passing, evidence map) - Add .github/workflows/scorecard.yml (push to main + Mondays 06:00 UTC, SHA-pinned actions, SARIF + artifact) - Add .github/workflows/security.yml — (B) OSS-CLI stack: Semgrep / OSV-Scanner / Trivy / Gitleaks / jscpd / Syft SBOM, language-adapted (PowerShell tokenization for jscpd, no Maven/npm bits) - Add .github/dependabot.yml (github-actions only — vigil has no language lockfile) - README.md: add OpenSSF Best Practices + Scorecard badges - LICENSE: align copyright with project precedent (Amit Kumar) Per board ruling: Scorecard is observational only (stretch >= 8.0/10); the OpenSSF Best Practices `passing` badge is the only hard gate. Final flip from `in_progress` to `passing` on bestpractices.dev is admin-UI work and stays board-owned. Board action items (cannot land via workflow file): - Enable signed-commit branch protection on main - Enable secret scanning + push protection - Enable Dependabot security updates - Flip bestpractices.dev project 12648 from in_progress to passing Closes RAN-55 (after the board-side toggles + bestpractices.dev flip). Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(ci): replace broken google/osv-scanner-action with binary install The pinned `google/osv-scanner-action@c5185470…` (v2.3.5) ships an `action.yml` that is composite-only and missing the top-level `runs:` section, so GitHub rejects it as a job step with: Top level 'runs:' section is required for google/osv-scanner-action/.../action.yml Codeiq hit the same trap on its RAN-52 follow-up and switched to installing the official `osv-scanner` binary via `gh release download`. Mirroring that pattern here, adapted for vigil: - env: OSV_SCANNER_VERSION=2.3.5, GH_TOKEN=github.token - gh release download `osv-scanner_linux_amd64` from `google/osv-scanner` v2.3.5 (pattern match → mv to stable name) - Smoke `./osv-scanner --version` so future regressions surface clearly instead of exit 127 - Recursive source scan (`--recursive --skip-git ./`); vigil has no language lockfile today, so the run exits with no findings. Coverage activates automatically once a `*.lock` lands in-tree. Co-Authored-By: Paperclip <noreply@paperclip.ing> * chore(bestpractices): rewrite to canonical autofill schema (RAN-60) Replace custom group structure (status / evidence / audit blocks) with bestpractices.dev's canonical flat per-criterion schema so the autofill robot pre-fills the criteria page on board flip. All 67 passing-level criteria (43 MUST, 10 SHOULD, 14 SUGGESTED) carry _status, _justification, and (where required by upstream criteria.yml) _url. Status distribution: 62 Met, 4 N/A (release_notes / release_notes_vulns / version_semver / version_tags — vigil ships no formal release line), 1 Unmet (test_continuous_integration — Test-Vigil.ps1 not yet wired into GHA), 2 ? (dynamic_analysis, dynamic_analysis_enable_assertions). Schema source: criteria/criteria.yml top-level '0:' block on coreinfrastructure/best-practices-badge. Companion to RAN-57 (codeiq), RAN-58 (otelcontext), RAN-59 (snipIT). Co-Authored-By: Paperclip <noreply@paperclip.ing> --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
1 parent 45f3acb commit bce5f30

9 files changed

Lines changed: 971 additions & 1 deletion

File tree

.bestpractices.json

Lines changed: 219 additions & 0 deletions
Large diffs are not rendered by default.

.github/dependabot.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Dependabot configuration for vigil.
2+
# Docs: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3+
#
4+
# Vigil ships no language-ecosystem dependency surface — it is a single-file
5+
# PowerShell + WPF app with no `package-lock.json`, no `pom.xml`, no
6+
# `requirements.txt`. The only thing Dependabot can usefully bump on this
7+
# repo is the GitHub Actions in `.github/workflows/`.
8+
#
9+
# Strategy:
10+
# * weekly cadence — keeps the noise floor low while still catching CVEs early
11+
# * grouped — single PR per week unless a security update fires
12+
# * security updates fire whenever needed regardless of the weekly slot
13+
#
14+
# RAN-55 — paired with `.github/workflows/security.yml` (OSS-CLI stack) and
15+
# `.github/workflows/scorecard.yml` (OpenSSF Scorecard). Repo-level
16+
# "Dependabot security updates" + "secret scanning" + "push protection"
17+
# are board-owned toggles in repo Settings.
18+
19+
version: 2
20+
updates:
21+
- package-ecosystem: "github-actions"
22+
directory: "/"
23+
schedule:
24+
interval: "weekly"
25+
day: "monday"
26+
time: "08:00"
27+
timezone: "Etc/UTC"
28+
open-pull-requests-limit: 5
29+
labels:
30+
- "type:dependencies"
31+
- "area:ci"
32+
commit-message:
33+
prefix: "chore(actions)"
34+
include: "scope"
35+
groups:
36+
actions:
37+
patterns:
38+
- "*"

.github/workflows/scorecard.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# OpenSSF Scorecard supply-chain analysis.
2+
# RAN-55 — best-effort target. Scorecard is observational and does NOT gate
3+
# merge per the board ruling; the OpenSSF Best Practices `passing` badge is
4+
# the only hard gate.
5+
# Docs: https://github.com/ossf/scorecard-action
6+
7+
name: Scorecard supply-chain security
8+
9+
on:
10+
push:
11+
branches: [main]
12+
schedule:
13+
# Mondays 06:00 UTC — same window as security.yml so the weekly
14+
# observability sweep runs together.
15+
- cron: "0 6 * * 1"
16+
workflow_dispatch:
17+
18+
# Restrict the default GITHUB_TOKEN to read-only; the steps below request the
19+
# narrow scopes they actually need.
20+
permissions: read-all
21+
22+
jobs:
23+
analysis:
24+
name: Scorecard analysis
25+
runs-on: ubuntu-latest
26+
permissions:
27+
# Required for upload to the code-scanning Security tab.
28+
security-events: write
29+
# Required to read OIDC token for publish_results.
30+
id-token: write
31+
# Default scopes for actions/checkout.
32+
contents: read
33+
actions: read
34+
35+
steps:
36+
- name: Harden runner egress
37+
# step-security/harden-runner v2.19.0
38+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40
39+
with:
40+
egress-policy: audit
41+
42+
- name: Checkout code
43+
# actions/checkout v6.0.2
44+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
45+
with:
46+
persist-credentials: false
47+
48+
- name: Run Scorecard analysis
49+
# ossf/scorecard-action v2.4.3
50+
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a
51+
with:
52+
results_file: results.sarif
53+
results_format: sarif
54+
# Publish the results so they appear on the public Scorecard dashboard.
55+
publish_results: true
56+
57+
- name: Upload Scorecard SARIF (artifact)
58+
# actions/upload-artifact v7.0.1
59+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
60+
with:
61+
name: scorecard-sarif
62+
path: results.sarif
63+
retention-days: 5
64+
65+
- name: Upload SARIF to GitHub code-scanning
66+
# github/codeql-action/upload-sarif v3.35.2
67+
uses: github/codeql-action/upload-sarif@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a
68+
with:
69+
sarif_file: results.sarif

0 commit comments

Comments
 (0)