AWS Deployment Checklist, Part 1: Secrets and Credentials
Earlier this week, Vercel confirmed that attackers accessed their internal systems. Someone claiming to be ShinyHunters put source code, API keys, NPM tokens, and GitHub tokens up for sale. Vercel's advice to customers: review your environment variables.
That advice is correct. It's also too late for the companies that stored production database credentials, Stripe API keys, and OAuth secrets in Vercel's environment variables tab — because those secrets are now potentially in someone else's hands.
But the Vercel breach just highlighted a pattern we see in almost every AWS environment we audit: secrets scattered across platforms, over-privileged credentials, no rotation plan, and no clear picture of what's exposed if any single link in the chain breaks.
This is part one of our AWS deployment checklist series. We're starting with secrets and credentials because they're the thing most likely to be the difference between "we heard about the breach" and "we were the breach."
1. Stop storing production secrets in platform environment variables
Environment variables in your deployment platform — Vercel, Netlify, GitHub Actions, whatever — are convenient. They're also a single point of compromise. When that platform gets breached, every secret in every environment variable is potentially exposed.
Use AWS Secrets Manager or Systems Manager Parameter Store for anything that matters. Database credentials, API keys, encryption keys, service tokens — these belong in a secrets manager with access logging, not in a text field in your deployment dashboard.
The overhead is minimal. Your application reads from Secrets Manager at startup instead of from process.env. The difference in security posture is enormous.
2. Separate credentials by environment — really separate
Most teams have separate environment variables for dev, staging, and production. Many of those teams use the same database credentials across staging and production, or the same Stripe API key, or the same GitHub token with the same permissions.
If your preview deployment has a credential that can touch production data, your preview environment is a production attack surface. A breach, a misconfigured branch, a dependency supply chain attack on a preview build — any of these becomes a production incident.
Different credentials per environment. Different database users. Different API keys. No exceptions.
3. MFA on root. IAM users for everything else. No shared credentials.
This one should be obvious by now, but we still see it: teams using the root account for daily work, or sharing a single IAM user across the team, or IAM users without MFA.
Root account: MFA enabled, credentials locked away, used only for billing and account-level operations. Daily work: individual IAM users, each with MFA, each with permissions scoped to what they actually need. Shared "deploy" user that three people know the password to: delete it.
If you can't trace an action in CloudTrail back to a specific person, your access control is broken.
4. Scope every credential to minimum required
That GitHub token connected to your CI/CD — does it have write access to every repository in your organisation? That IAM user running your deployments — does it have AdministratorAccess? That database connection string — is it using the root user?
The answer to all three is usually yes. And the answer to all three should be no.
Every credential should have the minimum permissions required for its specific job. A deployment pipeline needs permission to update specific services, not admin access to the entire AWS account. A database connection for a web app needs read/write on its own tables, not GRANT ALL.
This takes an afternoon to fix and dramatically reduces blast radius when — not if — a credential is compromised.
5. Enable CloudTrail and actually look at it
CloudTrail logs every API call in your AWS account. It's the difference between "we were breached and we don't know what happened" and "we were breached and we know exactly which credentials were used, what was accessed, and when."
Enable it. Send logs to S3. Set up a trail that covers all regions, not just the one you think you're using. Turn on CloudTrail Insights if you want anomaly detection without building it yourself.
Then — and this is where most teams fall off — actually review it. Set up CloudWatch alarms for suspicious patterns: root account usage, console logins from unexpected locations, API calls from IP ranges you don't recognise. These alerts are free to set up and worth everything when they fire.
6. Automate credential rotation
Manual credential rotation means credential rotation that doesn't happen. The database password that was set two years ago and is embedded in four different config files across three environments — that's the credential that will be compromised.
Secrets Manager supports automatic rotation for RDS credentials out of the box. For other secrets, build a rotation Lambda or use a scheduled pipeline. The goal: no credential lives longer than 90 days, and rotating one doesn't require a deployment or a restart.
If automated rotation feels like too much right now, start with a calendar reminder and a documented procedure. It's not as good, but it's infinitely better than "we'll get to it."
7. Know your blast radius
If someone gets your deployment platform credentials right now — what do they have access to? If someone gets your CI/CD pipeline secrets — what can they reach? If a developer's laptop is compromised — what credentials are stored locally?
Draw the diagram. For each secret you manage, answer: where is it stored, who can access it, what does it grant access to, and when was it last rotated?
If the answer to "what do they get?" is "everything" — you have a concentration risk that needs to be addressed before the next Vercel, the next SolarWinds, the next CodeCov.
8. Have a breach response plan for credential compromise
Not a generic incident response plan. A specific, documented answer to the question: "A platform we use has been breached and our credentials may be exposed. What do we do in the next 60 minutes?"
The plan should include: a list of every credential stored in each platform, how to rotate each one, who's responsible for each rotation, what services need to be restarted, and who needs to be notified.
When the Vercel news dropped this week, the teams that were fine are the ones that could open a document, follow a list, and have everything rotated within an hour. The teams that are still figuring it out are the ones that didn't have that document.
This is part one of our AWS deployment checklist series. Next: cost guardrails and billing hygiene — how to stop AWS from surprising you with a bill that's three times what you expected.
At Otocolobus, we audit AWS environments for exactly these problems — scattered secrets, over-privileged credentials, missing rotation policies. If you want to know where your gaps are before someone else finds them, get in touch.