Free, open-source software composition analysis (SCA) action for your GitHub repositories. No account, API key, or registration required to run the scan. Authentication is optional; see Authentication.
Scans your project dependencies for known vulnerabilities automatically on every push and pull request.
Add the file .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: scanReplace <version> with the latest release tag. Check the releases page for the current version and update whenever a new one is published.
Without a configuration file, the action scans the entire repository and writes results to .fluidattacks-sca-results.sarif.
To customize scan paths or output format, create a YAML file anywhere in your repository and pass its path to the action:
- uses: fluidattacks/sca-action@<version>
id: scan
with:
scan_config_path: .github/sca-config.yamlSee Configuration reference for the full list of options.
Commit and push. The scan will run automatically on the next push or pull request.
- A GitHub repository (public or private).
- GitHub Actions enabled on the repository.
- No account, token, or API key is needed to run the scan. The action is 100% open source. Authentication is optional; see Authentication.
Authenticating attributes the run to your Fluid Attacks group and applies the group's platform policy. Supply credentials in one of two ways.
No secret to store. Set the group input (required for OIDC) and grant the job id-token: write:
permissions:
id-token: write
contents: read
jobs:
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: fluidattacks/sca-action@<version>
with:
group: my-groupIn Fluid Attacks, add a trust for issuer https://token.actions.githubusercontent.com with the bound claim repository = my-org/my-repo and enable it for the group. See the OIDC federation guide.
- uses: fluidattacks/sca-action@<version>
with:
api_token: ${{ secrets.FLUID_GROUP_TOKEN }}The token identifies the group by itself, so the group input is not needed. It takes precedence over OIDC.
Authentication is best-effort: if group is missing or invalid for OIDC or no credentials are available (for example, pull requests from forks get neither id-token nor secrets), the action logs a warning and runs the scan unauthenticated.
By default, the action always performs a full scan — it analyzes all dependencies in the repository on every run, regardless of the event or branch.
You can switch to a differential scan with scanner_mode: diff — see Action inputs.
Full scan mode skips all git comparisons, so the default shallow checkout is sufficient. You only need fetch-depth: 0 if you set scanner_mode: diff.
After the workflow runs, results are written to the path configured in output.file_path (e.g. results.sarif), or to .fluidattacks-sca-results.sarif when no configuration file is provided.
The raw SARIF file is always available in your workspace. You can download it as an artifact, process it with other tools, or upload it to a third-party platform.
You can upload the SARIF file to GitHub's Security tab so findings appear as Code scanning alerts with inline PR annotations:
- name: Upload results to GitHub Security tab
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ steps.scan.outputs.sarif_file }}Restrictions: SARIF upload 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. See GitHub's documentation for details.
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:
- .# Language for vulnerability descriptions: EN or ES
language: EN
# If true, the pipeline fails when vulnerabilities are found
strict: false
# Optional: fail only for vulnerabilities at or above this severity
# (low, medium, high or critical)
strictness_threshold: high
output:
# Path where the results file will be written
file_path: results.sarif
# Format: SARIF, CSV, or ALL
format: SARIF
sca:
# Paths to include in the scan (relative to repo root)
include:
- .
# Paths to exclude from the scan
exclude:
- vendor/| Option | Required | Default | Description |
|---|---|---|---|
language |
No | EN |
Language for descriptions (EN or ES) |
strict |
No | false |
Fail the pipeline if vulnerabilities are found. |
strictness_threshold |
No | — | Minimum severity that fails the pipeline: low, medium, high or critical. |
output.file_path |
No | .fluidattacks-sca-results.sarif |
Path for the output file |
output.format |
No | SARIF |
Output format: SARIF, CSV, or ALL |
sca.include |
No | [.] |
List of paths to scan |
sca.exclude |
No | — | List of paths to exclude |
| Input | Required | Default | Description |
|---|---|---|---|
scan_config_path |
No | — | Path to the YAML configuration file, relative to the repository root. When omitted, the action runs with built-in defaults. The job fails if the file does not exist at the given path. |
scanner_mode |
No | full |
Scan mode. full scans the entire repository (default). diff scans only changed files versus the base branch or PR base. |
strict |
No | — | true or false. Breaks the build when vulnerabilities are found. Overrides strict in the configuration file. When omitted, the configuration file decides. See Breaking the build. |
strictness_threshold |
No | — | low, medium, high or critical. Breaks the build only for vulnerabilities at or above this severity. Overrides strictness_threshold in the configuration file. When omitted, the configuration file decides. See Breaking the build. |
group |
No | — | Fluid Attacks group to authenticate as. Required only for OpenID Connect. See Authentication. |
api_token |
No | — | Group token, used when OpenID Connect is not an option. Takes precedence over OIDC. See Authentication. |
Point the action at your configuration file:
- 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.
Scans only the files changed relative to the PR base (on pull requests), the commit before the push (on pushes to the default branch), or the default branch (on pushes to any other branch). Requires fetch-depth: 0 in the checkout step so the action can compare git history.
Diff mode is only active on push and pull_request events. For any other event (e.g. schedule, workflow_dispatch), or when no base commit is available, the action automatically falls back to a full scan.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: fluidattacks/sca-action@<version>
id: scan
with:
scanner_mode: diffBy default the action reports vulnerabilities without failing the job. Two inputs make it fail, and you only need one of them.
Fail on any vulnerability:
- uses: fluidattacks/sca-action@<version>
id: scan
with:
strict: trueFail only on vulnerabilities at or above a severity (low, medium, high or critical):
- uses: fluidattacks/sca-action@<version>
id: scan
with:
strictness_threshold: highstrictness_threshold breaks the build by itself, with or without strict. The scan always reports every vulnerability and fails only on those that reach the threshold.
How the decision is made:
- Unauthenticated runs:
strict: truebreaks the build on any vulnerability, andstrictness_thresholdon those at or above that severity. - Authenticated runs: the minimum CVSS score defined in your group's platform policy also applies. When both a policy and
strictness_thresholdare present, the stricter of the two applies, so the workflow can only make the gate stricter than the platform, never looser. - Precedence: the inputs override
strictandstrictness_thresholdin the configuration file, includingstrict: falseover a file that saystrue. When an input is omitted, the file decides. - Invalid values: a value that is not
true/false(forstrict) or not one oflow,medium,high,critical(forstrictness_threshold, lowercase only) is ignored with a warning, so the configuration file decides.
| Output | Description |
|---|---|
skip |
true when the scan was skipped because a diff run found no changed files, false otherwise |
sarif_file |
Path to the SARIF results file (when format is SARIF or ALL) |
vulnerabilities_found |
true if any vulnerabilities were detected, false otherwise |
Make sure the "Upload SARIF" step is included in your workflow and uses if: always() so it runs even if the scan breaks the build.
Verify that fetch-depth: 0 is set in the actions/checkout step and that scanner_mode: diff is configured.
If strict: true or a strictness_threshold is set (as an action input or in your configuration file), the pipeline fails when the scan finds vulnerabilities, or ones at or above the threshold. This is intentional. Remove them, or raise strictness_threshold, if you want the scan to report vulnerabilities without failing the pipeline. The action input wins over the configuration file.
The path provided to scan_config_path does not exist in the repository. Verify the path is correct and relative to the repository root.