Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Dependabot version updates
# ===========================
# Keeps pinned GitHub Action SHAs current via automated pull requests.
# Scoped to the github-actions ecosystem only; the go.mod tooling manifest
# is intentionally out of scope for this repo.
# See: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
include: "scope"
32 changes: 22 additions & 10 deletions .github/workflows/ci_dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
name: Dependencies

# --------------------------------------------------------------------------
# Dependency review for all PRs.
# Dependency review for all PRs, delegated to the org-infra reusable
# workflows (matching ci_security.yml / ci_scheduled.yml in this repo).
#
# Dependency review is SOFT-GATED: reusable_deps_reviewer.yml wraps
# actions/dependency-review-action with continue-on-error: true, so a
# missing Dependency Graph (GitHub Advanced Security is not enabled on
# this repo) no longer hard-fails every PR. The result is surfaced as an
# output rather than as a blocking gate. Re-evaluate this soft-gate if the
# Dependency Graph / GitHub Advanced Security is ever enabled here.
#
# The Dependabot comment and auto-approve jobs from the canonical org
# pattern are intentionally OMITTED: this repo governs org policy
# (Peribolos, safe-settings, rulesets), so auto-approving Dependabot PRs
# here is an elevated attack surface pending a separate threat-model review.
# --------------------------------------------------------------------------

on:
Expand All @@ -11,15 +24,14 @@ on:

permissions:
contents: read
issues: none
pull-requests: none

jobs:
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
call_deps_reviewer:
name: General
uses: complytime/org-infra/.github/workflows/reusable_deps_reviewer.yml@0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1

- name: Dependency Review
uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9 # v4.7.1
call_dependabot_reviewer:
name: Dependabot
uses: complytime/org-infra/.github/workflows/reusable_dependabot_reviewer.yml@0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-09-02
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Context

See proposal.md — Why. The current `ci_dependencies.yml` runs `actions/dependency-review-action` inline and hard-fails every PR because the Dependency Graph is unavailable. This repo already delegates its other security CI (`ci_security.yml`, `ci_scheduled.yml`) to `complytime/org-infra` reusable workflows pinned at `0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1`, so the reusable-caller pattern and the org-infra trust boundary are already established and operationally proven here. The canonical dependency-review callers exist in `unbound-force/unbound-force/.github/workflows/ci_dependencies.yml` and `complytime/.github/.github/workflows/ci_dependencies.yml`. `safe-settings/settings.yml` sets org-wide `enableAutomatedSecurityFixes: true`; there is currently no `.github/dependabot.yml` in this repo.

## Goals / Non-Goals

**Goals:**
- Stop the dependency-review hard-fail on every PR to `main` by delegating to `reusable_deps_reviewer.yml` (which wraps the action with `continue-on-error: true`).
- Align `ci_dependencies.yml` with the org-standard reusable-caller pattern used by the sibling workflows in this repo and across the org.
- Add `.github/dependabot.yml` for the `github-actions` ecosystem so action SHA pins stay current and auditable.

**Non-Goals:**
- Enabling GitHub Advanced Security / the Dependency Graph on this repo (explicitly out of plan).
- Enabling Dependabot auto-approve / auto-merge in this repo (deferred pending a separate threat-model review — see Open Questions).
- Adding Dependabot ecosystems beyond `github-actions` (this repo has no application dependency manifests that Dependabot would act on; `go.mod` exists but is tooling-only and out of scope for this change).
- Changing `ci_security.yml`, `ci_scheduled.yml`, Peribolos config, or safe-settings config.

## Decisions

**D1 — Delegate to org-infra reusables rather than adding `continue-on-error` to the inline step.**
The minimal hotfix would be to add `continue-on-error: true` (or an `if:` guard) to the existing inline `dependency-review-action` step. Rejected in favor of the reusable-caller migration because: (a) it converges on the org-standard pattern already used by the two sibling workflows in this repo, reducing per-repo drift; (b) it matches the parallel adoption tracked in `unbound-force/replicator#38` and the canonical callers in `unbound-force/unbound-force` and `complytime/.github`; (c) the reusable centralizes the soft-gate posture and result-surfacing so it stays consistent across repos.

**D2 — Pin `complytime/org-infra` by full commit SHA with a version comment.**
Both new `uses:` lines will be pinned to `0c784711926c9864f027ec565fd7c06a382d80f8 # v0.7.1` — the exact SHA already used by `ci_security.yml` and `ci_scheduled.yml` in this repo. This matches the repo-wide pin-by-SHA convention and keeps org-infra references uniform. Alternative (floating tag like `@v0.7.1`) rejected: it violates the repo convention and re-introduces the mutable-ref supply-chain risk the SHA pin exists to prevent. Implementation note: before writing, confirm `reusable_deps_reviewer.yml` and `reusable_dependabot_reviewer.yml` exist at that SHA; if v0.7.1 predates those files, bump both org-infra references (all callers in this repo) to the earliest SHA that contains them.

**D3 — Exclude the Dependabot auto-approve/auto-merge job from this repo.**
The canonical pattern includes an auto-approve flow. It is excluded here because `unbound-force/.github` controls org membership (Peribolos) and repository security settings (safe-settings) for the entire org; auto-merging Dependabot PRs into this repo is an elevated attack surface (e.g., a malicious action SHA substitution auto-merged into org policy). The `reusable_dependabot_reviewer.yml` caller is included (review/labeling only), but no auto-approve job is added. Re-enabling is gated on a separate threat-model review.

**D4 — Add `.github/dependabot.yml` scoped to `github-actions` only.**
This is the only ecosystem relevant to this repo's CI, and it is the prerequisite that makes SHA pins maintainable. Weekly schedule, consistent with typical org config. No `open-pull-requests-limit` change beyond defaults is required for this change. `go.mod` exists but is tooling-only and deliberately excluded (see Non-Goals); no other ecosystem entries are added.

**D5 — Permissions posture for the caller jobs.**
Verified against org-infra at the pinned SHA: both `reusable_deps_reviewer.yml` and `reusable_dependabot_reviewer.yml` are passive (review-only, output-emitting) and declare `permissions: { contents: read, issues: none, pull-requests: none }`. The `pull-requests: write` scope in the canonical `ci_dependencies.yml` is granted only at the job level for the comment/auto-approve jobs — which this change deliberately excludes. Therefore the migrated `ci_dependencies.yml` keeps a restrictive top-level block matching the canonical caller: `contents: read`, `issues: none`, `pull-requests: none`. No per-job `permissions:` overrides are needed because the two included callers require no write scopes.

## Risks / Trade-offs

- **Dependency-review signal becomes advisory (`continue-on-error: true`).** If GHAS/Dependency Graph is ever enabled on this repo, real vulnerability findings would no longer block PRs — they would pass silently. → Mitigation: the reusable captures the result as an output and surfaces it (job summary / annotation) rather than discarding it; document the soft-gate posture in the workflow. Re-evaluate the gate if GHAS is ever enabled.
- **CI availability coupling to `complytime/org-infra`.** An org-infra outage or a bad reusable revision could break the dependency CI job. → Mitigation: this coupling is identical to and no worse than the coupling already accepted by `ci_security.yml`/`ci_scheduled.yml`, and the SHA pin prevents unreviewed upstream changes from flowing in.
- **Adding Dependabot PRs where there were none.** Enabling `github-actions` updates will start generating Dependabot PRs. → Mitigation: acceptable and desired (keeps SHAs current); no auto-approve means every PR still requires human review, so there is no unattended-merge risk.

## Migration Plan

1. Replace the `dependency-review` job (checkout + `dependency-review-action` steps) in `ci_dependencies.yml` with `call_deps_reviewer` and `call_dependabot_reviewer` caller jobs pinned per D2.
2. Add `.github/dependabot.yml` with the `github-actions` ecosystem entry.
3. Validate YAML locally (`make sanity` / `yamllint`).
4. Open a PR and confirm the Dependency Review check no longer hard-fails and no inline `dependency-review-action` step remains.
5. Rollback: revert the two files (`ci_dependencies.yml`, `.github/dependabot.yml`) to their prior state; there is no state or data migration to unwind.

## Open Questions

- **Should Dependabot auto-approve ever be enabled for `unbound-force/.github`?** Deferred to a separate security review with an explicit threat model and, if approved, compensating controls (e.g., required human review on top of auto-approve, restricted Dependabot scope). This does not affect the specs, approach, or task breakdown of this change — auto-approve is out of scope here regardless of the eventual answer.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Why

`.github/workflows/ci_dependencies.yml` runs `actions/dependency-review-action@da24556b… (v4.7.1)` as a bare inline step with no `continue-on-error` guard. Because the Dependency Graph feature is not enabled on this repo (and there is no plan to enable GitHub Advanced Security here), the action hard-fails on **every** pull request to `main` with "Dependency review is not supported on this repository". This is a 100%-reproducible blocking CI gate, and the inline form also diverges from the org-standard reusable-caller pattern already adopted in this repo's `ci_security.yml` / `ci_scheduled.yml` and tracked for `unbound-force/replicator#38`.

## What Changes

- Replace the inline `dependency-review` job in `ci_dependencies.yml` with a caller to `complytime/org-infra/.github/workflows/reusable_deps_reviewer.yml`, which wraps `dependency-review-action` with `continue-on-error: true` so a missing Dependency Graph no longer blocks PRs; the result is captured as an output and surfaced informally rather than as a hard gate.
- Add a caller to `complytime/org-infra/.github/workflows/reusable_dependabot_reviewer.yml` for Dependabot-authored PRs, matching the canonical pattern in `unbound-force/unbound-force` and `complytime/.github`.
- **Explicitly exclude** the Dependabot auto-approve / auto-merge job from scope for this repo. Because `unbound-force/.github` governs org policy (Peribolos membership, safe-settings, rulesets), auto-approving Dependabot PRs here is an elevated attack surface; it is deferred pending a separate threat-model review.
- Pin both `uses:` references to `complytime/org-infra` at a full commit SHA with a version comment, matching the existing pin-by-SHA convention (`0c784711…926c9864f027ec565fd7c06a382d80f8 # v0.7.1`) already used by `ci_security.yml` and `ci_scheduled.yml`.
- Add `.github/dependabot.yml` for the `github-actions` ecosystem so action SHA updates are proposed automatically. This complements `safe-settings/settings.yml`'s org-wide `enableAutomatedSecurityFixes: true` and keeps action pins auditable.
- Remove the existing inline `actions/dependency-review-action` step and its `actions/checkout` step.

## Capabilities

### New Capabilities
- `ci-dependencies`: The dependency CI workflow (`ci_dependencies.yml`) SHALL delegate dependency review to org-infra reusable workflows rather than running an inline `dependency-review-action` step, and the repo SHALL declare a `github-actions` Dependabot configuration.

### Modified Capabilities
<!-- None — no existing specs under openspec/specs/. -->

## Impact

- `.github/workflows/ci_dependencies.yml` — inline `dependency-review` job (checkout + dependency-review-action steps) replaced by reusable-workflow callers.
- `.github/dependabot.yml` — new file declaring the `github-actions` ecosystem for automated action SHA updates.
- New CI availability coupling to `complytime/org-infra` for the dependency-review callers — identical in nature to the coupling already accepted by `ci_security.yml` and `ci_scheduled.yml`.
- The Dependency Review check name visible in GitHub CI changes from the inline job to the reusable-workflow caller job name(s) (`General`, `Dependabot`).
- No source files, Peribolos config, or safe-settings config are affected.
- Unblocks all future PRs to `main`, which currently hit a hard `dependency-review` failure. Same adoption is tracked in parallel for `unbound-force/replicator#38`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Purpose

Defines the dependency CI workflow's obligations for dependency review on pull requests — delegating execution to org-infra reusable workflows rather than running an inline `dependency-review-action` step — and the repository's obligation to declare a `github-actions` Dependabot configuration for automated action SHA updates.

## ADDED Requirements

### Requirement: Dependency review via org-infra reusable workflow
The dependency CI workflow SHALL delegate dependency review to `complytime/org-infra/.github/workflows/reusable_deps_reviewer.yml` rather than running an inline `actions/dependency-review-action` step.

#### Scenario: Dependency review runs on pull_request to main
- **WHEN** a pull request targets the `main` branch
- **THEN** the `reusable_deps_reviewer.yml` caller job is triggered and its Dependency Review check is reported in CI

#### Scenario: Missing Dependency Graph no longer blocks CI
- **WHEN** a pull request is opened against `main` and the Dependency Graph feature is not enabled on the repository
- **THEN** the dependency CI workflow SHALL NOT hard-fail the pull request
- **AND** the dependency review outcome is surfaced informally rather than as a blocking gate

#### Scenario: Inline dependency-review-action step removed
- **WHEN** `ci_dependencies.yml` is read
- **THEN** it SHALL NOT contain an inline `uses: actions/dependency-review-action` step

### Requirement: Dependabot PR review via org-infra reusable workflow
The dependency CI workflow SHALL delegate review of Dependabot-authored pull requests to `complytime/org-infra/.github/workflows/reusable_dependabot_reviewer.yml`.

#### Scenario: Dependabot reviewer caller present
- **WHEN** `ci_dependencies.yml` is read
- **THEN** it SHALL contain a caller job for `reusable_dependabot_reviewer.yml`

### Requirement: Dependabot auto-approve excluded from this repository
The dependency CI workflow SHALL NOT enable Dependabot auto-approve or auto-merge behavior, because this repository governs organization policy (Peribolos membership, safe-settings, rulesets) and auto-approval represents an elevated attack surface pending a separate threat-model review.

#### Scenario: No auto-approve job configured
- **WHEN** `ci_dependencies.yml` is read
- **THEN** it SHALL NOT contain a job that automatically approves or auto-merges Dependabot pull requests

### Requirement: Caller workflows pin org-infra reusable by SHA
The `uses:` reference to each org-infra reusable workflow in `ci_dependencies.yml` SHALL be pinned to a full commit SHA with an inline version comment, following the same pin-by-SHA convention used throughout this repository.

#### Scenario: SHA pin present for each caller
- **WHEN** `ci_dependencies.yml` is read
- **THEN** each `uses: complytime/org-infra/...` line includes a full 40-character SHA and an inline version comment (e.g., `# v0.7.1`)

### Requirement: Dependabot configuration for the github-actions ecosystem
The repository SHALL declare a `.github/dependabot.yml` configuration covering the `github-actions` package ecosystem so that action SHA updates are proposed automatically. As part of this change, no ecosystem entries beyond `github-actions` SHALL be added (the `go.mod` tooling manifest is deliberately out of scope).

#### Scenario: dependabot.yml declares github-actions ecosystem
- **WHEN** `.github/dependabot.yml` is read
- **THEN** it SHALL contain an entry with `package-ecosystem: "github-actions"` and a defined update schedule
- **AND** it SHALL NOT contain any `package-ecosystem` entry other than `github-actions`
Loading
Loading