SAST vs. Secret Scanning
Last updated: May 19, 2026
A hardcoded credential in your codebase can be detected by two fundamentally different techniques: static application security testing (SAST) and Secret Scanning. Both produce findings that may be summarized as "hardcoded secret" or similar, but they answer different questions, analyze different files, and protect against different categories of risk.
This article explains how Fluid Attacks classifies each, why both are needed, and what each looks like in practice.
The core distinction
| Dimension | SAST | Secret Scanning |
| What triggers detection | The code reveals that a value must be secret:
a constant flow into PBEKeySpec, a KeyParameter,
an HTTP client constructor, an authentication parameter.
The destination in code is what matters. | The value looks like a secret: it matches the format of an AWS Access Key, a GitHub token, a JWT, a PEM block, or has sufficiently high entropy. The shape of the string is what matters. |
| Scope of analysis | Executable source code only (Java, Scala, Python, Go, TypeScript, etc.). Program-flow analysis. | Any file in the repository:
source code, .env, YAML, JSON, Markdown, notebooks,
even commit history.
Content analysis. |
| Question it answers | Did the developer write insecure code around a secret? The root issue is poor cryptographic or authentication practice; the secret itself is a symptom. | Did a credential leak into the repository? The root issue is exposure; the surrounding code is irrelevant. |
In one line: SAST catches secrets by their use. Secrets Scanning catches them by their shape.
SAST: detection by context
A SAST method fires when a value reaches a security-sensitive sink, regardless of what the value looks like. The literal "123" will trigger a SAST finding if it lands in the wrong place. A perfectly random 32-character string will not, if it sits inert in a comment.
Example 1 — Hardcoded password in PBEKeySpec (Java/Scala)
import javax.crypto.spec.PBEKeySpec
val keySpec = new PBEKeySpec("myPassword".toCharArray)The string "myPassword" has no entropy,
no recognizable format, and no prefix that any secrets scanner would flag.
The finding exists because the value flows into a PBEKeySpec constructor
— an API whose entire purpose is to consume a secret.
Example 2 — Hardcoded KeyParameter (Scala, Bouncy Castle)
import org.bouncycastle.crypto.params.KeyParameter
val key = new KeyParameter(Array[Byte](0x01, 0x02, 0x03, 0x04))The byte array has no telltale pattern.
The finding exists because KeyParameter is a cryptographic key holder;
anything passed to it is, by definition, a key that should not be hardcoded.
Example 3 — Credentials in an SDK client constructor (Python)
import boto3
s3 = boto3.client(
"s3",
aws_access_key_id="placeholder",
aws_secret_access_key="changeme",
)The SAST finding is justified by the call site — boto3.client()
accepting credentials as keyword arguments
— not by the format of the strings.
The same rule fires even when the values are obvious placeholders
that no secrets scanner would catch.
Secret Scanning: detection by shape
A secret scanner fires when a string matches a known credential pattern, regardless of where it appears. It does not need to understand the surrounding language, framework, or call graph. It only needs the file to be readable as text.
Example 1 — AWS Access Key in .env
# .env
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY.env files are configuration, not source code;
SAST engines do not parse them.
But the AKIA prefix is a fixed identifier for AWS Access Key IDs
and is unambiguous to a secrets scanner.
Example 2 — GitHub token in a code comment
# TODO: rotate this — ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890
def fetch_repo():
...A SAST engine sees an inert comment with no program effect.
A secret scanner sees the ghp_ prefix
— the canonical marker for a GitHub Personal Access Token
— and reports a leaked credential,
even though the value is never used by the code.
Example 3 — Private key embedded in documentation
## Local setup
To connect to the staging cluster, paste this into `~/.ssh/staging_key`:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
-----END RSA PRIVATE KEY-----The file is documentation. It is never executed, never imported, never reachable from any program flow. SAST has no jurisdiction here. Secret Scanning does.
When both techniques fire on the same finding
There is a legitimate overlap zone. A real AWS access key passed directly to a client constructor will be detected by both engines:
boto3.client(
"s3",
aws_access_key_id="AKIAIOSFODNN7EXAMPLE",
aws_secret_access_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
)- SAST reports: Hardcoded credential passed to AWS SDK client.
- Secret Scanning reports: AWS Access Key ID pattern detected in source file.
This is not duplication. It is two independent confirmations of the same risk, arrived at through different reasoning. Each finding may carry distinct remediation guidance, severity, and ownership.
Why both techniques are necessary
The two are complementary and not interchangeable.
A SAST-only program misses secrets that live in .env files,
infrastructure manifests, configuration, documentation,
and commit history — because SAST never reads those files.
A Secret-Scanning-only program misses hardcoded credentials
whose values are weak, placeholder-shaped,
or otherwise lack a recognizable format
— because pattern matching cannot infer that "changeme" is being used
as a real key.
It also misses cryptographic misuse where the practice is wrong
even when the value is, technically, just a string
(e.g., a hardcoded IV, a hardcoded salt,
a hardcoded HMAC secret without an obvious prefix).
When evaluating coverage, the right question is not "does the platform find hardcoded secrets?" — it is "does the platform find secrets through use and through shape?" Fluid Attacks runs both, and each engine reports findings under its own technique so that the root cause and remediation path remain unambiguous.
What is CSPM?
Fluid Attacks' CSPM scanner detects misconfigurations and security issues in cloud environments, IaC scripts, and container images through automated cloud security posture management.
Tutorial videos
Watch tutorial videos to learn to use the Fluid Attacks platform and CI Agent for vulnerability management in favor of the security of your applications.