Skip to content

score

Compute a single posture score (0–100, letter grade A–F) for a repository’s GitHub Actions configuration. Implements the public scoring rubric — every point deducted maps to a named rule, so the grade can be re-derived by hand from the finding list.

Terminal window
pinprick score
pinprick score /path/to/repo
pinprick score --json
pinprick score --html > report.html
  • Scans .github/workflows/*.yml and emits findings across four categories: pin.*, workflow.*, source.*, runtime.*
  • Each finding has a fixed point deduction; the score is max(0, 100 - sum(points))
  • Exits 1 when any findings exist (matches audit for CI gating)
  • Runs fully offline by default. source.archived and source.advisory activate only when a GitHub token is available
  • Default: a compact human-readable summary with grade, finding counts by severity, and top remediations
  • --json: the full finding list as JSON for CI integration or downstream processing
  • --html: a self-contained HTML report (mutually exclusive with --json)

The full catalog lives in docs/scoring.md. Summary:

CategoryRuleSeverityPoints
pinpin.branch (branch ref)high15
pinpin.sliding (sliding tag @v4)medium5
pinpin.full_tag (e.g. @v4.2.1)low2
sourcesource.archivedhigh10
sourcesource.advisory (GHSA match)high15
sourcesource.unverified (untrusted org)low1
runtimeruntime.pipe_to_shellhigh20
runtimeruntime.fetch.highhigh15
runtimeruntime.fetch.mediummedium8
runtimeruntime.fetch.lowlow3
workflowworkflow.permissions_write_allhigh10
workflowworkflow.pull_request_targethigh5
workflowworkflow.workflow_runmedium3

Grade bands: A 90–100, B 80–89, C 70–79, D 60–69, F 0–59.

source.unverified fires when an action’s owner is not in the baseline trusted set (actions, github). Extend the allowlist in .pinprick.toml:

trusted-owners = ["my-org", "vendor"]

Matching is exact owner, case-insensitive. See Config File for the full set of options.

$ pinprick score
pinprick score v0.5.0 rubric
Grade: C (72 / 100)
Findings (11 unique, 24 occurrences):
high 2 pin.branch actions/foo@main
high 1 source.archived bar/baz@abc1234
medium 6 pin.sliding 7 actions
low 2 pin.full_tag 2 actions
Top remediations:
1. Pin actions/foo@main to a full SHA (-15)
2. Replace bar/baz (archived) with a maintained action (-10)
...
Run `pinprick score --json` for the full report.

The rubric is independently versioned from the pinprick binary (currently v0.5.0). Every scan records the rubric version so historical scores remain interpretable as the rubric evolves. Re-scoring against a newer rubric is always explicit — pinprick never silently re-grades a past scan.