VNX-LLM-003: Hardcoded LLM API key
Reports Anthropic, OpenAI and Groq API keys by their prefixes, and high-entropy literals assigned to LLM-provider key variables or passed to provider clients; placeholders and environment lookups are ignored.
| Field | Value |
|---|---|
| Rule ID | VNX-LLM-003 |
| Severity | Critical |
| SARIF level | error |
| Kind | secrets |
| Languages | Any file |
| CWE | CWE-798 |
| CAPEC | CAPEC-191 |
| ATT&CK | T1552.001 |
| CWSS vector | CWSS:1.0/TI:C/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:C/DI:H/EX:H/EC:N/P:W |
| Tags | secrets llm ai-security credentials |
| Source | internal/sast/rules/vnx-llm-003.rego |
Overview
An LLM provider API key, such as an OpenAI key (sk-), an Anthropic key (sk-ant-), or a similar credential, is hardcoded as a string literal in source code or configuration. Hardcoded keys are committed to version control and can be exposed through repository leaks, logs, or build artifacts, allowing anyone who discovers the key to consume your quota or access your data.
Why This Matters
LLM API keys are credentials with real monetary value. A leaked OpenAI key can be used to run expensive inference jobs at your cost, access fine-tuned models, retrieve embeddings from your data, or abuse your usage tier. Attackers actively scan GitHub for exposed keys and begin exploiting them within minutes of exposure. Unlike database passwords, API keys for LLM services are often directly monetizable without any further lateral movement.
What Gets Flagged
Anthropic (sk-ant-api03-...), OpenAI project/service-account/admin (sk-proj-, sk-svcacct-, sk-admin-) and classic (sk-...T3BlbkFJ...) keys anywhere in a file, and a high-entropy literal assigned to a provider-named key variable or passed as api_key/apiKey to a provider client.
# FLAGGED: OpenAI project key passed to the client
client = OpenAI(api_key="sk-proj-<64 random characters>")
# FLAGGED: Anthropic key in a committed .env file
ANTHROPIC_API_KEY=sk-ant-api03-<93 random characters>AA
// FLAGGED: provider-named key constant
export const COHERE_API_KEY = "<40 random characters>";
Not flagged: keys read from the environment (os.environ["OPENAI_API_KEY"]), placeholders (sk-your-openai-api-key-here, sk-ant-xxxx..., REPLACE_WITH_...), sk- inside longer identifiers (task-, desk-), and test or fixture paths.
Remediation
- Remove hardcoded keys from all source files and git history.
- Rotate any exposed keys immediately via the provider’s dashboard.
- Load credentials from environment variables or a secrets manager.
- Add key patterns to your
.gitignoreand pre-commit hooks.
# SAFE: load key from environment variable
import os
client = openai.OpenAI(api_key=os.environ["OPENAI_API_KEY"])
References
- CWE-798: Use of Hard-coded Credentials
- OpenAI – Best Practices for API Key Safety
- OWASP – Hardcoded Passwords
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-llm-003
// nosec vnx-llm-003
Or record an ignore rule: vulnetix ignore add --rule vnx-llm-003 --reason "...". See Suppressing findings.