ss

Last updated: Sep 9, 2026


ss is Fluid Attacks' native binary for secrets detection. It scans your source code for hardcoded credentials, API keys, tokens, and similar sensitive data. When a detection rule ships a verifier, ss also checks with the provider whether the secret is still active, so you can focus on the credentials that grant access today. Unlike the Docker-based scanners, ss is a single self-contained binary that runs without Docker. By default it runs without authenticating; you can optionally authenticate to attribute runs to your Fluid Attacks group.

Installation

Linux and macOS

Run the one-line installer:

curl -fsSL https://public.fluidattacks.com/ss/install.sh | sh

This installs the ss binary to /usr/local/bin by default.

Verify the installation

ss --version

Quick scan

To scan a directory or file without a configuration file:

ss scan /path/to/your/project

Findings are printed directly to the terminal. Use --strict to exit with code 1 when secrets are found, which is useful for blocking CI/CD pipelines:

ss scan /path/to/your/project --strict

Scan with a configuration file

For more control over paths, output format, and scan behavior, pass a YAML configuration file with --config:

ss scan --config ss-config.yaml

Secret verification

Many detection rules ship a verifier: a description of the provider's API request that tells whether a secret is still valid. When a match belongs to one of these rules, ss sends that request during the scan and classifies the secret by the answer. Verification runs automatically in both quick scans and configuration file scans. It needs no configuration change and has no option to disable it.

For each match, ss sends a single request to the provider that issued the secret, for example, the Google APIs discovery service for a GCP API key, using only the detected value. The request times out after five seconds and never follows redirects. The secret value is never printed or written to logs.

Verification outcomes

OutcomeMeaningEffect on the finding
activeThe provider accepted the secret, so it grants access right now.Reported. The CVSS vector ends in E:A (attacked).
inactiveThe provider rejected the secret: revoked, expired, or never valid.Dropped from the results and counted in the scan summary.
unverifiableThe provider could not be reached or answered in an unexpected way.Reported as a regular finding. The CVSS vector ends in E:U.

E: is the exploit maturity metric of the CVSS v4.0 vector. E:A (attacked) marks a secret confirmed to work, while E:U (unreported) marks one that could not be confirmed. Findings from rules without a verifier are always reported with E:U.

Because inactive secrets are dropped before the results are written, they do not count toward --strict, so a pipeline is blocked only by secrets that are active or could not be verified.

Where the outcome appears

  • Terminal: only reported findings are listed. The end-of-scan summary includes the number of inactive secrets discarded.
  • CSV: the verified column holds active, unverifiable, or the reason why the rule has no verifier (see below). The cvss_v4 column carries the E: metric.
  • SARIF: the cvss_v4 property of each result carries the E: metric.

Rules without a verifier

Not every secret can be checked with an HTTP request. When a rule has no verifier, the verified column of the CSV report explains why:

verified valueReason
Not availableNo verifier is available for this rule yet.
Raw key materialThe secret is used locally for encryption or signing; no API request can confirm it.
Generic pattern, provider unknownThe pattern matches a shape shared by many providers, so there is no single API to target.
Non HTTP protocolThe secret authenticates a non-HTTP protocol, such as a database connection string.
Variable endpointThe service is self-hosted or uses a per-customer host that cannot be derived from the secret.
Companion secret requiredChecking needs a second value the pattern does not capture, such as an account ID or a request signing key.
Checking triggers a side effectThe only way to probe validity would perform a real action, such as sending a message or starting a pipeline.

Authenticate (optional)

By default, ss runs without authenticating. You can optionally authenticate so runs are attributed to your Fluid Attacks group.

Running it yourself, on your own machine? Sign in through your browser instead — ss login once, and nothing to store.

Authenticate with your group's Group token, supplied either way:

  • Long-lived secret: set the INTEGRATES_API_TOKEN environment variable to a Group token from Organization → Groups → GroupName → DevSecOps → Manage token in the platform.
  • Short-lived, via OIDC: from any system that can issue OpenID Connect tokens (CI/CD, AWS, GCP, Kubernetes, and more), pass --group <your-group> and ss obtains one per run with no stored secret. On GitHub Actions it is fetched automatically; on any other system, expose it as the INTEGRATES_OIDC_TOKEN environment variable.

If both are set, the stored secret takes precedence.

See Authentication for the full guide (including OIDC federation setup), and CI/CD integration for pipeline examples.

The token is used only to identify the caller; it is never printed or written to logs.

Common scenarios

Scan only specific directories (monorepo)

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

Block the pipeline on findings

For pipeline gating with strict mode, see Distributed binaries.

Reduce false positives

Raise min_entropy to filter out low-entropy tokens:

ss:
  include:
    - .
  min_entropy: 3.5

Troubleshooting

For common installation troubleshooting (permission denied, PATH issues), see Distributed binaries.

Too many false positives

Raise the min_entropy threshold in your configuration file. Start at 3.5 and adjust upward until the noise is acceptable.

A known secret is not reported

If ss finds a secret and the provider reports it as inactive, the finding is dropped from the results and counted in the scan summary as an inactive secret. The value still appears in your source code, so remove it and rotate any related credentials.

No output file is produced

Verify that output.file_path is set in your configuration file and that the extension is .sarif or .csv. Any other extension causes an error.

Cannot use '--config' and a path together

--config and a positional path argument are mutually exclusive. Use one or the other:

# Config file mode
ss scan --config ss-config.yaml

# Quick scan mode
ss scan /path/to/project

On this page