Secrets Management Guide
This guide covers how secrets are managed in the Crypto Inventory Platform, including the encryption master key for platform integrations.
Overview
The platform uses various secrets for different purposes:
- Database credentials: PostgreSQL, Redis, InfluxDB
- JWT secrets: Token signing keys
- Service secrets: API keys, webhook secrets
- Platform integration credentials: AWS, cloud providers, SaaS integrations (encrypted)
Development Environment
Automatic Secret Generation
The development scripts automatically generate and manage secrets:
session-init.sh (Development)
This script automatically generates ENCRYPTION_MASTER_KEY if not set:
# Script checks if ENCRYPTION_MASTER_KEY is set
if [[ -z "${ENCRYPTION_MASTER_KEY:-}" ]]; then
# Generates a secure key using openssl
ENCRYPTION_MASTER_KEY=$(openssl rand -base64 32)
export ENCRYPTION_MASTER_KEY
fi
What it does:
- Generates a secure base64-encoded 32-byte key
- Exports it for the current session
- Sets a default if
opensslis not available
Where it's used:
admin-servicefor encrypting integration credentials- Automatically picked up by
docker-compose.ymlvia${ENCRYPTION_MASTER_KEY}
Manual Setup (Optional)
You can manually set the key in your shell environment:
# Generate a key
export ENCRYPTION_MASTER_KEY=$(openssl rand -base64 32)
# Or add to .env file
echo "ENCRYPTION_MASTER_KEY=$(openssl rand -base64 32)" >> .env
docker-compose.yml Configuration
The admin-service in docker-compose.yml is configured to use the encryption key:
admin-service:
environment:
- ENCRYPTION_MASTER_KEY=${ENCRYPTION_MASTER_KEY}
Behavior:
- Uses
${ENCRYPTION_MASTER_KEY}from environment - Certificate generation scripts will fail if the key is not set (no silent fallback)
- Auth service refuses to start in production if
JWT_SECRETorINTERNAL_AUTH_SECRETuse dev defaults
Security Note (Mar 2026 audit): Dev default fallbacks were removed from all certificate generation scripts and the auth service. Always set
ENCRYPTION_MASTER_KEY,JWT_SECRET, andINTERNAL_AUTH_SECRETto strong random values. Generate with:openssl rand -hex 32
Production Environment
generate-prod-env.sh (Production)
This script automatically generates ENCRYPTION_MASTER_KEY for production:
# Generates secure key
ENCRYPTION_MASTER_KEY=$(openssl rand -base64 32)
What it does:
- Generates a secure random key
- Adds it to
.env.prodwith documentation comments - Includes warnings about using key management services
deploy-aws.sh (Production)
This script validates that ENCRYPTION_MASTER_KEY is set:
if [[ -z "${ENCRYPTION_MASTER_KEY:-}" ]]; then
warn "ENCRYPTION_MASTER_KEY not set in .env.prod"
warn "Platform integration management will be disabled"
warn "For production, use AWS KMS or similar key management service"
fi
What it does:
- Validates key is present before deployment
- Warns if key is missing (does not block deployment)
- Provides guidance on using key management services
Production Best Practices
Option 1: AWS KMS (Recommended)
Setup:
- Create a KMS key in AWS:
aws kms create-key --description "Platform Integrations Encryption Key"
- Store the key ID in AWS Systems Manager Parameter Store:
aws ssm put-parameter
--name "/crypto-inventory/encryption-master-key-id"
--value "<key-id>"
--type "String"
- Update
deploy-aws.shto fetch the key:
# Fetch key from KMS via Systems Manager
KEY_ID=$(aws ssm get-parameter --name "/crypto-inventory/encryption-master-key-id" --query "Parameter.Value" --output text)
ENCRYPTION_MASTER_KEY=$(aws kms decrypt --ciphertext-blob fileb://encrypted_key.bin --key-id $KEY_ID --query Plaintext --output text)
Option 2: HashiCorp Vault
Setup:
- Store the key in Vault:
vault kv put secret/crypto-inventory encryption_master_key="<key>"
- Update deployment scripts to fetch from Vault:
ENCRYPTION_MASTER_KEY=$(vault kv get -field=encryption_master_key secret/crypto-inventory)
Option 3: AWS Secrets Manager
Setup:
- Store the key in Secrets Manager:
aws secretsmanager create-secret
--name crypto-inventory/encryption-master-key
--secret-string "<key>"
- Update deployment scripts to fetch from Secrets Manager:
ENCRYPTION_MASTER_KEY=$(aws secretsmanager get-secret-value
--secret-id crypto-inventory/encryption-master-key
--query SecretString --output text)
Platform Integration Credentials
How Encryption Works
When a platform admin creates an AWS integration:
- User enters credentials in the admin UI (plaintext)
- Frontend sends to backend API
- Backend encrypts sensitive fields (access_key_id, secret_access_key, etc.) using
ENCRYPTION_MASTER_KEY - Encrypted credentials are stored in
platform_integrations.config(JSONB column) - When retrieved, credentials are automatically decrypted
Encryption Details
- Algorithm: AES-256-GCM (authenticated encryption)
- Key Derivation: PBKDF2 (4096 iterations, SHA-256)
- Nonce: Random for each encryption operation
- Sensitive Fields:
access_key_id,secret_access_key,session_token,api_token,api_key,password,client_secret
Security Features
- Encrypted at rest: All credentials stored encrypted in database
- RBAC protected: Only platform admins with
platform.settingspermission can access - Audit logging: All credential changes logged to
platform_integration_audit_log - No plaintext storage: Credentials never stored in plaintext
Migration to Key Management Service
When moving to a 3rd party secrets management service:
Step 1: Export Current Credentials
- Connect to database
- Query all integrations (credentials are encrypted)
- Decrypt with current key
- Store securely for migration
Step 2: Set Up Key Management Service
- Create key in AWS KMS / HashiCorp Vault / etc.
- Store key ID/reference in environment or configuration
- Update deployment scripts to fetch key from service
Step 3: Update Application Code
- Update encryption service to fetch key from management service
- Test with existing encrypted credentials (if key is the same)
- Or re-encrypt all credentials with new key
Step 4: Deploy and Verify
- Deploy updated code
- Test integration creation/retrieval
- Verify credentials are encrypted/decrypted correctly
- Monitor audit logs for any issues
Troubleshooting
"Platform integration management will be disabled" Warning
Problem: ENCRYPTION_MASTER_KEY is not set.
Solution:
- Development: Run
session-init.sh(automatically generates key) - Production: Set
ENCRYPTION_MASTER_KEYin.env.prodor key management service - Restart
admin-servicecontainer
"Failed to encrypt config" Error
Problem: Encryption service failed to initialize.
Possible Causes:
ENCRYPTION_MASTER_KEYis empty- Key derivation failed
- Key management service unavailable
Solution:
- Verify
ENCRYPTION_MASTER_KEYis set and not empty - Check service logs for detailed error messages
- Verify key management service is accessible (if using one)
Cannot Decrypt Existing Credentials
Problem: Error decrypting credentials after key change.
Cause: The encryption master key was changed, but existing credentials were encrypted with the old key.
Solution:
- DO NOT change the encryption key if you have existing integrations
- If you must change the key:
- Export all integration credentials (decrypt with old key)
- Update encryption key
- Re-create all integrations (encrypt with new key)
- Or implement a key rotation mechanism
Prevention: Use a key management service that handles key rotation automatically (AWS KMS, HashiCorp Vault, etc.)
Related Documentation
- Platform Integrations Setup – Detailed integration configuration guide
- Security Architecture – Overall security design
- AWS Cost Explorer Setup – AWS-specific integration setup
Future Enhancements
Planned Features
- AWS KMS Integration – Direct integration with AWS KMS for key management
- Key Rotation – Automatic key rotation without downtime
- Multi-Key Support – Support for multiple encryption keys (for migration)
- Credential Rotation – Automated credential rotation for integrations
- HashiCorp Vault Integration – Direct integration with HashiCorp Vault
- Azure Key Vault Integration – Direct integration with Azure Key Vault