-
Notifications
You must be signed in to change notification settings - Fork 3
ci: migrate ci_security and ci_scheduled to org-infra reusable workflows #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
bb24415
ci: migrate ci_security and ci_scheduled to org-infra reusable workflows
yvonnedevlinrh 927ae8d
chore(openspec): mark code review passed and add config scaffold
yvonnedevlinrh d12588d
ci: drop packages and id-token write from call_reusable_vuln_scan
yvonnedevlinrh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
openspec/changes/fix-ci-security-reusable-migration/.openspec.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| schema: spec-driven | ||
| created: 2026-09-02 |
63 changes: 63 additions & 0 deletions
63
openspec/changes/fix-ci-security-reusable-migration/design.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| ## Context | ||
|
|
||
| Both `ci_security.yml` and `ci_scheduled.yml` contain two inline jobs with the same dead SHAs: | ||
| - `osv-scanner`: calls `google/osv-scanner-action/osv-scanner-action@e5012758...` (v2.0.2) — SHA gone upstream. | ||
| - `scorecards`: calls `ossf/scorecard-action@05b42c62...` (v2.4.2) — SHA gone upstream. | ||
|
|
||
| Both hard-fail with "unable to find version" — `ci_security.yml` on every PR, `ci_scheduled.yml` on the nightly cron. A previous attempt to fix the OSV SHA in `ci_security.yml` was reverted (`89ea9d7`) because the fix also required switching from the inline step form to OSV's own reusable workflow caller form — a structural change, not just a SHA bump. | ||
|
|
||
| The canonical fix pattern is established in `unbound-force/unbound-force` and `complytime/.github`, both of which replace the inline jobs with calls to `complytime/org-infra` reusable workflows. Notably, `complytime/.github` consolidates the scheduled OSV + Scorecard runs into a single `reusable_scheduled.yml` call rather than keeping separate inline jobs. | ||
|
|
||
| See `proposal.md` for motivation. | ||
|
|
||
| ## Goals / Non-Goals | ||
|
|
||
| **Goals:** | ||
| - Replace both broken inline jobs with org-infra reusable workflow calls. | ||
| - Match the structure and permission set used in `unbound-force/unbound-force` (the org canonical). | ||
| - Pin the org-infra SHA using the same `@<sha> # <version>` comment convention used everywhere else in this repo. | ||
|
|
||
| **Non-Goals:** | ||
| - Adding Trivy source scanning (not in scope for this repo; `enable_trivy_source` defaults to `false` in `reusable_vuln_scan.yml`). | ||
| - Touching `ci_checks.yml` — its inline Go lint/test jobs are repo-specific and not covered by `reusable_ci.yml`. | ||
| - Touching `ci_dependencies.yml` — that is covered separately by issue #41. | ||
|
|
||
| ## Decisions | ||
|
|
||
| ### Decision: Pin to the same org-infra SHA as `unbound-force/unbound-force` | ||
|
|
||
| The org canonical (`unbound-force/unbound-force`) pins both reusable calls at `0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1`. Using the same SHA avoids introducing drift between managed repos and is immediately verifiable against a known-good reference. | ||
|
|
||
| **Alternative considered**: Pin to the latest org-infra `main` SHA (`6f6dc6c9...`). Rejected because it has not been vetted as a tagged release and would silently diverge from the org canonical. | ||
|
|
||
| ### Decision: Mirror the `unbound-force/unbound-force` permissions exactly | ||
|
|
||
| The org canonical sets: | ||
| - `call_reusable_vuln_scan`: `contents: read`, `actions: read`, `security-events: write`, `packages: write`, `id-token: write` | ||
| - `call_reusable_security`: `contents: read`, `id-token: write`, `security-events: write` | ||
|
|
||
| The `packages: write` and `id-token: write` on the vuln-scan job are required by the reusable even when trivy image scanning is skipped (the reusable's job-level permissions are inherited). Omitting them causes a permission error at runtime. | ||
|
|
||
| **Alternative considered**: Trim to only what the enabled inputs need. Rejected — the org-infra reusable declares its permission needs; callers must satisfy them regardless of which inputs are toggled. | ||
|
|
||
| ### Decision: Keep the same job names as the current workflow | ||
|
|
||
| The current check names (`OSV-Scanner`, `OpenSSF Scorecards`) are set by the reusable workflows' own job `name:` fields and will be preserved automatically. The caller `name:` fields should match so GitHub's required-checks UI stays consistent. | ||
|
|
||
| ### Decision: Use `reusable_scheduled.yml` for `ci_scheduled.yml` rather than separate reusable calls | ||
|
|
||
| `complytime/.github` consolidates the scheduled OSV + Scorecard runs into a single `reusable_scheduled.yml` call. The alternative — calling `reusable_vuln_scan.yml` and `reusable_security.yml` individually from `ci_scheduled.yml` (as `ci_security.yml` does) — would work but diverges from the peer reference. `reusable_scheduled.yml` is purpose-built for the cron use case and requires a simpler permission set than the combined individual calls. | ||
|
|
||
| **Alternative considered**: Call `reusable_vuln_scan.yml` + `reusable_security.yml` from `ci_scheduled.yml` the same way `ci_security.yml` does. Rejected — `reusable_scheduled.yml` already encapsulates this combination for the scheduled context and is what the peer repo uses. | ||
|
|
||
| ## Risks / Trade-offs | ||
|
|
||
| - **[Risk] org-infra SHA drifts** → Mitigation: adding `dependabot.yml` for `github-actions` ecosystem (tracked in issue #41 / PR #40) will auto-propose SHA updates via Dependabot PRs. | ||
| - **[Risk] Future org-infra reusable changes break callers** → Mitigation: pinning by SHA means no surprise breakage; updates are explicit and reviewable. | ||
|
|
||
| ## Migration Plan | ||
|
|
||
| 1. Edit `.github/workflows/ci_security.yml` on branch `opsx/fix-ci-security-reusable-migration` — replace both inline jobs with `reusable_vuln_scan.yml` and `reusable_security.yml` caller jobs. | ||
| 2. Edit `.github/workflows/ci_scheduled.yml` on the same branch — replace both inline jobs with a single `reusable_scheduled.yml` caller job. | ||
| 3. Push — CI re-runs automatically on the open PR and the two failing checks should go green. The scheduled workflow fix takes effect on the next nightly cron run after merge. | ||
| 4. No rollback complexity: if the reusable calls fail, reverting the two file edits restores the previous state (though the previous state also hard-fails, so a rollback is only useful to isolate a new issue). |
27 changes: 27 additions & 0 deletions
27
openspec/changes/fix-ci-security-reusable-migration/proposal.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| ## Why | ||
|
|
||
| `ci_security.yml` and `ci_scheduled.yml` both pin two action SHAs that no longer resolve: `google/osv-scanner-action@e5012758...` (v2.0.2) and `ossf/scorecard-action@05b42c62...` (v2.4.2). The dead SHAs cause a hard CI failure on every PR — including PR #40 — with "unable to find version", and will fail the nightly cron job identically. The upstream actions have moved on and those SHAs are gone. Adopting the org-infra reusable workflows (`reusable_vuln_scan.yml`, `reusable_security.yml`, and `reusable_scheduled.yml`) fixes both files by delegating to SHAs that org-infra actively maintains, and aligns this repo with the org-standard pattern already used in `unbound-force/unbound-force` and `complytime/.github`. | ||
|
|
||
| ## What Changes | ||
|
|
||
| - Replace the inline `osv-scanner` and `scorecards` jobs in `ci_security.yml` with calls to `reusable_vuln_scan.yml` and `reusable_security.yml` from `complytime/org-infra` — this also switches from the old inline step form to the OSV-maintained reusable workflow caller form (v2.5.1). | ||
| - Replace the inline `osv-scanner` and `scorecards` jobs in `ci_scheduled.yml` with a single call to `reusable_scheduled.yml` from `complytime/org-infra`, which handles the scheduled OSV + Scorecard runs together (matching the `complytime/.github` pattern). | ||
| - Both files pin org-infra at the same SHA already used by `unbound-force/unbound-force` (`0c784711... # v0.7.1`). | ||
|
|
||
| ## Capabilities | ||
|
|
||
| ### New Capabilities | ||
|
|
||
| - `ci-security`: The security CI workflows (`ci_security.yml` and `ci_scheduled.yml`) must delegate OSV scanning and OpenSSF Scorecard analysis to org-infra reusable workflows rather than running inline steps with self-managed action SHAs. | ||
|
|
||
| ### Modified Capabilities | ||
|
|
||
| *(none — no existing specs)* | ||
|
|
||
| ## Impact | ||
|
|
||
| - `.github/workflows/ci_security.yml` — inline OSV + Scorecard jobs replaced. | ||
| - `.github/workflows/ci_scheduled.yml` — inline OSV + Scorecard jobs replaced. | ||
| - No other workflows, configs, or source files are affected. | ||
| - The `OSV-Scanner` and `OpenSSF Scorecards` check names visible in GitHub CI remain the same (defined by the reusable workflows). | ||
| - Unblocks PR #40 (`issue-39-enrich-org-labels`) which currently has two hard CI failures from `ci_security.yml`; also prevents the same failures from hitting the nightly cron via `ci_scheduled.yml`. |
53 changes: 53 additions & 0 deletions
53
openspec/changes/fix-ci-security-reusable-migration/specs/ci-security/spec.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| ## Purpose | ||
|
|
||
| Defines the security CI workflows' obligations for OSV vulnerability scanning and OpenSSF Scorecard analysis — both on PRs (`ci_security.yml`) and on schedule (`ci_scheduled.yml`) — delegating execution to org-infra reusable workflows rather than managing action SHAs inline. | ||
|
|
||
| ## ADDED Requirements | ||
|
|
||
| ### Requirement: OSV scanning via org-infra reusable workflow | ||
| The security CI workflow SHALL delegate OSV dependency scanning to `complytime/org-infra/.github/workflows/reusable_vuln_scan.yml` rather than running an inline `google/osv-scanner-action` step. | ||
|
|
||
| #### Scenario: OSV scan runs on pull_request to main | ||
| - **WHEN** a pull request targets the `main` branch | ||
| - **THEN** the `reusable_vuln_scan.yml` caller job is triggered and the OSV-Scanner check is reported in CI | ||
|
|
||
| #### Scenario: OSV scan runs on push to main | ||
| - **WHEN** a commit is pushed directly to `main` | ||
| - **THEN** the `reusable_vuln_scan.yml` caller job is triggered and the OSV-Scanner check is reported in CI | ||
|
|
||
| #### Scenario: Dead OSV SHA no longer blocks CI | ||
| - **WHEN** a PR is opened against `main` | ||
| - **THEN** the CI workflow SHALL NOT fail with "unable to find version" for `google/osv-scanner-action` | ||
|
|
||
| ### Requirement: OpenSSF Scorecard analysis via org-infra reusable workflow | ||
| The security CI workflow SHALL delegate OpenSSF Scorecard analysis to `complytime/org-infra/.github/workflows/reusable_security.yml` rather than running an inline `ossf/scorecard-action` step. | ||
|
|
||
| #### Scenario: Scorecard runs on push to main | ||
| - **WHEN** a commit is pushed directly to `main` | ||
| - **THEN** the `reusable_security.yml` caller job is triggered and the OpenSSF Scorecards check is reported in CI | ||
|
|
||
| #### Scenario: Scorecard runs on schedule | ||
| - **WHEN** the scheduled cron trigger fires | ||
| - **THEN** the `reusable_security.yml` caller job is triggered | ||
|
|
||
| #### Scenario: Dead Scorecard SHA no longer blocks CI | ||
| - **WHEN** a PR is opened against `main` | ||
| - **THEN** the CI workflow SHALL NOT fail with "unable to find version" for `ossf/scorecard-action` | ||
|
|
||
| ### Requirement: Scheduled OSV and Scorecard runs via org-infra reusable workflow | ||
| The scheduled CI workflow SHALL delegate the nightly OSV scan and Scorecard analysis to `complytime/org-infra/.github/workflows/reusable_scheduled.yml` rather than running inline steps. | ||
|
|
||
| #### Scenario: Scheduled workflow runs on cron trigger | ||
| - **WHEN** the nightly cron trigger fires | ||
| - **THEN** the `reusable_scheduled.yml` caller job is triggered and both OSV-Scanner and OpenSSF Scorecards checks are executed | ||
|
|
||
| #### Scenario: Dead SHAs no longer block scheduled runs | ||
| - **WHEN** the scheduled cron trigger fires | ||
| - **THEN** the workflow SHALL NOT fail with "unable to find version" for either `google/osv-scanner-action` or `ossf/scorecard-action` | ||
|
|
||
| ### Requirement: Caller workflows pin org-infra reusable by SHA | ||
| The `uses:` reference to each org-infra reusable workflow in both `ci_security.yml` and `ci_scheduled.yml` SHALL be pinned to a full commit SHA with a version comment, following the same pin-by-SHA convention used throughout this repo. | ||
|
|
||
| #### Scenario: SHA pin present in both workflow files | ||
| - **WHEN** `ci_security.yml` or `ci_scheduled.yml` is read | ||
| - **THEN** each `uses: complytime/org-infra/...` line includes a full 40-character SHA and an inline version comment (e.g., `# v1.2.3`) |
22 changes: 22 additions & 0 deletions
22
openspec/changes/fix-ci-security-reusable-migration/tasks.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ## 1. Rewrite ci_security.yml | ||
|
|
||
| - [x] 1.1 Replace the inline `osv-scanner` job in `.github/workflows/ci_security.yml` with a `call_reusable_vuln_scan` job that calls `complytime/org-infra/.github/workflows/reusable_vuln_scan.yml@0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1` with permissions `contents: read`, `actions: read`, `security-events: write`, `packages: write`, `id-token: write`. Verify the job block matches the `unbound-force/unbound-force` canonical. | ||
|
|
||
| - [x] 1.2 Replace the inline `scorecards` job with a `call_reusable_security` job that calls `complytime/org-infra/.github/workflows/reusable_security.yml@0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1` with permissions `contents: read`, `id-token: write`, `security-events: write`. Verify the job block matches the canonical. | ||
|
|
||
| - [x] 1.3 Update the top-level `permissions` block to add `packages: none` alongside the existing `actions: none`, `id-token: none`, `security-events: none` (mirroring `complytime/.github`). Verify no stale permission fields remain. | ||
|
|
||
| ## 2. Rewrite ci_scheduled.yml | ||
|
|
||
| - [x] 2.1 Replace both inline jobs (`osv-scanner` and `scorecards`) in `.github/workflows/ci_scheduled.yml` with a single `call_reusable_scheduled` job that calls `complytime/org-infra/.github/workflows/reusable_scheduled.yml@0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1` with permissions `contents: read`, `actions: read`, `security-events: write`, `id-token: write`. Verify the result matches the `complytime/.github` canonical. | ||
|
|
||
| ## 3. Verify locally | ||
|
|
||
| - [x] 3.1 Run `make lint` (or `yamllint .github/workflows/ci_security.yml .github/workflows/ci_scheduled.yml`) and confirm zero lint errors on both edited files. | ||
|
|
||
| ## 4. Push and confirm CI | ||
|
|
||
| - [ ] 4.1 Push the branch. In PR #40, confirm that both `OSV-Scanner` and `OpenSSF Scorecards` checks transition from FAILURE to SUCCESS (or neutral/skipped if the repo lacks OIDC publish rights for Scorecards). Verify the `Dependency Review` check is the only remaining failure (addressed separately by issue #41). | ||
|
|
||
| <!-- spec-review: passed --> | ||
| <!-- code-review: passed --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| schema: spec-driven |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.