ci: support external contributor PRs securely - #310
Merged
Conversation
- Switch CI to GitHub-hosted runners (ubuntu-latest) so fork PRs never execute on self-hosted infrastructure - Reduce permissions to contents:read for lint & test job - Guard API keys step to only run for internal PRs - Move labeling and test report publishing to ci-trusted.yml using pull_request_target (safe: never checks out fork code) - Isolate docs deployment to a separate job with minimal permissions
ckorchane-ledger
approved these changes
Jul 29, 2026
fsamier
enabled auto-merge (squash)
July 29, 2026 10:11
Contributor
There was a problem hiding this comment.
Pull request overview
This PR restructures GitHub Actions CI to safely support external (fork) pull requests by moving privileged operations (labeling, commenting) into a separate trusted workflow and reducing permissions in the main CI workflow.
Changes:
- Switched CI to GitHub-hosted runners (
ubuntu-latest) with read-only permissions for PRs, and guarded secret-dependent steps. - Replaced inline test reporting with artifact upload in
ci.yml, and introduced a newci-trusted.ymlworkflow intended to publish reports and manage labels with write permissions. - Split GitHub Pages deployment into a dedicated
deploy-docsjob that only runs on pushes tomainwith minimal Pages permissions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| .github/workflows/ci.yml | Harden CI for fork PRs (runner/permissions), upload artifacts (tests/docs), and deploy docs only on main pushes. |
| .github/workflows/ci-trusted.yml | New trusted workflow using pull_request_target for labeling and test report publishing. |
Comments suppressed due to low confidence (1)
.github/workflows/ci-trusted.yml:77
- This workflow is triggered by
pull_request_target, sogithub.event.workflow_run.idis not present in the event payload. The artifact download will fail (or always download nothing) becauserun-idresolves to an empty value.
- name: Download test results artifact
timeout-minutes: 5
uses: actions/download-artifact@v4
with:
name: test-results
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+63
to
+68
| uses: lewagon/wait-on-check-action@v1.3.4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| check-name: "lint & test" | ||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
| wait-interval: 30 |
Comment on lines
+16
to
+19
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
|
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Adapt CI workflows to safely support external contributor (fork) PRs, addressing the security and functional issues surfaced by #308.
Changes
ci.yml— Hardened for fork PRsubuntu-latest(GitHub-hosted runners) — untrusted fork code must never run on self-hosted runners (public-ledgerhq-shared-small) to prevent arbitrary code execution on Ledger infrastructurecontents: readat job level — principle of least privilegeif: github.event.pull_request.head.repo.full_name == github.repository— secrets are empty for fork PRs, but this makes intent explicitci-trusted.ymlsince these need write accessdeploy-docsjob with minimal permissions (pages: write,id-token: write), only runs on push tomainci-trusted.yml— New workflow for privileged operationspull_request_targettrigger — runs in the base branch context with access to secrets/write tokenSecurity considerations
pull_request_targetworkflow never checks out fork code (onlybase.ref)Notes
release.ymlintentionally kept onpublic-ledgerhq-shared-small(needs JFrog Artifactory access)