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 | shThis installs the ss binary to /usr/local/bin by default.
Verify the installation
ss --versionQuick scan
To scan a directory or file without a configuration file:
ss scan /path/to/your/projectFindings 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 --strictScan 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.yamlYou cannot combine --config and a path argument in the same command.
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
| Outcome | Meaning | Effect on the finding |
|---|---|---|
active | The provider accepted the secret, so it grants access right now. | Reported. The CVSS vector ends in E:A (attacked). |
inactive | The provider rejected the secret: revoked, expired, or never valid. | Dropped from the results and counted in the scan summary. |
unverifiable | The 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.
In environments without outbound internet access, every verifiable match is
classified as unverifiable. Nothing is dropped, and all findings are
reported with E:U.
Where the outcome appears
- Terminal: only reported findings are listed. The end-of-scan summary includes the number of inactive secrets discarded.
- CSV: the
verifiedcolumn holdsactive,unverifiable, or the reason why the rule has no verifier (see below). Thecvss_v4column carries theE:metric. - SARIF: the
cvss_v4property of each result carries theE: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 value | Reason |
|---|---|
| Not available | No verifier is available for this rule yet. |
| Raw key material | The secret is used locally for encryption or signing; no API request can confirm it. |
| Generic pattern, provider unknown | The pattern matches a shape shared by many providers, so there is no single API to target. |
| Non HTTP protocol | The secret authenticates a non-HTTP protocol, such as a database connection string. |
| Variable endpoint | The service is self-hosted or uses a per-customer host that cannot be derived from the secret. |
| Companion secret required | Checking needs a second value the pattern does not capture, such as an account ID or a request signing key. |
| Checking triggers a side effect | The 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.
Authentication is currently optional and never blocks a scan, but a future release will require it. We recommend adopting it now so your runs are attributed to your 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_TOKENenvironment 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>andssobtains one per run with no stored secret. On GitHub Actions it is fetched automatically; on any other system, expose it as theINTEGRATES_OIDC_TOKENenvironment 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.5Troubleshooting
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