How supply-chain security works
We scan our own repositories rather than relying on GitHub’s built-in scanning, because GitHub Advanced Security is not licensed for this organisation. Code scanning, secret scanning and push protection are therefore unavailable to us as platform features. What we run instead is assembled from four repositories, and this page is the map of it.
The four layers
Section titled “The four layers”| Layer | What it catches | How it runs |
|---|---|---|
| Dependabot | Known vulnerabilities in declared dependencies | Alerts, security updates and the dependency graph are enabled per repository by github-iac. Version updates are separate: they need a .github/dependabot.yml in the repo, and each repo opts in |
| Aikido safe-chain | Malicious packages at install time, before their scripts run | Installed on CI runners by setup-ci-runner |
| OpenSSF Scorecard | Weak repository practices, including unpinned actions, missing branch protection and stale dependencies | The shared static-analysis-scorecard workflow |
| CodeQL | Vulnerabilities in our own code | The shared static-analysis-codeql workflow |
Dependabot and safe-chain guard the dependencies coming in. Scorecard and CodeQL measure what we have. The two pairs answer different questions and neither substitutes for the other.
Both signals land on one dashboard
Section titled “Both signals land on one dashboard”Scorecard and CodeQL do not report in place. Each workflow emits an artifact — JSON for
Scorecard, SARIF (Static Analysis Results Interchange Format) for CodeQL — and a weekly
aggregator in
security-dashboard
collects them across repositories and renders one static page at
scorecard.ajomark.dev (Cloudflare Access, then Auth0).
What covers this repository
Section titled “What covers this repository”Not all four layers reach this site’s own repository, and the gap is deliberate rather than an oversight:
- Scorecard — not yet onboarded. Onboarding is a rollout from
security-dashboard(aconfig/repos.jsonentry, thenscripts/rollout-scorecard.sh), never a hand-edited workflow here — see add a repository to the dashboard. - CodeQL — not run. GitHub Advanced Security is unlicensed, so results cannot be
uploaded for a non-public repository, and there is little to scan: three
.astrocomponents, one Python script, and prose. - Aikido safe-chain — not run. This repo’s CI uses plain
ubuntu-latestrather than asetup-ci-runnerrunner, so the layer does not apply to itsnpm ci. - Dependabot — alerts and security updates apply as everywhere. Version updates are
configured here for
github-actionsonly, to keep the SHA pins current.
The two are kept in separate S3 namespaces on purpose: a Scorecard score is a number that trends over time, while CodeQL findings are a list diffed snapshot to snapshot. Storing them together would make one of the two views wrong (ADR-0008).
Every run also writes a history snapshot, so a regression can be traced to the week it appeared rather than merely observed (ADR-0006).
The dashboard signals do not block a pull request
Section titled “The dashboard signals do not block a pull request”Deliberately. A Scorecard regression is informational, not a gate (ADR-0007).
The reasoning is that a Scorecard score moves for reasons unrelated to the pull request in front of you — a dependency ages, a check is added upstream — and a gate that fires on things the author cannot fix gets routed around within a week. An informational signal that people actually read beats a blocking one they learn to bypass.
That is a decision about this signal, not a general position. Required checks in your own repository’s CI still block, and org policy is explicit that they must be green before merge.
Two conventions that are really supply-chain controls
Section titled “Two conventions that are really supply-chain controls”Both look like CI style rules and are not:
- Third-party actions pinned by SHA. A tag can be moved; a SHA cannot. Nothing
enforces this: the org-level Actions allowlist in
github-iaccontrols which actions may run, not how a workflow references them. Scorecard scores it, and review is what catches it, so check the pin when you review a workflow. - Internal reusable workflows referenced at
@main. The trust boundary is the organisation, so an internal reference is allowed to move.
Why those two are consistent rather than contradictory, and what follows from it, is on how CI runs across our repos — that page owns the reasoning.
The package-manager choice in m1-web belongs in the same category: the migration from
npm to pnpm was made for supply-chain hardening rather than speed
(m1-web ADR-0010).
What is proposed but not decided
Section titled “What is proposed but not decided”Adding Semgrep CE and Trivy alongside CodeQL is a Proposed ADR, not current behaviour (ADR-0009). If someone tells you Trivy runs on our repositories, check that ADR’s status before believing it.
Reporting a vulnerability
Section titled “Reporting a vulnerability”Private vulnerability reporting is a GitHub Advanced Security feature, so we do not have
it. Use the channels in
.github/SECURITY.md
instead, and never a public issue.
Where to go next
Section titled “Where to go next”- Add a repository to the dashboard
- How the dashboard works
- The GitHub organisation model — where the Dependabot defaults and the Actions allowlist are set