Repository navigation
Conversation
A finding whose rule emitted no line fell back to its job header, so a template injection in the fifth step of a job, an unpinned container image or an inherited write-all permission all landed on `jobs.<id>:`. The GitHub collector now reads, off the YAML node tree, the line of every run: script line, of the container image, of the env: entry that sets each variable and of each job key (permissions falling back to the workflow-level key). The rules report them through a shared lib.location helper: 102, 103, 203, 207, 209, 302, 309, 410, 411, 701 and 713 (reusable calls), 802 and 803. A line that is unknown stays 0 and keeps the job-header fallback, so GitLab is unchanged for now. Line is not an identity input: every fingerprint is unchanged. Each rule takes the first line that fires, so a finding keeps the one location it reports. Jobs of a called workflow drop these lines, which belong to another file, and keep landing on the calling job. Refs #572. The GitLab half is #573. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Exypte
requested review from
Totara-thib,
coconux3 and
thomasboni
as code owners
October 23, 2026 14:52
Review of the #572 change: branches of one rule that share an identity reported different lines, so one fingerprint showed as two results. ISSUE-203 takes the first of its env: entry and its $GITHUB_ENV writes, and ISSUE-209's env-bound branches the first write of the variable that fires for its value. A $GITHUB_ENV write whose name sits on a heredoc line points at the script's first line instead of the job header. ISSUE-101 reports the image line, as 102 and 103 do, and the script lines pair with the decoded scripts only when the values match, not just the count. Refs #572. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ISSUE-209's env-bound writes to $GITHUB_ENV and $GITHUB_PATH, inline and through a heredoc, and ISSUE-309's secrets dump in env: and in a step input each get a job of their own, so a helper falling back to the job header fails the test. Refs #572. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The images a called job's container resolves to through its matrix literals carry the callee's container line once parsed, a line of another file, and only the nested resolution drops it. Images resolved from the call's inputs never carry one. Pin both. Refs #572. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
PR ready to review @thomasboni |
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.
What type of PR is this?
fix
What this PR does / why we need it:
When a rule emitted no
line, the finding fell back to its job header (internal/engine/opa/engine.go). A template injection in a job's fifth step, an unpinned container image and an inheritedwrite-allall landed onjobs.<id>:. This is the GitHub half of #572.scanGitHubJobLocations(github/github_locations.go), records per job:run:script line: a literal block maps line for line; a folded, plain or quoted scalar reports its start line;env:entry that sets each variable (step over job over workflow, asmergedEnvmerges them);permissionsfalls back to the workflow-level key when the job inherits it.Image.Line,Job.ScriptLines,Job.VariableLines,Job.KeyLines.lib.locationhelper:image:env:entry, or the$GITHUB_ENVwritesecrets: inheritcontinue-on-erroruses:permissions:the job runs withWhich issue(s) this PR is related to:
Fixes #572. The GitLab half, including the include-level findings that have no location at all, is #573.
Special notes for your reviewer:
lineis not an identity input. The e2e below checks this: identical fingerprint sets on main and on this branch.location.first. Binding the line to the iteration variable would have split one finding into several that share a fingerprint.run:with different YAML versions:run: yesis a boolean to one and a string to the other.ScriptLinesis set only when both find the same number of scripts.clearJobLocationsingithub/nested_workflows.go), since they belong to another file. Those findings keep landing where they did.services:on GitHub, because the collector doesn't readservices:at all.permissions:) correctly stays on the job header.lib.locationlater.$GITHUB_ENVwrite), and 209's env-bound branches (inline write and heredoc). Otherwise one fingerprint would show up as two results.KeyLinesrecords every job key, not just the ones used today. Matrix images take the container reference's line.Does this PR introduce a user-facing change?
How was this tested?
github/github_locations_test.go: script lines for literal, plain and foldedrun:; image lines in string and mapping form; env precedence; key lines including inheritedpermissions; the alignment guard; a nested callee that keeps no lines.policies/finding_line_test.go: every code in the table through the real collector; shared-identity branches reporting one line; a GitLab job keeping the job-header fallback.go test ./...passes.nestedjob calls a workflow on a branch of a second scratch repository. I analyzed it withplumber analyze github.com/<owner>/<repo>/tree/<branch>, once with a binary built frommainand once with this branch:ci/nested/innerfindings keep the same location as on main.Fixture workflow
Callee (
.github/workflows/callee.ymlin the second repository):Results: line on main → line on this branch
AI usage disclosure:
YES. Claude Code (Claude Opus 5.5) did the investigation, implementation, tests and e2e run, under the author's direction. The author is responsible for the submitted changes (CONTRIBUTING.md, AI_POLICY.md).
🤖 Generated with Claude Code