This guide walks you through migrating from insecure environment variable key storage to HSM-backed key management.
- Choose HSM provider (AWS KMS or Google Cloud KMS)
- Set up HSM key and permissions
- Test in staging environment
- Document rollback procedure
- Schedule maintenance window (minimal downtime)
AWS KMS:
aws kms create-key \
--description "Oracle signing key - Production" \
--key-usage SIGN_VERIFY \
--key-spec ECC_SECG_P256K1 \
--tags TagKey=Environment,TagValue=productionGoogle Cloud KMS:
gcloud kms keys create oracle-signing-key-prod \
--keyring oracle-keys \
--location global \
--purpose asymmetric-signing \
--default-algorithm ec-sign-ed25519AWS:
# Create IAM policy
aws iam create-policy \
--policy-name OracleKMSSigningPolicy \
--policy-document file://docs/iam-policies/aws-kms-policy.json
# Attach to role (EKS/ECS) or user
aws iam attach-role-policy \
--role-name oracle-service-role \
--policy-arn arn:aws:iam::ACCOUNT:policy/OracleKMSSigningPolicyGCP:
# Create service account
gcloud iam service-accounts create oracle-signer-prod \
--display-name "Oracle Signing Service - Production"
# Grant permissions
gcloud kms keys add-iam-policy-binding oracle-signing-key-prod \
--keyring oracle-keys \
--location global \
--member "serviceAccount:oracle-signer-prod@PROJECT.iam.gserviceaccount.com" \
--role roles/cloudkms.signerVerifiercd oracle
# For AWS KMS
npm install @aws-sdk/client-kms
# For Google Cloud KMS
npm install @google-cloud/kms# staging.env
KEY_PROVIDER=aws-kms # or gcp-kms
AWS_REGION=us-east-1
AWS_KMS_KEY_ID=arn:aws:kms:...
# Keep old config as backup
# ORACLE_PRIVATE_KEY=S... # commented out# Update staging deployment
kubectl apply -f k8s/staging/
# Verify logs
kubectl logs -f deployment/oracle -n staging
# Expected log:
# "KeyService initialized with aws-kms provider for address: G..."# Test VRF computation
npm run test:integration
# Test transaction signing
npm run test:e2e
# Monitor for errors
kubectl logs -f deployment/oracle -n staging | grep -i error# Measure signing latency
# Expected: 10-50ms for HSM vs <1ms for env provider
# Load test
# Ensure throughput meets requirements# Save current secrets
kubectl get secret oracle-secrets -n production -o yaml > backup-secrets.yaml
# Save current deployment
kubectl get deployment oracle -n production -o yaml > backup-deployment.yaml# Create new secret with HSM configuration
kubectl create secret generic oracle-secrets-hsm \
--from-literal=key-provider=aws-kms \
--from-literal=aws-region=us-east-1 \
--from-literal=aws-kms-key-id=arn:aws:kms:... \
-n production# k8s/production/deployment.yaml
spec:
template:
spec:
containers:
- name: oracle
env:
- name: KEY_PROVIDER
valueFrom:
secretKeyRef:
name: oracle-secrets-hsm
key: key-provider
- name: AWS_REGION
valueFrom:
secretKeyRef:
name: oracle-secrets-hsm
key: aws-region
- name: AWS_KMS_KEY_ID
valueFrom:
secretKeyRef:
name: oracle-secrets-hsm
key: aws-kms-key-id
# Remove ORACLE_PRIVATE_KEY reference# Apply updated deployment
kubectl apply -f k8s/production/deployment.yaml
# Watch rollout
kubectl rollout status deployment/oracle -n production
# Monitor logs
kubectl logs -f deployment/oracle -n production# Check logs for successful initialization
kubectl logs deployment/oracle -n production | grep "KeyService initialized"
# Monitor for errors
kubectl logs deployment/oracle -n production | grep -i error
# Check metrics
# - Signing operations succeeding
# - No increase in error rate
# - Latency within acceptable range# Verify everything is working
# Monitor for 24-48 hours
# Remove old secret
kubectl delete secret oracle-secrets -n production
# Remove backup files from secure location
rm backup-secrets.yaml- Update deployment docs
- Update runbooks
- Update disaster recovery procedures
- Notify team of changes
If issues occur during migration:
# Restore previous deployment
kubectl apply -f backup-deployment.yaml
# Verify rollback
kubectl rollout status deployment/oracle -n production
# Check logs
kubectl logs -f deployment/oracle -n production# Restore secrets
kubectl apply -f backup-secrets.yaml
# Restore deployment
kubectl apply -f backup-deployment.yaml
# Verify
kubectl get pods -n production
kubectl logs -f deployment/oracle -n productioncd oracle
npm install @aws-sdk/client-kms
# Rebuild Docker image
docker build -t oracle:latest .# Verify IAM permissions
aws kms describe-key --key-id $AWS_KMS_KEY_ID
# Test signing
aws kms sign \
--key-id $AWS_KMS_KEY_ID \
--message-type RAW \
--signing-algorithm ECDSA_SHA_256 \
--message fileb://test-message.bin- Check network connectivity to KMS endpoint
- Verify KMS endpoint is in same region
- Consider caching strategies for high-throughput scenarios
- AWS KMS: 1,200 req/s shared across operations
- GCP KMS: 60,000 req/min
- Implement exponential backoff
- Consider request batching
-
Signing Success Rate
- Should remain at 100%
- Alert if drops below 99.9%
-
Signing Latency
- Expected: 10-50ms (vs <1ms for env provider)
- Alert if exceeds 100ms
-
KMS API Errors
- Monitor for throttling
- Monitor for access denied errors
-
Cost
- Track KMS API usage
- Expected: ~$3 per 1M signatures
Ensure these log entries appear:
✅ "KeyService initialized with aws-kms provider"
✅ "Signed X bytes using AWS KMS"
❌ "AWS KMS signing failed" (should not appear)
Set up alerts for:
- KMS signing failures
- High latency (>100ms)
- Rate limiting errors
- IAM permission errors
After migration, you've achieved:
✅ Private keys never exposed in environment variables ✅ Private keys never stored in memory ✅ All signing operations audited (CloudTrail/Cloud Audit Logs) ✅ Centralized key management ✅ Key rotation capabilities ✅ Compliance with security best practices
-
Enable Key Rotation
# AWS KMS aws kms enable-key-rotation --key-id $AWS_KMS_KEY_ID
-
Set Up Monitoring Dashboard
- KMS API usage
- Signing latency
- Error rates
-
Document Disaster Recovery
- Key backup procedures
- Failover scenarios
- Contact information
-
Regular Security Audits
- Review IAM policies quarterly
- Audit KMS access logs
- Test rollback procedures
For issues during migration:
- Check logs:
kubectl logs -f deployment/oracle - Review KEY_MANAGEMENT.md
- Test in staging first
- Have rollback plan ready