Security Best Practices
When working with secrets and sensitive data, it's critical to follow security best practices. This guide provides recommendations for using Node SOPS securely in your projects.
Key Management
Protecting the Encryption Key
The .sops-key file is the most critical security component in your Node SOPS setup. Anyone with access to this file can decrypt your secrets.
Do:
- Add
.sops-keyto your.gitignorefile immediately after generating it - Store the key securely outside your repository
- Use different keys for different environments (development, staging, production)
- Rotate keys periodically for enhanced security
Don't:
- Commit the key file to version control
- Share the key through insecure channels (like email or chat)
- Use the same key across multiple projects
Secure Key Sharing
To share the encryption key with team members:
- Use a secure password manager like 1Password, LastPass, or Bitwarden
- Use end-to-end encrypted communication channels
- Consider using a secrets management service for enterprise environments
File Handling
Encrypted Files
Do:
- Commit encrypted files to version control
- Use descriptive file names that indicate they contain encrypted content (e.g.,
secrets.enc.json) - Keep encrypted files organized in a consistent location in your project
Don't:
- Store unencrypted secrets files in the repository
- Log or display decrypted content in your application logs
Temporary Decrypted Files
If you need to temporarily decrypt files during development:
Do:
- Add decrypted files to
.gitignore - Delete decrypted files when you're done with them
- Use the
vieworgetcommands instead of full decryption when possible
Don't:
- Leave decrypted files on disk longer than necessary
- Share decrypted files outside secure channels
Application Security
Environment Variables
When using secrets in your application:
Do:
- Load secrets from encrypted files at application startup
- Use environment variables as an interface to your secrets
- Clear sensitive data from memory when no longer needed
Don't:
- Hard-code secrets in your application code
- Include secrets in client-side code
- Log environment variables that contain secrets
Example: Loading Secrets Securely
const { Sops } = require('node-sops');
// Load secrets early in your application bootstrap
function loadSecrets() {
try {
const sops = new Sops();
const secrets = sops.view('secrets.enc.json');
// Add secrets to process.env
Object.entries(secrets.data).forEach(([key, value]) => {
if (typeof value === 'string') {
process.env[key.toUpperCase()] = value;
} else if (typeof value === 'object') {
Object.entries(value).forEach(([subKey, subValue]) => {
if (typeof subValue === 'string') {
process.env[`${key.toUpperCase()}_${subKey.toUpperCase()}`] = subValue;
}
});
}
});
// The decrypted content is no longer accessible outside this function
// due to JavaScript's garbage collection
} catch (error) {
console.error('Failed to load secrets:', error.message);
process.exit(1); // Exit if secrets cannot be loaded
}
}
CI/CD Integration
When using Node SOPS in continuous integration and deployment pipelines:
Do:
- Store the encryption key in your CI/CD system's secure environment variables or secrets storage
- Decrypt secrets only during the build/deploy process, not in artifacts
- Use different keys for different deployment environments
Don't:
- Store the key in your repository or build scripts
- Output decrypted secrets in build logs
- Use the same key across multiple environments
Example: GitHub Actions Integration
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm ci
- name: Create key file
run: echo "$SOPS_KEY" > .sops-key
env:
SOPS_KEY: ${{ secrets.SOPS_KEY }}
- name: Build with secrets
run: |
# Use the secrets during build
npx node-sops view -i secrets.enc.json -f json > .env.json
npm run build
- name: Clean up
run: rm -f .sops-key .env.json
Team Workflows
Onboarding New Team Members
When onboarding new team members:
- Share the encryption key securely
- Provide clear documentation on how to use Node SOPS in your project
- Establish clear guidelines for creating and modifying secrets
Handling Key Rotation
Periodically rotating encryption keys enhances security:
- Generate a new encryption key
- Decrypt all secret files using the old key
- Re-encrypt them with the new key
- Securely distribute the new key to all team members
- Securely destroy the old key
Production Deployments
For production deployments, consider these additional recommendations:
Do:
- Use a dedicated key for production environments
- Consider using a more robust secrets management solution for production (like AWS Secrets Manager, HashiCorp Vault, etc.)
- Limit access to production keys to essential personnel only
- Audit and log access to production secrets
Don't:
- Use development keys in production
- Store production keys on developer machines
- Automate production key distribution without proper security controls
Additional Security Measures
File Permissions
Set appropriate file permissions on your encryption key file:
# On Unix-based systems (Linux, macOS)
chmod 600 .sops-key
This makes the file readable and writable only by the owner.
Key Backups
Ensure you have a secure backup of your encryption keys. Losing the key means losing access to all encrypted data.
Security Audits
Regularly audit your security practices and ensure all team members are following established guidelines.
Conclusion
Security is a continuous process, not a one-time setup. Regularly review and update your security practices as your project evolves and as new security challenges emerge.