feat(package): pin GitHub refs to commit SHAs before package scans - #56
Merged
Merged
Conversation
`safedep package scan run pkg:github/owner/repo@main` sent `main` as the version. A branch or tag moves, so the scan and its idempotency key drifted away from the code that was reviewed. Resolve every GitHub target to the commit SHA it points to, in `run`, `get`, `show` and the `list` filter, so all four commands name the same immutable version. A full SHA passes through without a lookup. A GitHub URL without a ref resolves to the head of the default branch. The resolver is `adapters.GithubClient.ResolveCommitSHA` from dry, built in `App.GitHub()` from the same GITHUB_* variables vet reads. Commands accept it as a one-method interface so tests use a fake and prove that non-GitHub targets never touch the network. The dry bump also pulls a newer API SDK. The jfrog fake threat intel client gains the new RPC so it still satisfies the interface. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016cyGZqVsNaGBCzrof9qtDc
SafeDep Report SummaryPackage Details
This report is generated by SafeDep GitHub App |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 23e913b60a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
`get --scan-id` and `show --scan-id` never resolve a target, but the commands built the GitHub client before the lookup. A bad GITHUB_BASE_URL then failed a lookup that needs only the control plane. The resolver now builds the client on the first GitHub target. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016cyGZqVsNaGBCzrof9qtDc
safedep/dry#154 merged. Move the pin from the branch commit to main head. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016cyGZqVsNaGBCzrof9qtDc
Sahilb315
approved these changes
Sep 2, 2026
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.




Why
safedep package scan run pkg:github/owner/repo@mainsentmainas the version. A branch or tag moves, so the scan and its idempotency key drifted away from the code that was reviewed. vet already pins refs in its malware enricher. The CLI now does the same.What
github_actionsandgithub_repository) is resolved to the commit SHA its ref points to. This applies to thepkg:github/...PURL, a GitHub URL and the explicit triple, inrun,get,showand thelistfilter, so all four name the same immutable version./tree/<ref>resolves to the head of the default branch.App.GitHub()builds the client from the sameGITHUB_TOKEN,GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRETandGITHUB_BASE_URL/GITHUB_UPLOAD_URLvariables vet reads. Commands pass a lazy resolver as a one-method interface, so the client is built only on the first GitHub target and--scan-idlookups never touch it. Tests use a fake and prove that non-GitHub targets never call it.tui.Infoon stderr, so--output jsonstays clean.run,get,showandlistdescribe the resolution and theGITHUB_TOKENrate-limit note.Dependency
Uses
GithubClient.ResolveCommitSHAandIsCommitSHAfrom safedep/dry#154, now merged. go.mod pins dry to the main commit that carries it. The dry bump also pulls a newer API SDK, so the jfrog fake threat intel client gains the newGetCampaignPackageReportsRPC to keep satisfying the interface.Verification
go test ./...passes.golangci-lint runreports 0 issues.🤖 Generated with Claude Code
https://claude.ai/code/session_016cyGZqVsNaGBCzrof9qtDc