SCA action
Last updated: Apr 21, 2026
The SCA action runs Fluid Attacks' software composition analysis scanner in your GitHub Actions workflows, detecting known vulnerabilities in your third-party dependencies by checking package manifests against the Fluid Attacks vulnerability database.
Marketplace: fluidattacks/sca-action
Scan modes
By default the action always runs a full scan, regardless of the workflow trigger.
Differential scanning must be opted into explicitly via the scanner_mode input.
Trigger / scanner_mode | Mode | What is scanned |
|---|---|---|
| Any trigger (default) | Full scan | All dependencies in the repository |
scanner_mode: diff on a PR | Differential scan | Only changed files relative to the PR base branch |
scanner_mode: diff otherwise | Differential scan | Only changed files relative to the default branch |
The scanner detects dependency files automatically:
package.json, pom.xml, *.csproj, requirements.txt, and more.
Note: In differential mode, if no dependency files changed, the scan is skipped and no output file is produced. This is expected behavior, not an error.
Setup
1. Create the workflow
Add .github/workflows/sca.yml to your repository:
name: SCA
on:
push:
pull_request:
types: [opened, synchronize, reopened]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: fluidattacks/sca-action@<version>
id: scan
# Optional: upload findings to the GitHub Security tab
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ steps.scan.outputs.sarif_file }}Replace
<version>with the latest release tag. Find it on the Marketplace page.
upload-sarifis optional. When included, run it withif: always()so results are uploaded even when the scan step exits with a non-zero code (e.g., whenstrict: true).
Restriction: Uploading to the Security tab requires GitHub Advanced Security, which is available on all public repositories and on private repositories under a GitHub Advanced Security license. On private repositories without that license, the upload step will fail.
Without a configuration file, the action scans the entire repository and writes results
to .fluidattacks-sca-results.sarif.
2. (Optional) Add a configuration file
To customize scan paths, output format, or strict mode,
create a YAML configuration file anywhere in your repository
and pass its path to the action via scan_config_path:
- uses: fluidattacks/sca-action@<version>
id: scan
with:
scan_config_path: .github/sca-config.yamlThe path is relative to the repository root. The job fails immediately if the file does not exist at the given path.
3. Push and run
Commit the workflow file and push. The scan runs automatically on the next push or pull request.
Configuration
When scan_config_path is provided, the action uses that file exclusively.
When omitted, the action runs with built-in defaults:
scans the entire repository (sca.include: [.]) and writes results to .fluidattacks-sca-results.sarif.
language: EN
strict: false
output:
file_path: results.sarif
format: SARIF
sca:
include:
- .
exclude: # Optional: paths to exclude from scanning
- vendor/language— language for vulnerability descriptions in the output (ENfor English,ESfor Spanish).strict— whenfalse, the scanner reports findings but does not fail the pipeline. Set totrueto break the build on any detected vulnerability.output.file_path— use a distinct name (e.g.,results-sca.sarif) to avoid overwriting the SAST results file if both scanners run in the same workspace. When format isSARIForALL, this path is also exposed as thesarif_fileaction output.output.format—SARIFproduces the standard format consumed by GitHub's code scanning API. UseCSVfor a spreadsheet-friendly report, orALLto generate bothresults-sca.sarifandresults-sca.csv.sca.include— list of paths the scanner searches for dependency manifests. A single.means the entire repository.sca.exclude— optional list of paths to skip.
Action inputs
| Input | Required | Default | Description |
|---|---|---|---|
scan_config_path | No | — | Path to the YAML configuration file, relative to the repository root. When omitted, built-in defaults are used. The job fails if the file does not exist. |
scanner_mode | No | full | Set to diff to run a differential scan (changed files only). Omit or set to full for a full scan. |
Running a differential scan
Use scanner_mode: diff to scan only the files that changed relative to the default branch
(or the PR base branch on pull requests).
Remember to set fetch-depth: 0 in the checkout step so git history is available:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: fluidattacks/[email protected]
id: scan
with:
scanner_mode: diffAction outputs
| Output | Description |
|---|---|
sarif_file | Path to the SARIF results file (only set when output.format is SARIF or ALL) |
vulnerabilities_found | true if any vulnerabilities were detected, false otherwise |
You can use these outputs in subsequent workflow steps:
- name: Comment on PR
if: steps.scan.outputs.vulnerabilities_found == 'true'
run: echo "Vulnerable dependencies detected — check the Security tab."Common scenarios
Monorepo: scan only specific folders
sca:
include:
- services/api/
- services/web/
exclude:
- services/legacy/Use this option if you use the scanner mode full, but you wish to only analyze certain directories.
Strict mode: block merges with vulnerable dependencies
Set strict: true in your configuration file and enable Require status checks to pass before merging
in your repository's branch protection settings.
strict: trueExport results as CSV
output:
file_path: results-sca.csv
format: CSVTroubleshooting
No results appear in the Security tab
Make sure the upload step uses if: always() so it runs even when the scan finds vulnerabilities
with strict: true.
Differential scan analyzes all files instead of just changes
Verify that fetch-depth: 0 is set in the actions/checkout step and that scanner_mode: diff
is explicitly passed to the action. Without both, the action runs a full scan.
The pipeline fails unexpectedly
If strict: true is set, the pipeline fails whenever vulnerabilities are found.
Set strict: false to report findings without failing the pipeline.
The job fails with "not found in repository"
The path provided to scan_config_path does not exist in the repository.
Verify the path is correct and relative to the repository root.
See the Marketplace page for all configuration options and additional troubleshooting.