Vulnerabilities
AWS Credentials File vs .env on Production Origins
April 5, 2022
An AWS credentials file vs .env on a production origin is two containers for the same class of secret. /.env often holds AWS_ACCESS_KEY_ID-shaped values — the roast signatures that path. A copied credentials file from a developer home directory is the shared-file version of the same miss. Neither belongs next to index.html. RoastMyOpsec may not fetch that credentials filename today. Still deny it at the edge. Do not Disallow it in robots.txt; deny the object, do not advertise the path.
The practical difference
The credentials file is the CLI/SDK shared-config convention. .env is the twelve-factor convention the app loads. Attackers do not care which format you used once the bytes are public.
IAM best practice is temporary roles, not long-lived keys in any file on a CDN. If a public object may have held access keys, rotate them. Then fix the publish pipeline so home-directory files never enter the artifact.
How to choose based on what you shipped
Take the object off the origin, deny the basename at the CDN, rotate access keys that may have been in that tree, and prefer workload roles going forward. Fail CI if credential-file names appear in a static export. Same deny on guessable staging hosts.
| Option | When it wins | Watch-out | Takeaway |
|---|---|---|---|
| .env with AWS keys on the origin | Never | Live secrets | Incident; roast signatures /.env |
| Credentials file on the origin | Never | Same keys, different filename | Same class of miss; deny the name |
| IAM role / temporary creds | Compute and CI you control | Do not dump role output into static files | No long-lived keys on the CDN |
| robots.txt Disallow | Not for this | Treasure-map line | Edge deny is the control |
When each option wins (never as a public download)
.env wins only as a private runtime file on the app host — and even then, prefer platform secrets or roles. A local credentials file wins on a locked-down workstation for CLI work. Neither wins on the marketing bucket.
If /.git/HEAD was also reachable, assume history as well as the current file. See exposed .git vs .env.
Common mistakes
The first mistake is zipping a developer home folder into the deploy because a script 'needed AWS for the build.'
The second mistake is rotating the .env keys and leaving the credentials file on the origin.
The third mistake is documenting the filename in robots.txt Disallow instead of blocking it at the CDN.
What a URL roast can prove
The roast signatures /.env and /.env.local. An AWS credentials filename is not a scored path today. Still deny it. Bounded GETs, signature checks, no AWS API calls, no key use. A 404 is not proof the file is gone under another prefix.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Is a public AWS credentials file a vulnerability?
- Treat it as a credential incident. Remove it, deny the name at the edge, and rotate keys that may have been inside.
- Does RoastMyOpsec fetch AWS credentials files?
- Not as a scored path today. It does probe /.env. Deny the credentials filename anyway. Same class of miss as /.env.
- Are publishable AWS keys in JavaScript the same issue?
- Browser keys are a different placement rule. Long-lived secret keys must never ship. See public JavaScript API keys vs server secrets.
Sources
Related guides
Vulnerabilities
Exposed .git vs .env on Production WebsitesVulnerabilities
.env.example vs .env on Production OriginsVulnerabilities
Public JavaScript API Keys vs Server Secrets