Secret Scan action

Last updated: Jun 25, 2026


The SS action detects hardcoded secrets and credentials (API keys, passwords, tokens, and similar sensitive data) in your repository. No account, API key, or registration is required.

Marketplace: fluidattacks/ss-action

Scan modes

The action prefers differential scanning whenever a base commit is available, falling back to a full scan only when there is nothing to compare against. The default branch is detected automatically by running git remote show origin, so any branch name (main, master, trunk, develop, etc.) works without configuration.

TriggerModeBase for comparison
Push to any branchDifferential scanCommit before the push (github.event.before)
Pull requestDifferential scanPR base branch
Scheduled / manual triggerFull scan

Both differential modes compare against a known base commit, not just the previous commit, so all changes in a multi-commit push are analyzed. This keeps CI fast while ensuring nothing slips through.

Setup

1. Create the workflow

Add .github/workflows/secret-scan.yml to your repository:

name: SECRET_SCAN
on:
  push:
  pull_request:
    types: [opened, synchronize, reopened]
  schedule:
    - cron: "0 8 * * 1" # optional: weekly full scan every Monday at 8am

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # required: full history enables differential scanning

      - uses: fluidattacks/ss-action@<version> # Use latest released version
        id: scan

      # Optional: upload findings to the GitHub Security tab
      - name: Upload results to GitHub Security tab
        if: always()
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: ${{ steps.scan.outputs.sarif_file }}
  • fetch-depth: 0 downloads the full git history, which is necessary for the differential scan to resolve the base commit and to detect the default branch via git remote show origin. You can omit it only if you force scanner_mode: full.
  • upload-sarif is optional. When included, run it with if: always() so results are uploaded even when secrets are found.
  • The optional schedule trigger adds a weekly full scan to catch secrets that were already present before you added this workflow.

Without a configuration file, the action scans the entire repository and writes results to .fluidattacks-secret-scan-results.sarif.

2. (Optional) Add a configuration file

To customize scan paths or output format, create a YAML configuration file anywhere in your repository and pass its path to the action via scan_config_path:

- uses: fluidattacks/ss-action@<version>
  id: scan
  with:
    scan_config_path: .github/secret-scan-config.yaml

The 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.

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 and writes results to .fluidattacks-secret-scan-results.sarif.

Only the ss and output keys are used by this action.

ss:
  include:
    - . # paths to scan (default: entire repo)
  exclude:
    - tests/ # paths to skip

output:
  file_path: .fluidattacks-secret-scan-results.sarif
  format: SARIF

ss.include

A list of paths (files or directories) to scan.

  • Full scan: uses this list, defaulting to . (entire repository) if not set.
  • Differential scan: always uses the list of changed files, regardless of this setting.

ss.exclude

A list of paths to exclude from the scan. Applied in both full and differential modes.

output

FieldDefaultDescription
file_path.fluidattacks-secret-scan-results.sarifPath to the results file
formatSARIFOutput format (SARIF or CSV)

Action inputs

InputRequiredDefaultDescription
scan_config_pathNoPath 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_modeNo(auto)Override the scan mode. full forces a full repository scan; diff forces a differential scan. If omitted, the mode is set automatically.

Forcing a full scan

Use scanner_mode: full to scan the entire repository on every run regardless of the trigger. This is useful for scheduled audits:

- uses: fluidattacks/ss-action@main
  id: scan
  with:
    scanner_mode: full

Action outputs

OutputDescription
sarif_fileSARIF results file. Set when format is SARIF, ALL, or path ends in .sarif
vulnerabilities_foundtrue if any secrets 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 "Secrets detected — check the Security tab."

Viewing results

After the workflow runs, findings appear in two places:

  1. GitHub Security tab — Go to your repository → SecurityCode scanning alerts. Each finding shows severity, file location, and the exact line where the secret was detected.
  2. Pull request annotations — On pull requests, findings appear as inline annotations directly in the code diff.

Common scenarios

Scan only specific folders (monorepo)

ss:
  include:
    - services/api/
    - services/web/
  exclude:
    - services/legacy/

Export results as CSV

For common scenarios and troubleshooting, see GitHub Actions.

Troubleshooting

The action doesn't detect my default branch: The action runs git remote show origin to detect the default branch. This requires fetch-depth: 0 in the checkout step so remote metadata is available. If detection fails, verify that the origin remote is correctly configured.

For common scenarios and troubleshooting, see GitHub Actions.

Prerequisites

  • A GitHub repository (public or private).
  • GitHub Actions enabled on the repository.
  • A Linux runner (ubuntu-latest or equivalent) — the action requires Docker, which is only available on Linux-hosted runners.

On this page