Use pull_request to check proposed changes, push to the default branch to record what shipped, schedule to catch new advisories, workflow_dispatch for manual runs and repository_dispatch for events from outside systems. Avoid privileged triggers unless the job truly needs them.
The comparison
| Trigger | Starts when | Runs from | Best security use | Main risk |
|---|---|---|---|---|
| pull_request | A pull request opens or changes | The merge result of the pull request | Gate checks, dependency diff | Forked pull requests get limited secrets |
| push | Commits land on a branch | The pushed branch | Scan after merge, build SBOM | Runs after the fact |
| schedule | A cron time | Latest default branch commit | Rescan for new advisories, weekly report | Delays and silent disabling |
| workflow_dispatch | A person or API call | A chosen branch | Manual rescan, on demand report | Needs access control |
| repository_dispatch | An API call with an event type | Default branch | Advisory feed or ticket events | Untrusted payload |
| pull_request_target | Pull request activity | The base branch | Label and comment automation | Privileged, unsafe with untrusted checkout |
The "runs from" column comes from GitHub's event reference, which states for example that scheduled workflows run on the latest commit of the default branch and that repository_dispatch needs the workflow file on the default branch.
Match trigger to question
Is this change safe to merge? Use pull_request. The result should be a required status check. See vulnerability scan cadence for the combination of triggers.
Did something we already shipped become vulnerable? Code did not change, so no Git event fires. Use schedule or a repository_dispatch driven by an advisory source. See scheduled or event driven scans.
Can I run this by hand when asked? Use workflow_dispatch with declared inputs, so a person picks a repository from a list instead of typing free text.
Does an outside system need to start this? Use repository_dispatch, and validate the payload. See repository_dispatch for security automation.
Fork pull requests
GitHub's documentation notes that for pull requests from a forked repository, events are sent to the base repository, and that a first-time contributor's workflow may need approval from a maintainer. Secrets are generally not passed to workflows from forks on the pull_request trigger, which is why people reach for pull_request_target. That choice moves risk onto you. The hardening guide says workflows with pull_request_target or workflow_run must not explicitly check out untrusted code. If your job only needs to read the diff and post a label, keep it simple and unprivileged.
A default starter set
pull_request: dependency scan and policy check, required.pushto main: generate and store the SBOM.schedule: weekly rescan with an off hour minute.workflow_dispatch: the same scan, runnable by hand.
Add repository_dispatch only when you have a real external event source.
Quick check
Can one workflow use several triggers?
Yes. List them under the on key and use conditions on the event name when behavior differs.
Which trigger finds vulnerabilities published after a merge?
A schedule or an external event through repository_dispatch, since no Git event occurs.
Sources
Safeguard's continuous monitoring and CI policy gates cover both the on change and the after the fact questions. Try the free scan at gold.safeguard.sh/scan.
Last reviewed: 19 October 2026.