Skip to content

ci: apply the public OSS security suite to this repository - #42

Merged
rldyourmnd merged 1 commit into
mainfrom
ci/dogfood-public-oss-suite
Jul 24, 2026
Merged

ci: apply the public OSS security suite to this repository#42
rldyourmnd merged 1 commit into
mainfrom
ci/dogfood-public-oss-suite

Conversation

@rldyourmnd

@rldyourmnd rldyourmnd commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

This repository ships CodeQL, OSSF Scorecard, Dependency Review and gitleaks to the rest of the estate and consumed none of them itself. It self-applied only actionlint, zizmor and release-supply-chain, so the repository that defines the estate's security posture had the weakest one in it.

Verified against gh api repos/NDDev-it-com/ci-workflows/actions/workflows — no such caller was registered, so this is not local checkout drift.

Found while auditing CI across all four public estate repositories.

Type of change

  • New reusable workflow / capability — self-application callers, not new reusables
  • Hardening / security posture improvement

Threat-model note

These are self workflows: this repository calling its own reusables through relative ./ refs, so no new third-party code enters the supply chain and no new external dependency is pinned. The attack surface added is the token scope each reusable already requires of every other consumer.

The one scope worth naming is dependency-review.yml's pull-requests: write, which lets the reusable post its summary comment. It is contained by the trigger: pull_request only, and pull_request (not pull_request_target) runs with a read-only token on fork PRs, so a fork cannot use it to write to this repository.

scorecard.yml takes id-token: write for OIDC, restricted to push-on-default and schedule — it never runs on a PR, so an untrusted ref cannot reach it.

Permissions diff

All four are new files; there is no prior state.

codeql (codeql job):
+ actions: read              # read workflow run metadata for the actions analysis
+ contents: read
+ security-events: write     # upload CodeQL SARIF to the Security tab

gitleaks (gitleaks job):
+ contents: read             # no elevation

dependency-review (dependency-review job):
+ contents: read
+ pull-requests: write       # post the dependency review summary on the PR

scorecard (scorecard job):
+ id-token: write            # OIDC token for Scorecard provenance checks
+ contents: read
+ actions: read              # inspect workflow definitions for the scoring checks

Checklist

  • All third-party actions pinned to a full 40-char commit SHA — N/A: these call local reusables by relative ref; the reusables carry the pins
  • Least-privilege permissions (top-level {}, per-job minimal scopes)
  • concurrency and timeout-minutes present on new/changed workflows/jobs — concurrency on the push/PR-triggered files; timeout-minutes lives in the called reusables
  • persist-credentials: false on all read-only actions/checkout steps — N/A: no checkout step in a caller
  • No ${{ ... }} interpolated inside run:N/A: no run: steps
  • Paid public/GHAS actions absent from private-free/cross-tier files — all four are public-tier callers in a public repository
  • actionlint passes locally
  • zizmor --pedantic passes locally — it initially reported 3 undocumented-permissions findings; every elevated scope now carries an explanatory comment and it reports "No findings"
  • README capability table and docs/ / catalog/ updated — SELF_WORKFLOWS entries carry no catalog record by design; docs/generated/ regenerated
  • CHANGELOG.md updated under [Unreleased]
  • Commits are signed (-S) and signed off (-s, DCO); Conventional Commit messages

Tier impact

  • Public (free OSS suite)
  • Private free tier
  • Private paid tier

The contract change, and why

SELF_WORKFLOWS gains the four names. That set already existed for exactly this: files that are this repository applying its own catalog rather than defining a reusable, so they carry no catalog, runtime-coverage or inventory entry.

While wiring it I found the same literal set duplicated in three places — _workflow_yaml.py holds the named constant, but validate_catalog.py and generate_docs.py each hardcoded {"ci.yml", "release.yml"} again. Both now import the constant.

That was not cosmetic. With the constant honoured in only one of the three, validate_all.py passed while the generated inventory listed the new callers as MISSING | MISSING instead of internal | internal — a green gate over wrong generated output.

Verification

python3 scripts/validate_all.py exits 0. actionlint and zizmor --pedantic clean on all four files. docs/generated/ regenerated; the only diff is the four new rows, correctly marked internal.

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@rldyourmnd
rldyourmnd force-pushed the ci/dogfood-public-oss-suite branch from ffbda52 to 14941b2 Compare July 24, 2026 18:28
This repository ships CodeQL, OSSF Scorecard, Dependency Review and gitleaks to
the estate and consumed none of them itself. It self-applied only actionlint,
zizmor and release-supply-chain, so the repository that defines the estate's
security posture had the weakest one in it.

Add four self-application callers using relative refs, matching ci.yml's
existing convention; only external consumers pin by full SHA. The gitleaks
caller is named gitleaks.yml because secret-scan.yml is the reusable definition.
Triggers follow the repository's own examples/public-oss shapes: Scorecard is
push-to-default plus schedule because the action does not support pull_request,
and Dependency Review is pull_request only.

SELF_WORKFLOWS gains the four names. That set already existed to mark files that
are this repository applying its own catalog rather than reusable definitions,
so they carry no catalog, runtime-coverage or inventory entry.

The same literal set was duplicated in three places: _workflow_yaml.py held the
constant while validate_catalog.py and generate_docs.py each hardcoded
{ci.yml, release.yml} again. Both now import it, so the exemption is defined
once. Without that, the generated inventory listed the new callers as MISSING
rather than internal.

scripts/validate_all.py exits 0.

Signed-off-by: Danil Silantyev <danilsilantyevwork@gmail.com>
@rldyourmnd
rldyourmnd force-pushed the ci/dogfood-public-oss-suite branch from 14941b2 to 0095566 Compare July 24, 2026 18:29
@rldyourmnd
rldyourmnd merged commit 82bab56 into main Jul 24, 2026
10 checks passed
@rldyourmnd
rldyourmnd deleted the ci/dogfood-public-oss-suite branch July 24, 2026 19:06
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.

2 participants