Add use-pr-linker workflow to auto-link PRs to issues#127
Conversation
WalkthroughThis pull request adds a new GitHub Actions workflow that automates the linking of pull requests to related issues. The workflow triggers on multiple PR lifecycle events, configures appropriate permissions, and delegates to a reusable workflow from the mosip/kattu repository. ChangesPR Linking Automation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Ivanmeneges <ivan.anil016@gmail.com>
976bd4d to
41b5c8c
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/use-pr-linker.yml:
- Line 19: The reusable workflow reference in the call-linker job uses a mutable
ref ("mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop") and forwards
secrets.ACTION_PAT; replace the branch ref with a specific commit SHA for that
reusable workflow and stop forwarding secrets.ACTION_PAT to the external
workflow (or replace with a minimal, scoped token stored internally) so the
workflow is pinned and no sensitive secret is passed to an external repo.
- Around line 3-10: The workflow currently invokes the reusable workflow
reference "mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop" and
passes ACTION_PAT, which risks executing unpinned/PR-head code; pin that
reusable-workflow reference to an immutable commit SHA instead of `@develop`, and
ensure the called workflow does not checkout or run PR head code—use only
github.event metadata for all inputs/logic; if a checkout is absolutely required
in the reusable workflow, harden it by setting persist-credentials: false and
applying least-privilege token usage, and in this file narrow the
pull_request_target event types to the minimal set needed (e.g., opened and
reopened) instead of opened/edited/synchronize/closed to reduce exposure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41018544-3d4a-45ee-a630-4ed3d86094c0
📒 Files selected for processing (1)
.github/workflows/use-pr-linker.yml
| on: | ||
| pull_request_target: | ||
| types: | ||
| - opened | ||
| - edited | ||
| - synchronize | ||
| - reopened | ||
| - closed |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub pull_request_target security best practices 2025
💡 Result:
GitHub pull_request_target security best practices (grounded, up-to-date) 1) Use pull_request vs pull_request_target based on need for secrets/write access - pull_request_target runs with higher privileges than pull_request; it can access repository/organization secrets and a read/write GITHUB_TOKEN by default, especially risky when the triggering PR comes from a fork. [1][2][3] - Use pull_request_target only when you truly need the privileged context (for example: labeling/commenting/status automation), otherwise use pull_request to keep fork code isolated. [4][3] 2) The safest pattern: never check out or execute untrusted PR code in pull_request_target - The most direct mitigation is to avoid checkout/execution of forked PR code in a pull_request_target workflow (i.e., delete actions/checkout if you don’t need code). [5][4] - If you must test code, split into two workflows: (a) pull_request builds/tests on untrusted code without secrets, then (b) workflow_run triggers a privileged workflow that only consumes artifacts for reporting/side effects. [3][4] 3) Restrict what your pull_request_target workflow is allowed to do (repository checks / actor checks) - Add checks so the privileged workflow runs only for trusted PR origins (e.g., internal repo only) and trusted actors (e.g., org members/approved collaborators), instead of automatically processing arbitrary forks. [2] 4) Apply least-privilege permissions to GITHUB_TOKEN (and don’t rely on defaults) - Configure a least-privilege permissions block for the workflow/job, rather than inheriting broad defaults. GitHub documentation explicitly recommends granting the minimum required access to GITHUB_TOKEN via the permissions key. [6][7] - GitHub also notes that for fork PR events other than pull_request_target, write permissions may be adjusted to read-only when a repository setting is not enabled; pull_request_target is an exception (i.e., don’t assume the “fork PRs become read-only” protection applies). [8] - Practical goal: ensure pull_request_target workflows that must exist have minimal GITHUB_TOKEN scopes, and only the scopes needed for their limited tasks (e.g., pull-requests: write for commenting), not broad contents write. [1][6] 5) Treat secrets as “highly dangerous inputs” and prevent them from reaching attacker-controlled execution - GitHub’s Security Lab describes pull_request_target as capable of reading secrets and having write permissions, and calls out that it bypasses normal pull request approval safeguards; this increases impact when something goes wrong. [2] - Therefore, ensure user-controlled input/code cannot influence execution in a way that causes untrusted code to run with secrets access. [1] 6) Pin and harden your workflow dependencies/actions - Pin actions to immutable references (commit SHAs) rather than mutable tags, and restrict/limit third-party action risk. [9] 7) Enable automated security scanning for workflows - GitHub changelog guidance recommends enabling CodeQL code scanning to scan action workflows for common vulnerabilities (free for public repos). [1] What “good” pull_request_target looks like (examples of safe design) - Metadata-only workflows: comment/label/triage using event context, without checking out and executing PR code. [5][3] - Split-workflow design: unprivileged tests on pull_request -> privileged reporting on workflow_run (consume artifacts, not source checkout). [3][4] Notable risk to remember (why these controls matter) - Multiple security writeups and GitHub security materials emphasize the core failure mode: pull_request_target coupled with checking out and running code from the pull request can enable attackers to execute arbitrary code with access to secrets/tokens. [4][3][2] If you share one of your actual pull_request_target workflow YAMLs, I can audit it line-by-line against these rules and propose a concrete hardened rewrite.
Citations:
- 1: https://github.blog/changelog/2025-11-07-actions-pull_request_target-and-environment-branch-protections-changes/
- 2: https://securitylab.github.com/resources/github-actions-new-patterns-and-mitigations/
- 3: https://github.com/github/codeql/blob/main/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.md
- 4: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
- 5: https://paulserban.eu/blog/post/am-i-vulnerable-how-to-audit-your-github-actions-for-the-pullrequesttarget-flaw/
- 6: https://github.com/github/docs/blob/main/content/actions/tutorials/authenticate-with-github_token.md
- 7: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token
- 8: https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/workflow-syntax.md
- 9: https://asecurityengineer.com/posts/hardening-github-actions-workflows/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the workflow under review
echo "===== .github/workflows/use-pr-linker.yml ====="
sed -n '1,200p' .github/workflows/use-pr-linker.yml
# Find the reusable workflow reference(s) it calls
echo
echo "===== uses: references from use-pr-linker.yml ====="
rg -n "^\s*uses:\s*" .github/workflows/use-pr-linker.yml || true
# Extract the exact 'uses:' line(s) for reuse targets
echo
echo "===== extracted uses targets ====="
rg -n "^\s*uses:\s*" .github/workflows/use-pr-linker.yml | sed -E 's/^\s*[0-9]+:\s*uses:\s*//'
# Search for any workflow files referenced in those uses targets (best-effort by filename patterns)
# Common pattern: .github/workflows/<something>.yml
echo
echo "===== candidate workflow files under .github/workflows/ ====="
ls -la .github/workflows
# Search for reusable workflow filenames likely referenced by the uses line(s)
# (This is a heuristic; we'll still inspect the specific file once we learn the target name.)Repository: mosip/converters
Length of output: 1269
🌐 Web query:
mosip/kattu link-pr-to-issue.yml pull_request_target checkout secrets ACTION_PAT
💡 Result:
I couldn’t directly locate the specific file you named (mosip/kattu “link-pr-to-issue.yml”) in the sources returned by the web search I ran. However, I can still answer the core part of your query—what it typically means when a GitHub Actions workflow is triggered by pull_request_target, uses actions/checkout, and provides a PAT/ACTION_PAT secret. Key points grounded in cited evidence: 1) pull_request_target runs with elevated privileges and access to target-repo secrets Workflows triggered via pull_request_target have write permission to the target repository and access to target repository secrets, even if the PR comes from an external fork. This is a known risk model because attacker-controlled PR code may still end up running in the privileged workflow environment. [1] 2) Combining pull_request_target with checking out PR code increases risk Security guidance notes the danger when you pair pull_request_target with actions/checkout of the PR head (i.e., executing code from the PR). One example calls this the “line that creates the vulnerability” (checkout of github.event.pull_request.head.sha) and shows that secrets can become available to subsequent steps. [2] 3) If checkout persists credentials, downstream code can access repository tokens GitHub security lab material explains that if you use actions/checkout and don’t set persist-credentials to false, the default behavior persists the token on disk and makes it easier for any running code to read it. [1] 4) actions/checkout can accept a token (PAT) input The official actions/checkout documentation describes that a “Personal access token (PAT) used to fetch the repository” can be configured (and stored in git config) and then removed during cleanup. [3] What your query likely implies about “ACTION_PAT” Given your string includes “pull_request_target checkout secrets ACTION_PAT”, the workflow is likely doing one or more of the following: - Triggering on pull_request_target to gain permissions/secrets in the trusted base-repo context. [1] - Using actions/checkout (possibly defaulting persist-credentials=true, unless overridden) such that a token/PAT is used to fetch the repo and may be left in local git credentials for later steps. [1][3] - Supplying a PAT via secrets (e.g., ACTION_PAT) as the token for checkout and/or as the token for GitHub API calls in later steps. Recommended secure pattern (high level) - Avoid checking out PR code in pull_request_target workflows unless absolutely necessary; the safer fix is to delete the checkout step if the workflow only needs metadata already in the github.event context. [2] - If checkout is required, harden it by disabling credential persistence (persist-credentials: false) and use least-privilege tokens. [1][3] If you paste the contents of mosip/kattu’s link-pr-to-issue.yml (or the relevant job/steps using pull_request_target, actions/checkout, and ACTION_PAT), I can do a precise, line-by-line assessment of whether it is vulnerable and what to change.
Citations:
- 1: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
- 2: https://paulserban.eu/blog/post/am-i-vulnerable-how-to-audit-your-github-actions-for-the-pullrequesttarget-flaw/
- 3: https://github.com/actions/checkout?tab=readme-ov-file
🌐 Web query:
site:github.com mosip/kattu "link-pr-to-issue.yml" "pull_request_target"
💡 Result:
There is no evidence of a file named link-pr-to-issue.yml within the official MOSIP Kattu (mosip/kattu) repository [1][2]. The Kattu repository functions as a centralized library of reusable GitHub Actions workflows for MOSIP projects, covering tasks like building, testing, and deployment [1]. While you may have encountered a file with this name, it is not part of the standard MOSIP Kattu workflow suite [1]. The use of the pull_request_target event is, however, a common pattern in GitHub Actions for workflows that need to comment on or interact with pull requests from external forks, as it provides the necessary permissions to do so [3]. Similar functionality to link pull requests to issues is typically handled by third-party actions, such as nearform-actions/github-action-check-linked-issues [3] or tkt-actions/add-issue-links [4]. It is also possible that a workflow by that name was recently introduced or proposed in other MOSIP-related repositories, as evidenced by recent pull requests in other parts of the MOSIP ecosystem [5][6].
Citations:
- 1: https://github.com/mosip/kattu
- 2: https://github.com/mosip/kattu/blob/master/docs/npm-build-readme.md
- 3: https://github.com/nearform-actions/github-action-check-linked-issues
- 4: https://github.com/tkt-actions/add-issue-links
- 5: Add use-pr-linker workflow to auto-link PRs to issues release-script#1703
- 6: Add use-pr-linker workflow to auto-link PRs to issues security-tools#55
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "ACTION_PAT|link-pr-to-issue\.yml|mosip/kattu/\.github/workflows/link-pr-to-issue\.yml" .github/workflows . || trueRepository: mosip/converters
Length of output: 425
Harden pull_request_target reusable-workflow invocation (pin + ensure no PR code execution)
.github/workflows/use-pr-linker.ymlrunspull_request_targetand passesACTION_PATtomosip/kattu/.github/workflows/link-pr-to-issue.yml@develop; ensure the called reusable workflow never checks out or executes untrusted PR head code (use onlygithub.eventmetadata), and if checkout is ever required it must be hardened (persist-credentials: false, least-privilege).- Pin the reusable workflow reference to an immutable commit SHA instead of
@developto prevent supply-chain changes. - Consider narrowing event types to what’s required for linking (typically
opened/reopened);edited/synchronize/closedexpand the exposure surface.
🧰 Tools
🪛 zizmor (1.25.2)
[error] 3-10: use of fundamentally insecure workflow trigger (dangerous-triggers): pull_request_target is almost always used insecurely
(dangerous-triggers)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/use-pr-linker.yml around lines 3 - 10, The workflow
currently invokes the reusable workflow reference
"mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop" and passes
ACTION_PAT, which risks executing unpinned/PR-head code; pin that
reusable-workflow reference to an immutable commit SHA instead of `@develop`, and
ensure the called workflow does not checkout or run PR head code—use only
github.event metadata for all inputs/logic; if a checkout is absolutely required
in the reusable workflow, harden it by setting persist-credentials: false and
applying least-privilege token usage, and in this file narrow the
pull_request_target event types to the minimal set needed (e.g., opened and
reopened) instead of opened/edited/synchronize/closed to reduce exposure.
|
|
||
| jobs: | ||
| call-linker: | ||
| uses: mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Get the latest commit SHA from mosip/kattu develop branch
gh api repos/mosip/kattu/commits/develop --jq '.sha'Repository: mosip/converters
Length of output: 101
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File context =="
nl -ba .github/workflows/use-pr-linker.yml | sed -n '1,120p'
echo
echo "== Search matches =="
rg -n "mosip/kattu/|link-pr-to-issue|ACTION_PAT|secrets\." .github/workflows/use-pr-linker.yml || trueRepository: mosip/converters
Length of output: 140
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File context (lines 1-60) =="
cat -n .github/workflows/use-pr-linker.yml | sed -n '1,60p'
echo
echo "== Search matches in workflow file =="
rg -n "mosip/kattu|link-pr-to-issue|ACTION_PAT|secrets\." .github/workflows/use-pr-linker.yml || trueRepository: mosip/converters
Length of output: 763
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== mosip/kattu reusable workflow refs =="
rg -n "mosip/kattu/\.github/workflows/.*`@develop`|mosip/kattu/\.github/workflows/.*@" .github/workflows || true
echo
echo "== All `@develop` refs in workflows =="
rg -n "`@develop`" .github/workflows || trueRepository: mosip/converters
Length of output: 1222
Pin the reusable workflow reference to a commit SHA (don’t use @develop).
In .github/workflows/use-pr-linker.yml (job call-linker), the reusable workflow is referenced as mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop, which can change without notice (supply-chain risk). It also forwards secrets.ACTION_PAT to that external workflow.
🔒 Example fix
- uses: mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop
+ uses: mosip/kattu/.github/workflows/link-pr-to-issue.yml@6bb3c38b8f5643b906a0d7f4baaede996766b71e📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| uses: mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop | |
| uses: mosip/kattu/.github/workflows/link-pr-to-issue.yml@6bb3c38b8f5643b906a0d7f4baaede996766b71e |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 19-19: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/use-pr-linker.yml at line 19, The reusable workflow
reference in the call-linker job uses a mutable ref
("mosip/kattu/.github/workflows/link-pr-to-issue.yml@develop") and forwards
secrets.ACTION_PAT; replace the branch ref with a specific commit SHA for that
reusable workflow and stop forwarding secrets.ACTION_PAT to the external
workflow (or replace with a minimal, scoped token stored internally) so the
workflow is pinned and no sensitive secret is passed to an external repo.
Adds
use-pr-linker.ymlcallingmosip/kattulink-pr-to-issue.yml@develop. Requires ACTION_PAT secret.Summary by CodeRabbit