SAST vs. Secret Scanning
Last updated: Oct 21, 2026
Two very different techniques can detect a hardcoded credential in your codebase: static application security testing (SAST) and Secret Scanning. Both techniques can give findings with a name like "hardcoded secret". But they answer different questions, analyze different files, and give protection against different types of risk.
This page explains how Fluid Attacks classifies each technique, why you need the two techniques, and how each technique works in practice.
The core distinction
| Dimension | SAST | Secret Scanning |
| What triggers detection | The code shows that a value must be secret:
a constant value goes to PBEKeySpec, a KeyParameter,
an HTTP client constructor, or an authentication parameter.
The destination in the code is the important item. | The value looks like a secret: it has the format of an AWS Access Key, a GitHub token, a JWT, or a PEM block, or it has a high entropy. The shape of the string is the important item. |
| Scope of analysis | Only executable source code (Java, Scala, Python, Go, TypeScript, and more). Program-flow analysis. | All files in the repository:
source code, .env, YAML, JSON, Markdown, notebooks,
and also the commit history.
Content analysis. |
| Question it answers | Did the developer write insecure code around a secret? The root issue is a bad cryptographic or authentication practice. The secret is only a symptom. | Did a credential leak into the repository? The root issue is exposure. The code around the secret is not important. |
In summary: SAST finds secrets by their use. Secret Scanning finds secrets by their shape.
SAST: detection by context
A SAST method reports a finding when a value goes to a security-sensitive sink. The shape of the value is not important. For example, the literal "123" causes a SAST finding if it goes to the wrong location. But a fully random 32-character string does not cause a finding if it is only 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 format that a secrets scanner can recognize,
and no prefix that a secrets scanner identifies.
The finding exists because the value goes to a PBEKeySpec constructor.
This API has only one purpose:
to use 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 pattern that identifies it.
The finding exists because KeyParameter holds a cryptographic key.
Thus,
all values that go to it are keys,
and you must not hardcode keys.
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 call site is the cause of the SAST finding:
boto3.client() accepts credentials as keyword arguments.
The format of the strings is not the cause.
The same rule reports a finding
when the values are clear placeholders
that a secrets scanner does not detect.
Secret Scanning: detection by shape
A secret scanner reports a finding when a string has the format of a known credential. The location of the string is not important. The scanner does not need to understand the language, framework, or call graph around the string. It only needs a file that it can read as text.
Example 1 — AWS Access Key in .env
# .env
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY.env files contain configuration, not source code.
SAST engines do not parse them.
But the AKIA prefix is a fixed identifier for AWS Access Key IDs,
and a secrets scanner identifies it clearly.
Example 2 — GitHub token in a code comment
# TODO: rotate this — ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890
def fetch_repo():
...A SAST engine sees only a comment that has no effect on the program.
A secret scanner sees the ghp_ prefix,
which is the standard marker for a GitHub Personal Access Token.
Thus,
the secret scanner reports a leaked credential,
although the code never uses the value.
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. No program runs or imports this file, and it is not in a program flow. SAST does not apply here. Secret Scanning applies.
When both techniques fire on the same finding
The two techniques can overlap. For example, a real AWS access key that goes directly to a client constructor causes a finding in 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. These are two independent confirmations of the same risk. Each engine gets its result with different logic. Each finding can have its own remediation guidance, severity, and owner.
Why both techniques are necessary
The two techniques complement each other. One technique cannot replace the other.
A program that uses only SAST misses secrets in .env files,
infrastructure manifests, configuration, documentation,
and commit history,
because SAST never reads those files.
A program that uses only Secret Scanning misses hardcoded credentials
with weak values,
placeholder values,
or values without a known format.
This occurs because pattern matching cannot know
that the code uses "changeme" as a real key.
Secret Scanning also misses cryptographic misuse,
where the practice is wrong
but the value is only a string.
Examples are a hardcoded IV, a hardcoded salt,
or a hardcoded HMAC secret without a clear prefix.
When you examine the coverage of a platform, the correct question is not "Does the platform find hardcoded secrets?". The correct question is "Does the platform find secrets by their use and by their shape?". Fluid Attacks uses the two techniques. Each engine reports findings under its own technique. Thus, the root cause and the remediation path are always clear.
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.