WhollySoftware
Back to blogBackend

Getting Secrets Out of Code: A Practical Migration to a Secrets Manager

Wholly Software TeamSeptember 12, 20246 min read
Getting Secrets Out of Code: A Practical Migration to a Secrets Manager

The audit that triggered this was mundane: a client wanted a security review before a funding round. We ran a secret scanner against their full git history and found eleven live credentials, including a Stripe key committed in 2022 that had never been rotated. None of this was negligence exactly — it's just what happens when '.env' files get copy-pasted between environments for three years.

We moved everything to AWS Secrets Manager, since the client was already on AWS and it integrates cleanly with ECS task definitions via secret ARNs injected as environment variables at container start. For a smaller client on a single VPS the same year, we used Doppler instead — less infrastructure to stand up, and their team of four didn't need Secrets Manager's IAM complexity.

The migration itself was the easy part. The hard part was habits: developers pulling a secret once and hardcoding it locally 'just for now,' or pasting a database password into a Slack thread when debugging. We added a pre-commit hook running gitleaks and wired it into CI as a blocking check, which caught four more accidental commits in the first month alone.

One decision we debated was rotation cadence. We settled on 90-day automatic rotation for database credentials using Secrets Manager's native rotation Lambdas, but left third-party API keys (Stripe, Twilio) on manual rotation since automating those requires provider-specific coordination that wasn't worth building for keys used by two services.

The remaining friction is local development. Pulling secrets from Secrets Manager on every 'npm run dev' adds a noticeable half-second delay and requires every engineer to have properly scoped IAM credentials, which is more setup than a shared .env file. We accepted that trade-off — a slower local boot is a fair price for never finding a Stripe key in git blame again.

SecurityDevOpsAWSSecrets Management
Getting Secrets Out of Code: A Practical Migration to a Secrets Manager — Wholly Software