Use a reusable workflow when the shared logic needs several jobs, its own runner type, or secrets. Use a composite action when you want to bundle a few steps inside a job the caller already controls. For most security scan templates, a reusable workflow is the better fit.
The difference in one table
This comparison follows the GitHub documentation on avoiding duplication.
| Aspect | Reusable workflow | Composite action |
|---|---|---|
| Unit | Workflow file with jobs | Action with steps only |
| Called from | A job (uses at job level) | A step inside a job |
| Secrets | Can use secrets | Cannot use secrets directly |
| Runner | Each job picks its own | Runs on the caller job machine |
| Logs | Each job and step logged separately | Shown as one step |
| Marketplace | Cannot be published | Can be published |
| Nesting | Up to ten levels | Up to ten composite actions in a workflow |
Which one fits a security scan
A scan job often needs a token to upload results or fetch policy, and it may need a larger runner than the build. Both points favour a reusable workflow. The separate job also makes the scan visible as its own check, which is handy when you later require it before merge.
A composite action fits small helpers: set up the CLI, add a step that comments on the pull request, or format output. The caller keeps control of ordering, and you can add steps before and after.
Passing secrets safely
With reusable workflows, the caller passes secrets with secrets: or inherits them with secrets: inherit. The docs say inherit is meant for workflows in the same organization or enterprise. Secrets pass one level down only, so a middle workflow must forward what a child needs. If you forget, an environment secret resolves to an empty string with no error, so test the failure case.
Prefer short lived credentials from OIDC over stored keys where your cloud supports it.
Pin what you call
Callers reference owner/repo/.github/workflows/file.yml@ref. The ref can be a SHA, tag, or branch. The docs call the SHA the safest option for stability and security. For an internal template, many teams use a tag they control and protect tag creation, then let a bot propose upgrades.
A simple decision path
- Does the logic need more than one job or secrets? Reusable workflow.
- Does the caller need to add steps around it in the same job? Composite action.
- Will outside projects use it? Composite action, since it can be published.
- Unsure? Start with a reusable workflow and extract helpers later.
Try it yourself
The demo shows a pull request check from the point of view of a developer. Notice that the scan appears as its own named result you could require.
Click through it at your own pace, or open it full screen.
Quick check
Can a composite action use repository secrets?
Not directly. The documentation lists that as a difference. The caller can pass a value in as an input, but a reusable workflow is the cleaner route when secrets are central.
How deep can reusable workflows nest?
Up to ten levels, counting the top level caller plus up to nine levels of reusable workflows. Keep it to one or two for readability.
Safeguard runs as a CLI step in pipelines, so it works inside either approach.
Sources
- GitHub Docs: Reuse workflows, fetched 19 October 2026
- GitHub Docs: Avoiding duplication, fetched 19 October 2026
Last reviewed: 19 October 2026.