Skip to content

feat(ci): integrate uv.lock into dependency-review via Dependency Submission API #891

@WilliamBerryiii

Description

@WilliamBerryiii

Summary

The GitHub dependency-review action scans lockfiles for known vulnerabilities during PR checks. With uv as the Python package manager, uv.lock is the lockfile format. The dependency-review action (via the Dependency Graph API) does not support uv.lock — confirmed through v4.9.0. The Dependency Submission API is the GitHub-recommended mechanism for ecosystems not natively supported by the Dependency Graph.

Context

The dependency-review action (.github/workflows/dependency-review.yml) is part of the repository's security posture, scanning for known CVEs in dependencies introduced by pull requests. It currently handles package-lock.json for npm dependencies.

Investigation Findings

Verified: uv.lock is not supported by:

  • The GitHub Dependency Graph API (recognizes requirements.txt, pipfile.lock, poetry.lock for Python — not uv.lock)
  • dependency-review-action v4.9.0 (thin client over the Dependency Graph API, does not parse lockfiles directly)
  • Dependabot (relies on the same Dependency Graph)

Ruled out: Ephemeral CI uv export --format requirements-txt does not work. The dependency-review action queries the Dependency Graph API, which diffs committed repository content only. CI-generated files are invisible to it.

Ruled out: Committing requirements.txt alongside uv.lock. While functional, this introduces lockfile drift risk (two lockfiles to maintain), requires a sync enforcement mechanism, and adds generated files to the repository. The Dependency Submission API is the cleaner, GitHub-recommended approach.

Selected Approach: Dependency Submission API

The Dependency Submission API allows CI to submit dependency data to the Dependency Graph at runtime. Dependencies submitted via this API are included in dependency-review comparisons and Dependabot alerts — confirmed by GitHub documentation.

Recommended action: advanced-security/component-detection-dependency-submission-action v0.1.1 (MIT, Microsoft-maintained). Its UvLock detector parses uv.lock files and submits the dependency tree to the graph. The detector is currently experimental (IExperimentalDetector) and requires explicit opt-in.

Fallback action: rmuir/uv-dependency-submission v1.0.0 — purpose-built for uv.lock with richer metadata (direct/indirect, runtime/dev scope). Single maintainer, 21 stars.

Criterion component-detection (recommended) rmuir/uv-dependency-submission
Version v0.1.1 v1.0.0
SHA 9c110eb34dee187cd9eca76a652b9f6a0ed22927 1c48aaac13e566e39fd04269ff1900b86c1105c5
UvLock maturity Experimental (IExperimentalDetector) Stable (purpose-built)
Permissions contents: write contents: write
Maintainer Microsoft / GitHub staff Single individual
Ecosystem breadth npm, NuGet, Maven, Pip, Go, Cargo, uv, etc. uv.lock only

Workflow Design

GitHub recommends running dependency submission and dependency review in the same workflow to guarantee ordering and eliminate race conditions. The submission step runs before the review step in the same job:

jobs:
  dependency-review:
    name: Review Dependencies
    runs-on: ubuntu-latest
    permissions:
      contents: write       # Elevated for dependency submission (from contents: read)
      pull-requests: write
    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
        with:
          persist-credentials: false

      - name: Submit uv.lock dependencies
        uses: advanced-security/component-detection-dependency-submission-action@9c110eb34dee187cd9eca76a652b9f6a0ed22927 # v0.1.1
        with:
          detectorArgs: 'UvLock=EnableIfDefaultOff'

      - name: Dependency Review
        uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
        with:
          fail-on-severity: moderate
          comment-summary-in-pr: always
          license-check: true
          allow-licenses: >-
            MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC,
            MPL-2.0, 0BSD, Unlicense, CC0-1.0, CC-BY-4.0,
            CC-BY-SA-4.0, PSF-2.0, LGPL-2.1-only
          show-openssf-scorecard: true
          warn-on-openssf-scorecard-level: 3

Note: The allow-licenses and OSSF Scorecard configuration reflects the hardening added in PR #1052. This workflow example assumes #1052 has merged.

Permission Escalation

The dependency submission step requires contents: write, elevated from the current contents: read. This is the minimum viable escalation. The id-token: write permission referenced in some action documentation is only needed for OIDC authentication scenarios, not when using the default github.token.

Architecture: Multiple Lockfiles

With independent Python projects (one pyproject.toml per skill), each skill directory contains its own uv.lock. The component-detection-dependency-submission-action automatically discovers all uv.lock files in the repository tree — no explicit path configuration required. New Python skills are automatically included in vulnerability scanning without workflow modifications.

Currently only one Python skill has dependencies: .github/skills/experimental/powerpoint/ with uv.lock and pyproject.toml.

Changes Required

File Action Change
.github/workflows/dependency-review.yml MODIFY Add component-detection-dependency-submission-action step before the dependency-review step; elevate job permissions to contents: write

Acceptance Criteria

  • Verified whether the dependency-review action supports uv.lock format — not supported through v4.9.0
  • Documented findings: ephemeral uv export does not work (Dependency Graph API reads committed files only)
  • Identified solution: Dependency Submission API via component-detection-dependency-submission-action with UvLock=EnableIfDefaultOff
  • Added dependency submission step to dependency-review.yml before the dependency-review step (same-job design)
  • Elevated job permissions from contents: read to contents: write
  • Python dependencies in PRs are scanned for known vulnerabilities across all skill directories
  • Existing npm dependency scanning is unaffected
  • Adding a new Python skill with uv.lock is automatically included in scanning (auto-discovery, no workflow changes needed)
  • If component-detection UvLock detector proves unreliable, switch to rmuir/uv-dependency-submission v1.0.0

Dependencies

Related

Metadata

Metadata

Labels

infrastructureRepository infrastructure and toolingsecuritySecurity-related changes or concerns

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions