Secret management
Skill VersoXBT/claude-initial-setup/skills/security/secret-management
Manage secrets, API keys, and sensitive configuration securely. Activate whenever the user handles API keys, passwords, tokens, database credentials, .env files, CI/CD pipelines, or any configuration that contains sensitive values. Also activate when the user asks about secret rotation, vault integration, or gitignore setup.From its SKILL.md
npx -y skills add VersoXBT/claude-initial-setup --skill secret-managementAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.0 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Secret Management
Secure handling of API keys, passwords, tokens, and sensitive configuration across development, CI/CD, and production environments. Never hardcode secrets; always use environment variables, secret managers, or vault solutions.
When to Use
- Setting up a new project that needs API keys or database credentials
- Configuring CI/CD pipelines with secrets
- Reviewing code that may contain hardcoded secrets
- Setting up .env files and .gitignore
- Integrating with secret management services (Vault, AWS Secrets Manager)
- Rotating compromised or expired credentials
Core Patterns
Environment Variables and .env Files
Use .env files for local development, never commit them to version control.
# .env (NEVER committed to git)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxx
JWT_SECRET=your-256-bit-secret-here
REDIS_URL=redis://localhost:6379
# .env.example (committed to git, no real values)
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
OPENAI_API_KEY=sk-proj-your-key-here
JWT_SECRET=generate-a-secure-random-string
REDIS_URL=redis://localhost:6379
# .gitignore - ALWAYS include these
.env
.env.local
.env.*.local
*.pem
*.key
credentials.json
service-account.json
Loading and Validating Secrets
Always validate that required secrets exist at startup, not at first use.
import { z } from 'zod';
import dotenv from 'dotenv';
dotenv.config();
const envSchema = z.object({
DATABASE_URL: z.string().url(),
OPENAI_API_KEY: z.string().startsWith('sk-'),
JWT_SECRET: z.string().min(32),
NODE_ENV: z.enum(['development', 'staging', 'production']),
PORT: z.coerce.number().default(3000),
});
function loadConfig() {
const result = envSchema.safeParse(process.env);
if (!result.success) {
const missing = result.error.issues.map(i => i.path.join('.'));
throw new Error(`Missing or invalid env vars: ${missing.join(', ')}`);
}
return result.data;
}
export const config = loadConfig();
# Python equivalent with Pydantic
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
openai_api_key: str
jwt_secret: str
debug: bool = False
class Config:
env_file = ".env"
settings = Settings()
HashiCorp Vault Integration
Use Vault for production secret management with automatic rotation.
import Vault from 'node-vault';
const vault = Vault({
apiVersion: 'v1',
endpoint: process.env.VAULT_ADDR,
token: process.env.VAULT_TOKEN,
});
async function getSecret(path: string): Promise<string> {
try {
const result = await vault.read(`secret/data/${path}`);
return result.data.data.value;
} catch (error) {
throw new Error(`Failed to read secret at ${path}: ${error.message}`);
}
}
// Usage
const dbPassword = await getSecret('production/database');
CI/CD Secret Configuration
Configure secrets in CI/CD without exposing them in logs or artifacts.
# GitHub Actions - use repository secrets
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
run: |
# Never echo secrets
npm run deploy
# WRONG: This exposes secrets in logs
# - run: echo ${{ secrets.API_KEY }}
# WRONG: This exposes secrets in artifacts
# - run: env > debug.txt
# GitLab CI - use protected variables
deploy:
stage: deploy
variables:
DATABASE_URL: $DATABASE_URL # Set in GitLab CI/CD settings
script:
- npm run deploy
only:
- main
Secret Rotation
Implement graceful secret rotation without downtime.
interface SecretProvider {
getCurrent(): Promise<string>;
getPrevious(): Promise<string | null>;
}
// Accept both current and previous secrets during rotation window
async function validateApiKey(
key: string,
provider: SecretProvider
): Promise<boolean> {
const current = await provider.getCurrent();
if (key === current) return true;
const previous = await provider.getPrevious();
if (previous && key === previous) return true;
return false;
}
// Rotate JWT secrets gracefully
function verifyToken(token: string): JwtPayload {
try {
return jwt.verify(token, config.JWT_SECRET) as JwtPayload;
} catch {
if (config.JWT_SECRET_PREVIOUS) {
return jwt.verify(token, config.JWT_SECRET_PREVIOUS) as JwtPayload;
}
throw new Error('Invalid token');
}
}
Anti-Patterns
- Hardcoding secrets directly in source code (
const apiKey = "sk-...") - Committing .env files to version control
- Logging secret values, even in debug mode
- Passing secrets as command-line arguments (visible in process listings)
- Storing secrets in frontend/client-side code (always exposed to users)
- Using the same secrets across all environments (dev, staging, production)
- Sharing secrets via Slack, email, or other unencrypted channels
- Not rotating secrets after team member departure or suspected compromise
Quick Reference
| Context | Solution |
|---|---|
| Local development | .env files + dotenv, validated at startup |
| CI/CD pipelines | Platform secret storage (GitHub Secrets, GitLab Variables) |
| Production | Vault, AWS Secrets Manager, GCP Secret Manager |
| Rotation | Dual-key acceptance window, then revoke old key |
| Frontend | Never store secrets; proxy through backend API |
| Git protection | .gitignore, pre-commit hooks, git-secrets scanner |
| Validation | Zod/Pydantic schema at app startup |
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most project setup skills give in ~1.3k tokens
Counted across 1,553 of the 3,091 authors here whose files we hold, read 2026-09-06
- Write the configuration filein 36 of 1553
- Create the directory structurein 35 of 1553, across 33 files
- Verify the setupin 31 of 1553, across 28 files
- Run the setup scriptin 30 of 1553, across 29 files
- Pre-determine the required sample sizein 29 of 1553, across 12 files
- Check if the configuration already existsin 29 of 1553
- Document every testin 26 of 1553, across 10 files
- Start with a hypothesisin 26 of 1553, across 11 files
- Ask one question at a timein 22 of 1553
- Test a single variable per testin 21 of 1553, across 9 files
- Read product marketing context before asking questionsin 19 of 1553, across 8 files
- Do not peek and stop earlyin 18 of 1553, across 7 files
Said here and by no other author read
- Use .env files for local development
- Validate required secrets at startup
- Configure secrets in CI/CD without exposing them
- Implement graceful secret rotation
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.