Skip to content

Add security hardening modeled after deterministic-deps #104

Description

@bjcorder

Context

bjcorder/deterministic-deps has a useful security-hardening pattern that Rulepath should adopt before broader release and external contributor activity. I inspected the repository on 2026-05-05. The repo is an MIT-licensed GitHub Action with security policy enabled, latest release v1.0.0, and a CI/security posture built around deterministic workflow refs, least-privilege permissions, scheduled checks, SARIF upload, dependency review, CodeQL, zizmor, OpenSSF Scorecard, Dependabot grouping/cooldowns, and its own dependency determinism policy.

This issue tracks implementing the same style of hardening for Rulepath, adapted for a Rust workspace.

Source Pattern To Mirror

Reference implementation in bjcorder/deterministic-deps:

Related upstream docs:

Implementation Scope

Add Rulepath security-hardening workflows and policy files that preserve the repository's deterministic dependency posture.

1. Add dependency determinism workflow

  • Add a workflow that runs bjcorder/deterministic-deps against Rulepath on pull requests, pushes to main, and a weekly schedule.
  • Use advisory mode initially unless the repository is already clean enough to enforce.
  • Upload SARIF to code scanning when a SARIF file is emitted.
  • Pin bjcorder/deterministic-deps, actions/checkout, and github/codeql-action/upload-sarif to full commit SHAs, not tags.
  • Coordinate with Integrate dependency-deps action for dependency pinning enforcement #19 and update any older bjcorder/dependency-deps naming to the actual bjcorder/deterministic-deps action if needed.

2. Add CodeQL for Rust

  • Add .github/workflows/codeql.yml for Rust analysis.
  • Run on pull requests, pushes to main, and a weekly schedule.
  • Use least-privilege permissions: contents: read, security-events: write.
  • Pin all external actions by full commit SHA.
  • Prefer a deterministic build path that uses the pinned Rust toolchain and cargo build --locked --workspace if CodeQL needs an explicit build.
  • Document any CodeQL limitations or required build mode decisions in workflow comments or docs/.

3. Add dependency review

  • Add .github/workflows/dependency-review.yml for pull requests.
  • Start with fail-on-severity: high and revisit once dependency policy stabilizes.
  • Pin actions/checkout and actions/dependency-review-action to full commit SHAs.
  • Use least-privilege permissions: contents: read, pull-requests: read.

4. Add workflow hygiene scanning

  • Add a workflow hygiene job using zizmorcore/zizmor-action, modeled after deterministic-deps.
  • Scan .github/dependabot.yml, .github/workflows, and any action metadata if Rulepath later adds local actions.
  • Use persona: auditor with medium-or-higher severity/confidence as the first posture.
  • Upload SARIF if supported by the selected pinned action/configuration.
  • Keep all external actions SHA-pinned.

5. Add OpenSSF Scorecard

  • Add an OpenSSF Scorecard job with SARIF output and code-scanning upload.
  • Use publish_results: true only if appropriate for the repository's public posture.
  • Use permissions matching the deterministic-deps pattern: contents: read, id-token: write, security-events: write.
  • Pin ossf/scorecard-action, actions/checkout, and SARIF upload actions to full commit SHAs.

6. Add Rust security audit coverage

  • Add a Rust dependency/advisory audit job using an appropriate Rust-native tool such as cargo-deny or cargo-audit.
  • The selected tool and installation method must itself be deterministic: pin the installer/action/version by immutable commit SHA or use a checked-in config and a deterministic install path.
  • Include checks for advisories at minimum; consider licenses, bans, and source allowlists if using cargo-deny.
  • Add config files such as deny.toml only if needed and document the initial policy.

7. Harden existing CI conventions

  • Keep permissions: contents: read as the default workflow permission unless a job needs more.
  • Use persist-credentials: false for checkout where possible.
  • Keep all third-party workflow actions pinned to full commit SHA with comments naming the upstream action/version being pinned.
  • Use scheduled runs with staggered cron times so security jobs do not all run at once.
  • Prefer advisory/reporting mode first where noisy findings are likely, then document the path to enforcement.

8. Improve Dependabot policy

  • Update .github/dependabot.yml to mirror useful deterministic-deps settings where supported:
    • weekly schedule for Cargo and GitHub Actions
    • labels for dependency/security/CI work
    • grouped PRs for related dependency updates where practical
    • open PR limit
    • commit message prefix/scope
    • cooldown if supported for the ecosystem
  • Ensure Dependabot updates do not weaken SHA-pinning policy for GitHub Actions.

9. Documentation updates

Update repository docs so contributors understand the hardening posture:

  • CONTRIBUTING.md: mention security/dependency workflow expectations for PRs.
  • SECURITY.md: mention CI security checks and how to report bypasses or vulnerabilities.
  • docs/cli-ci.md or a new security/dependency doc: describe CodeQL, dependency review, deterministic-deps, workflow hygiene, Scorecard, and Rust advisory checks.
  • PR template if needed: include a checkbox for security workflow/pinning impact.

Acceptance Criteria

  • Rulepath has security-hardening workflows for dependency determinism, CodeQL, dependency review, workflow hygiene, OpenSSF Scorecard, and Rust advisory/dependency auditing.
  • Every external GitHub Action in those workflows is pinned by full commit SHA.
  • Workflows use least-privilege permissions and persist-credentials: false where possible.
  • SARIF-producing jobs upload results to GitHub code scanning with if: always() where appropriate.
  • Initial mode is advisory/reporting for checks likely to be noisy, with clear follow-up notes for enforcement.
  • Existing cargo build/test/clippy/fmt --locked CI remains intact.
  • Dependabot config uses useful labels, grouping, limits, and cooldowns where supported.
  • Documentation and PR checklist explain the repository's deterministic dependency/security posture.
  • CI passes after the new workflows/config are added.

Suggested Labels

enhancement, priority:p1, phase:5-adoption-ops, area:ci, area:docs, dependencies, size:m

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:ciCI behavior, baselines, dependency policy, and workflowsarea:docsRepository documentationdependenciesPull requests that update a dependency fileenhancementNew feature or requestphase:5-adoption-opsAdoption, releases, docs, Wiki, and operationspriority:p1Important v1 worksize:mMedium implementation slice

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions