secretsjson
Secrets.json: The Complete Playbook for Secure Secret Management in 2025
Whether you're building a Node.js application, configuring a CI/CD pipeline, or managing environment-sensitive settings for a production service, secrets.json remains one of the most practical approaches to handling sensitive configuration data. This playbook gives you everything you need — from foundational patterns to advanced hardening techniques — so you can stop guessing and start securing your app's credentials once and for all.
What Is secrets.json and Why Does It Matter?
secrets.json is a JSON-formatted configuration file used to store sensitive application data such as API keys, database passwords, OAuth tokens, JWT signing secrets, and cloud provider credentials. Unlike regular config files, a secrets.json is designed to be loaded at runtime and kept out of source repositories.
Frameworks and tools across the JavaScript ecosystem — including NestJS, Express, Next.js, and serverless platforms — commonly reference a secrets.json (or a similarly named file) as the single source of truth for environment-specific credentials.
Common Use Cases
- Storing Stripe API keys and webhook signing secrets for payment services
- Holding AWS Access Key IDs and Secret Access Keys for serverless functions
- Keeping MongoDB connection strings with embedded passwords
- Managing SMTP credentials for transactional email services
- Storing client secrets for OAuth 2.0 / OpenID Connect flows
Building a secrets.json: A Step-by-Step Playbook
Follow this checklist to create a production-ready secrets.json structure that scales across environments.
Step 1 — Define Your Secrets Shape
- Identify every credential your application needs at runtime
- Group secrets by service (e.g.,
database,stripe,aws,smtp) - Name each key descriptively: use
STRIPE_SECRET_KEY, notkey1 - Create a
secrets.schema.jsonto validate your structure programmatically
Step 2 — Write the File
{
"database": {
"connectionString": "mongodb+srv://user:password@cluster.example.com/app",
"poolSize": 10
},
"stripe": {
"secretKey": "sk_live_xxxxxxxxxxxx",
"webhookSecret": "whsec_xxxxxxxxxxxx"
},
"aws": {
"accessKeyId": "AKIAxxxxxxxxxxxx",
"secretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"region": "us-east-1"
},
"jwt": {
"signingSecret": "your-super-secret-jwt-key-min-32-chars"
}
}
Step 3 — Protect the File
- Add
secrets.jsonto.gitignoreas your first action - Create a
secrets.example.jsontemplate with placeholder values for teammates - Set file permissions to
600(chmod 600 secrets.json) on Linux/macOS - Encrypt the repository or use a secrets manager if the file must travel between machines
Step 4 — Load It Safely in Code
// load-secrets.js
const fs = require('fs');
const path = require('path');
function loadSecrets() {
const filePath = path.resolve(__dirname, 'secrets.json');
if (!fs.existsSync(filePath)) {
throw new Error('secrets.json not found. Copy secrets.example.json and fill in values.');
}
const raw = fs.readFileSync(filePath, 'utf8');
return JSON.parse(raw);
}
module.exports = { loadSecrets };
Step 5 — Add Validation and Fallbacks
- Validate every secret exists before the app starts (fail fast)
- Fallback to
process.envfor CI/CD environments where the file is unavailable - Log a warning (never the value) if a secret is missing
- Use a library like
zodorjoi0> for runtime schema validation
secrets.json vs. Alternatives: Which Approach Fits Your Stack?
Choosing the right secret management strategy depends on your team size, deployment model, and compliance requirements. The table below breaks down the most common alternatives.
| Approach | Best For | Security Level | Complexity | Cost |
|---|---|---|---|---|
| secrets.json | Small teams, local dev, solo founders | Medium (file-level protection) | Low | Free |
| .env files | Quick prototypes, simple deployments | Low-Medium (easy to accidentally commit) | Low | Free |
| AWS Secrets Manager | AWS-native apps, enterprise teams | High (encryption at rest, rotation support) | Medium | Per-secret pricing |
| Vault (HashiCorp) | Multi-cloud, compliance-heavy environments | Very High (dynamic secrets, audit logs) | High | Self-hosted free / Cloud paid |
| Azure Key Vault | MICROSOFT Azure workloads | High (HSM-backed, integrated with AAD) | Medium | Per-object pricing |
| GCP Secret Manager | GCP-native applications | High (integrated with IAM) | Low-Medium | Per-secret pricing |
Hardening Checklist: 15 Steps to Secure Your secrets.json
Use this checklist before deploying any application that reads from a secrets.json file.
- [ ]
secrets.jsonis listed in.gitignore - [ ] A
secrets.example.jsontemplate exists with safe placeholder values - [ ] File permissions are set to
600(owner read/write only) - [ ] No secrets are logged to console, stdout, or error trackers
- [ ] A startup validation routine checks every required key before the server listens
- [ ] Environment-specific overrides are supported (dev / staging / prod)
- [ ] Secrets are rotated at least every 9