Conversation
Pin all GitHub Actions to commit SHAs to prevent tag-based supply chain attacks (same class as CVE-2025-30066). Replace softprops/action-gh-release (single-maintainer, no security policy) with gh CLI. Add top-level permissions: {} to all workflows that lacked it, enforcing least-privilege by default. Enable Dependabot for GitHub Actions and pip dependencies. Closes #471
|
Docs preview: https://5fb796f1.dd-docs-preview.pages.dev
|
Greptile SummaryThis PR hardens CI supply chain security by pinning ~30 GitHub Action references to commit SHAs, replacing
|
| Filename | Overview |
|---|---|
| .github/dependabot.yml | New file: adds weekly Dependabot updates for GitHub Actions (root) and pip (three sub-package directories), correctly addressing the previous comment about per-package pip entries. |
| .github/workflows/pack-tutorials.yml | Adds permissions: {} top-level, pins actions/download-artifact to SHA, and replaces softprops/action-gh-release with gh release upload; the build-notebooks: reusable-workflow call lacks permissions: actions: read, silently disabling cache seeding. |
| .github/workflows/build-docs.yml | Adds permissions: {} top-level and pins all actions to SHAs; build-notebooks: reusable-workflow call lacks permissions: actions: read, silently disabling cache seeding in the called workflow. |
| .github/workflows/build-notebooks.yml | Adds permissions: {} top-level; build job correctly grants actions: read and contents: write; all actions pinned to SHAs. |
| .github/workflows/ci.yml | Adds permissions: {} top-level and pins all actions/checkout and astral-sh/setup-uv references to SHAs; test jobs don't need GITHUB_TOKEN so no permission issues. |
| .github/workflows/docs-preview.yml | Adds permissions: {} top-level; build-and-deploy job correctly specifies contents: read and pull-requests: write; all four third-party actions pinned to SHAs. |
| .github/workflows/agentic-ci-pr-review.yml | Pins actions/checkout to SHA (v4); already had explicit top-level permissions so no change needed there. |
| .github/workflows/semantic-pull-requests.yml | Pins the external reusable workflow call to a commit SHA; already had correct permissions. |
Sequence Diagram
sequenceDiagram
participant GH as GitHub Event
participant PT as pack-tutorials.yml
participant BN as build-notebooks.yml
participant Runner as Runner
participant GHAPI as GitHub API
GH->>PT: release:published / workflow_dispatch
Note over PT: permissions: {} (top-level)
PT->>BN: calls reusable workflow (no job-level permissions)
Note over BN: GITHUB_TOKEN inherits permissions: {} from caller
BN->>Runner: checkout + install + build notebooks
BN-->>Runner: upload artifact (service token, unaffected)
BN-->>PT: artifact available
PT->>Runner: download artifact → zip tutorials
Note over PT: zip-and-upload job: permissions: contents:write
Runner->>GHAPI: gh release upload tag zip_file
GHAPI-->>Runner: asset uploaded
Runner->>Runner: rm zip (cleanup)
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/build-docs.yml
Line: 16-19
Comment:
**Reusable-workflow call inherits `permissions: {}`, silently losing `actions: read`**
With top-level `permissions: {}` and no `permissions:` key on this job, the GITHUB_TOKEN passed into `build-notebooks.yml` is capped at zero permissions. The called workflow's `build` job explicitly grants `actions: read`, but that grant cannot exceed what the caller provides, so it is effectively `none`. The immediate consequence is that the "Seed cache from last successful artifact" step (`gh run list` / `gh run download`) silently fails and the cache-seeding path is skipped — falling back to a full rebuild on every run. Adding `permissions: actions: read` here preserves the intended behaviour. (The same applies to `pack-tutorials.yml` line 12.)
```suggestion
build-notebooks:
uses: ./.github/workflows/build-notebooks.yml
permissions:
actions: read
with:
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: .github/workflows/pack-tutorials.yml
Line: 11-13
Comment:
**Reusable-workflow call inherits `permissions: {}`, silently losing `actions: read`**
Same issue as `build-docs.yml`: the `build-notebooks:` job has no `permissions:` block, so the called workflow's GITHUB_TOKEN is capped at `{}` (from the top-level `permissions: {}`). The `actions: read` declared inside `build-notebooks.yml` is nullified. The cache-seeding step (`gh run list`/`gh run download`) silently falls back to a full rebuild.
```suggestion
build-notebooks:
uses: ./.github/workflows/build-notebooks.yml
permissions:
actions: read
secrets: inherit
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (3): Last reviewed commit: "Merge branch 'main' into andreatgretel/c..." | Re-trigger Greptile
PR #517 Review: chore: harden CI supply chainSummaryThis PR hardens the CI pipeline against supply chain attacks by:
Motivated by CVE-2025-30066 (tj-actions/changed-files tag compromise) and Astral's open-source security writeup. Changes are CI-only with no runtime code impact. Changed files (10): All under FindingsSHA Pin Verification (all passed)All SHA-to-tag mappings were verified against upstream repositories:
Workflow Coverage CheckTwo workflows were not modified by this PR:
All workflows are accounted for. Permissions ModelThe Suggestion (Low Severity): Explicit
|
The root directory has no pyproject.toml; the actual packages live under packages/data-designer-config, packages/data-designer-engine, and packages/data-designer.
The Dependabot config added in #517 included weekly version-bump PRs for all three pip packages. This would generate noisy PRs for routine dep updates we don't need. Set open-pull-requests-limit: 0 on the pip ecosystems so only CVE-triggered security updates open PRs. GitHub Actions weekly bumps are kept as-is to keep SHA pins current.
The Dependabot config added in #517 included weekly version-bump PRs for all three pip packages. This would generate noisy PRs for routine dep updates we don't need. Set open-pull-requests-limit: 0 on the pip ecosystems so only CVE-triggered security updates open PRs. GitHub Actions weekly bumps are kept as-is to keep SHA pins current.
Address Greptile review findings: - Pin checkout, setup-uv, and download-artifact to commit SHAs matching the pattern from #517 - Add top-level permissions: {} to restrict default token scope
- Add a Dependabot group to bundle all GitHub Actions updates into a single weekly PR instead of one per action - Fix DCO allowlist: dependabot -> dependabot[bot] to match the actual GitHub username (the old value never matched, but there were no Dependabot PRs before #517 to expose the bug)
* fix: restrict Dependabot pip updates to security-only The Dependabot config added in #517 included weekly version-bump PRs for all three pip packages. This would generate noisy PRs for routine dep updates we don't need. Set open-pull-requests-limit: 0 on the pip ecosystems so only CVE-triggered security updates open PRs. GitHub Actions weekly bumps are kept as-is to keep SHA pins current. * fix: group Dependabot Actions PRs and fix DCO allowlist - Add a Dependabot group to bundle all GitHub Actions updates into a single weekly PR instead of one per action - Fix DCO allowlist: dependabot -> dependabot[bot] to match the actual GitHub username (the old value never matched, but there were no Dependabot PRs before #517 to expose the bug) * fix: align DCO assistant if-condition with custom sign-off text The step's if-condition checked for the default sign-off text but custom-pr-sign-comment uses different wording. This meant the issue_comment trigger was always skipped - sign-offs only worked by accident when a subsequent push re-triggered the action via pull_request_target.
* ci: add workflow to publish devnotes independently of releases Adds a GitHub Actions workflow that rebuilds the `latest` docs alias when devnotes change on main, so blog posts go live without cutting a package release. * ci: pin actions to commit SHAs and restrict default permissions Address Greptile review findings: - Pin checkout, setup-uv, and download-artifact to commit SHAs matching the pattern from #517 - Add top-level permissions: {} to restrict default token scope * ci: build devnotes from last deployed state, not main Instead of building the full site from main (which could include unreleased docs), checkout the commit that latest was last built from (tracked in gh-pages commit messages) and overlay only docs/devnotes/ from main. Download notebooks from the last successful build-docs run instead of rebuilding them. * ci: add actions:read permission for notebook download The gh run list/download calls need actions:read on GITHUB_TOKEN, which is denied by the top-level permissions: {} block.
📋 Summary
Harden CI workflows against supply chain attacks by pinning all GitHub Actions to
immutable commit SHAs, removing a single-maintainer third-party action, enforcing
least-privilege workflow permissions, and enabling Dependabot. Motivated by
CVE-2025-30066
(tj-actions/changed-files tag compromise) and
Astral's open-source security writeup.
🔗 Related Issue
Closes #471
🔄 Changes
# vNcomments for readabilitysoftprops/action-gh-releasewithgh release uploadinpack-tutorials.yml, eliminating a single-maintainer dependency with no security policypermissions: {}to 7 workflows that lacked it (build-docs,build-notebooks,check-colab-notebooks,ci,docs-preview,health-checks,pack-tutorials), enforcing least-privilege by default.github/dependabot.ymlfor weekly automated updates to GitHub Actions and pip dependencies🧪 Testing
make testpasses - N/A, no runtime code changespack-tutorialsworkflow works on next release or viaworkflow_dispatch✅ Checklist