Stripe API Key Naming Convention: How Prefixes Like sk_live Work
If you have ever used the Stripe API, you have seen keys like sk_live_51J3... and pk_test_51J3.... These prefixes are not decorative. They encode critical information about key type and environment, prevent entire categories of bugs, and enable automated leak detection across the internet. This convention has become an industry standard that every API provider should adopt.
How Stripe's Prefix System Works
Stripe uses a two-part prefix separated by underscores:
sk_live_EXAMPLE_DO_NOT_USE_1a2b...
│ │
│ └─ Environment: live (production) or test (sandbox)
└──── Key type: sk (secret key) or pk (publishable key)
This gives Stripe four key variants:
| Prefix | Type | Environment | Can charge cards? | Safe for client? |
|---|---|---|---|---|
sk_live_ | Secret | Production | Yes | No |
sk_test_ | Secret | Sandbox | No | No |
pk_live_ | Publishable | Production | No (tokenize only) | Yes |
pk_test_ | Publishable | Sandbox | No | Yes |
A developer can instantly tell, just by looking at the first 8 characters, whether a key is safe to include in client-side code and whether it will affect real customers.
Industry Prefix Standards
Stripe pioneered this pattern, but it has spread across the industry. Here are the most common prefix conventions in use today:
| Service | Prefix | Meaning |
|---|---|---|
| Stripe | sk_live_, sk_test_ | Secret key, environment |
| Stripe | pk_live_, pk_test_ | Publishable key, environment |
| GitHub | ghp_ | Personal access token |
| GitHub | gho_ | OAuth access token |
| GitHub | ghs_ | Server-to-server token |
| GitHub | ghr_ | Refresh token |
| AWS | AKIA | IAM access key |
| AWS | ASIA | Temporary STS credentials |
| Slack | xoxb- | Bot token |
| Slack | xoxp- | User token |
| Twilio | SK | API key SID |
| SendGrid | SG. | API key |
| npm | npm_ | Access token |
| PyPI | pypi- | API token |
Why Prefixes Matter
1. Automated Leak Detection
GitHub's secret scanning, GitGuardian, TruffleHog, and other security tools rely on prefixes to identify leaked credentials in code repositories, chat logs, and public websites. Without a distinctive prefix, your API keys are invisible to these scanners.
When GitHub detects a string matching ghp_[A-Za-z0-9]{36} in a public repository, it automatically notifies GitHub and revokes the token. Stripe receives similar notifications for sk_live_ patterns. This automated detection has prevented millions of credential leaks.
2. Environment Isolation
The most common API key bug is using a production key in a development environment (or vice versa). Prefixes make this visually obvious and programmatically enforceable:
// Server-side validation
function validateApiKey(key, expectedEnv) {
if (expectedEnv === 'production' && key.startsWith('sk_test_')) {
throw new Error('Test key used in production environment');
}
if (expectedEnv === 'test' && key.startsWith('sk_live_')) {
throw new Error('Production key used in test environment');
}
}
With prefixes, your server can reject mismatched keys before they cause damage.
3. Key Type Enforcement
Prefixes prevent developers from using publishable keys where secret keys are required. If a frontend developer accidentally sends a pk_live_ key in an API call that requires server-level permissions, the prefix check rejects it immediately instead of returning a confusing authentication error.
4. Log Readability
When reviewing application logs, server access logs, or error reports, prefixed keys are immediately identifiable. You can tell at a glance whether a log entry involves a test key, a production key, a bot token, or a user token without looking up the key in a database.
5. Routing and Load Balancing
Some systems use key prefixes to route requests to the appropriate backend. A sk_test_ key can be routed to a sandbox environment with test data, while sk_live_ goes to production. This can happen at the load balancer level, before the request even reaches application code.
Designing Your Own Prefix Scheme
If you are building an API, here is a framework for designing effective key prefixes:
Step 1: Choose a Service Identifier
Pick a 2-4 character code that uniquely identifies your service. Check that it does not collide with existing conventions:
// Good: unique, short, memorable
myapp_
acme_
pay_
// Bad: collides with existing services
sk_ // Stripe
gh_ // GitHub
aws_ // Amazon
Step 2: Encode Key Type
Distinguish between different permission levels:
myapp_sk_ // Secret key (full access)
myapp_pk_ // Public key (read-only)
myapp_wh_ // Webhook signing secret
myapp_sa_ // Service account key
Step 3: Encode Environment
Add environment context:
myapp_sk_live_ // Production secret key
myapp_sk_test_ // Sandbox secret key
myapp_sk_dev_ // Development secret key
Step 4: Define the Random Portion
Generate the random portion with at least 256 bits of entropy using a CSPRNG:
function generatePrefixedKey(type = 'sk', env = 'live') {
const prefix = `myapp_${type}_${env}_`;
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
const random = Array.from(bytes)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
return prefix + random;
}
// Output: myapp_sk_live_a3f8c1d9e4b72f6a...
console.log(generatePrefixedKey());
console.log(generatePrefixedKey('pk', 'test'));
Step 5: Document the Pattern
Publish a regex pattern so security tools can detect your keys:
// Pattern for secret scanning tools
myapp_(sk|pk|wh|sa)_(live|test|dev)_[0-9a-f]{64}
You can register this pattern with GitHub's secret scanning partner program so that any key matching your pattern triggers an automatic notification if it appears in a public repository.
Validation Best Practices
class ApiKeyValidator {
static PATTERN = /^myapp_(sk|pk|wh|sa)_(live|test|dev)_[0-9a-f]{64}$/;
static validate(key) {
if (!this.PATTERN.test(key)) {
return { valid: false, error: 'Invalid key format' };
}
const [, type, env] = key.match(/^myapp_(sk|pk|wh|sa)_(live|test|dev)_/);
return {
valid: true,
type,
environment: env,
isSecret: type === 'sk' || type === 'wh',
isProduction: env === 'live'
};
}
}
const result = ApiKeyValidator.validate('myapp_sk_live_a3f8...');
if (result.isProduction && process.env.NODE_ENV !== 'production') {
console.warn('Production key detected in non-production environment');
}
Common Mistakes to Avoid
- Prefix too long. Keep prefixes under 15 characters. Long prefixes waste space and annoy developers.
- No separator character. Use underscores or hyphens between prefix components.
myappskliveis harder to parse thanmyapp_sk_live_. - Counting prefix as entropy. The prefix is public information. Only the random portion contributes to key security.
- Different prefix formats across versions. Once you ship a prefix format, keep it stable. Changing from
myapp_sk_toma_secret_breaks every security scanner configuration. - Forgetting to register with scanning tools. If you do not register your pattern, leaked keys go undetected. Contact GitHub's secret scanning partner program.
Prefixes are one of the rare cases in software engineering where a simple convention provides enormous safety benefits at zero cost. Every API should use them.
Generate prefixed keys instantly with our free API key generator. Select the "Prefixed" format and enter your custom prefix to get started.
Recommended Resources
For the security theory behind key prefixes and authentication, The Web Application Hacker's Handbook covers API security patterns in depth. To understand the cryptographic underpinnings, Real-World Cryptography is an excellent reference.