| Table of Contents |
Appendix: Trigger-by-Trigger Risk Profile
Quick-reference for every trigger that has a standalone page, plus the triggers that don’t. Each entry summarizes the guidance, key dimensions, and links to the full page. See Triggers for the guidance key.
This appendix also covers triggers without a standalone page (e.g., repository_dispatch).
workflow_dispatch — ✅ Recommended
- Authz: Write+ required. Auto-paired with most gh-aw triggers.
- Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do (canonical way for one workflow to invoke another). - Concurrency: Standard.
- Fork guard:
if: $—workflow_dispatchis the explicit escape hatch. - Note: Branch selection is user-controlled — a write-role contributor can dispatch against a branch with different workflow YAML.
- Integrity filtering:
approved(default) for outputs that require triage+ permissions.unapproved/nonewhen the dispatched workflow reads community content (e.g., ad-hoc triage run), paired with tightsafe-outputs.
schedule — ✅ Recommended
- Authz: None — no actor. Runs as default branch workflow file.
- Approval gate: Not subject.
- Copilot events: N/A (time-driven).
- Concurrency:
$. Fewest compounding pitfalls of any trigger — concurrency/idempotency challenges exist but are not compounded by privilege-escalation or trust-boundary risks. - Fork guard:
if: $(defense-in-depth; schedules disabled on forks by default). - Idempotency: Required. Pair with
workflow_dispatchfor manual off-schedule runs. - Cost: Watch for unbounded growth — a workflow designed for 20 issues running against 2,000.
- Integrity filtering:
approved(default) for outputs that require triage+ permissions.unapprovedfor housekeeping pollers that scan community content (e.g., stale issue sweeps, triage of community-filed issues), paired with tightsafe-outputs.
labeled / label_command: — ✅ Recommended
- Authz: Triage+ (label application requires triage role).
triageis the natural fit foron.roles:. - Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$withcancel-in-progress: false. - Fork guard:
if: $ - Idempotency: Required.
label_command:auto-removes the label (one-shot), but must be safe to re-run. - Integrity filtering:
none— the label application is the human-in-the-loop gate.
issues — ✅ Recommended
- Authz: Read (anyone can open/edit/close own issues).
on.roles: allis acceptable. - Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$. - Fork guard:
if: $ - Sanitize: Yes —
steps.sanitized.outputs.text; unsanitized OK within sandboxed agent job. - Integrity filtering:
approved(default) for outputs that require triage+ permissions (e.g., auto-labeling workflow).unapproved/nonefor workflows that scan community issues (e.g., duplicate detection withadd-commentonly).
release — ✅ Recommended
- Authz: Write+ (creating/publishing releases requires write access).
- Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$. - Fork guard:
if: $ - Idempotency: Required — releases can be deleted and re-created.
- Integrity filtering:
approved(default) for outputs that require triage+ permissions.unapproved/nonewhen scanning community issues (e.g., closing issues resolved by the release), paired with tightsafe-outputs.
milestone — ✅ Recommended
- Authz: Write+ (milestone operations require write access).
- Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$. - Fork guard:
if: $ - Cascade: Deleting a milestone fires
issues.demilestoned/pull_request.demilestonedfor every assigned item.on: milestone≠on: issues: types: [milestoned]. - Integrity filtering:
approved(default) for outputs that require triage+ permissions.unapproved/nonewhen scanning community issues (e.g., generating release notes from community-filed issues in the milestone), paired with tightsafe-outputs.
push — ⚠️ Use with caution
- Authz: Write+ (push access required).
- Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Runs: On every matching push; always use explicit
branches:and optionallypaths:/tags:filters. - Concurrency:
$-$. - Fork guard:
if: $ - Integrity filtering:
approved(default) for outputs that require triage+ permissions.unapprovedfor post-merge scans that find community issues resolved by the push (e.g., commenting or closing resolved issues), paired with tightsafe-outputs.
issue_comment / slash_command: — ⚠️ Use with caution (public repos) · ✅ Recommended (private repos)
- Authz: Read (anyone can comment).
on.roles: allacceptable for community-facing commands. - Approval gate: Not subject — even on fork PRs. Key advantage over
pull_request. - Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$withcancel-in-progress: false. - Fork guard:
if: $ - Sanitize: Yes —
steps.sanitized.outputs.text; unsanitized OK within sandboxed agent job. - Idempotency: Required.
lock-for-agent: trueavailable but use with extreme caution. slash_command:specifics: Always narrowevents:. Broad subscription + shared concurrency group = non-matching-cancels-matching race.- Integrity filtering:
approvedfor privileged commands (e.g.,/backportthat applies labels or dispatches workflows).unapprovedfor community-facing bots (e.g.,/helpthat only posts replies), paired with tightsafe-outputs.
pull_request_review — ⚠️ Use with caution
- Authz: Read (anyone can submit a review).
on.roles: allacceptable — same considerations asissues. - Approval gate: Not directly subject (unless workflow also subscribes to
pull_request). - Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$withcancel-in-progress: false. Prefer separate workflows per trigger to avoid group-key collisions. - Fork guard:
if: $ - Note: “Review submitted” ≠ “approved.” Fires for
COMMENT-type reviews from any user. - Integrity filtering:
approvedfor post-approval automation (e.g., applying ready-to-land label).unapproved/nonewhen intentionally reading community review content (e.g., reply-only review bot), paired with tightsafe-outputs.
pull_request_review_comment — ⚠️ Use with caution
- Authz: Read (anyone can post inline comments).
on.roles: allacceptable. - Approval gate: Not directly subject (unless workflow also subscribes to
pull_request). - Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$withcancel-in-progress: false. Prefer separate workflow frompull_request/pull_request_review. - Fork guard:
if: $ - Note: The trigger nobody remembers exists. Inline comments are high-leverage surface for positioned content.
- Integrity filtering:
approved(e.g., agent-generated code explanations).unapproved/nonewhen intentionally reading community inline comments (e.g., reply-only bot). Highest-leverage injection vector.
discussion / discussion_comment — ⚠️ Use with caution
- Authz: Read.
on.roles: allacceptable — same considerations asissues. - Approval gate: Not subject.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Concurrency:
$-$withcancel-in-progress: false. - Fork guard:
if: $ - Sanitize: Yes —
steps.sanitized.outputs.text; unsanitized OK within sandboxed agent job. - Note: Most-open untrusted-input surface; no approval gate; lower visibility/monitoring than issues or PRs.
- Integrity filtering:
approvedfor privileged operations (e.g., labeling or routing discussions).unapprovedfor community Q&A bots (e.g., auto-reply withadd-commentonly), paired with tightsafe-outputs.
workflow_call — ☢️ Use with extreme caution
- Authz: Inherits caller’s. Callee cannot enforce its own role check.
- Approval gate: Inherits caller’s.
- Copilot events: Inherits caller’s.
- Concurrency: Layers on top of caller’s.
- Note:
secrets: inherithands every secret to the callee. Pin by SHA, not branch. Undeclared trust boundary. - Integrity filtering:
approvedas defense-in-depth; caller’s trigger determines the real threat model.
workflow_run — ☢️ Use with extreme caution
- Authz: Indirect (whoever triggered the upstream workflow).
- Approval gate: Not subject — this is what makes it dangerous. No human gate between fork PR’s CI and privileged downstream.
- Copilot events: All workflow completions trigger, including
GITHUB_TOKEN-triggered ones. - Runs: With full secrets and write token on the default branch.
- Concurrency:
$-$. - Fork guard:
if: $. Treat all downloaded artifacts as untrusted. - Alternatives:
schedule,issue_comment/slash_command:. - Integrity filtering:
approved;mergedfor production-content-only workflows.unapproved/nonecarries full-secrets warning. Does not filter downloaded artifacts.
pull_request — ⛔ Avoid (public repos) · ☢️ Use with extreme caution (private repos)
- Authz: Anyone who can open a PR (incl. fork contributors).
on.roles: allis acceptable. - Approval gate: Subject. The existence of any
pull_requestworkflow causes the button, and clicking approves all gated workflows. Button appears even when the contributor doesn’t matchon.roles:. - Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Runs: Read-only
GITHUB_TOKEN, no secrets for fork PRs1. The safer of the two PR triggers. - Concurrency:
$-$. - Fork guard:
if: $ - Alternatives:
schedule,issue_comment/slash_command:,labeled/label_command:. - Integrity filtering:
approved. Fork contributors are typicallyCONTRIBUTORor lower, so their PR content is filtered out before the agent sees it.
pull_request_target — ⛔ Avoid (public repos) · ☢️ Use with extreme caution (private repos)
- Authz: Same actors as
pull_request.on.roles: allonly with ☢️ extreme caution. - Approval gate: Subject — and this is where it’s most dangerous. Clicking approves all gated workflows with full secrets. Assume the button will always be clicked — by someone trying to approve a different workflow.
- Copilot events:
GITHUB_TOKENdoes not trigger; GitHub App tokens/PATs do. - Runs: On the base ref with full
GITHUB_TOKENand all secrets. Most-exploited vulnerability class2. - Concurrency:
$-$. - Fork guard:
if: $+ gate agent ongithub.event.pull_request.head.repo.fork == false. Never check out PR head SHA. - Sanitize: Yes critically —
steps.sanitized.outputs.text; unsanitized OK within sandboxed agent job coupled with propersafe-outputs. - Alternatives:
schedule,issue_comment/slash_command:,labeled/label_command:. - Integrity filtering:
approved. Fork contributors are typicallyCONTRIBUTORor lower, so their PR content is filtered out before the agent sees it. Does not protect against checking out PR head SHA.
Triggers without standalone pages
These either have low headline risk or are irrelevant to agentic workflows in this repo’s context.
repository_dispatch
- Authz: PAT with
reposcope. - Approval gate: Not subject.
- Copilot events: API-triggered only.
- Runs: With base secrets.
- Unintended: Anyone with the PAT can fire arbitrary
event_typestrings.
Other standard events
branch_protection_rule, check_run, check_suite, create/delete, deployment/deployment_status, fork, gollum, label, member, merge_group, page_build, project*, public, registry_package, status, watch — see the GitHub Events documentation for activity types and default-branch-only flags. These are generally low-risk for agentic workflows: they either require admin-level actions, fire rarely, or have no untrusted-input surface.
| Table of Contents |
-
GitHub Docs, Automatic token authentication ↩
-
GitHub Security Lab, Keeping your GitHub Actions and workflows secure: Preventing pwn requests ↩