RoastMyOpsec

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.

OptionWhen it winsWatch-outTakeaway
.env with AWS keys on the originNeverLive secretsIncident; roast signatures /.env
Credentials file on the originNeverSame keys, different filenameSame class of miss; deny the name
IAM role / temporary credsCompute and CI you controlDo not dump role output into static filesNo long-lived keys on the CDN
robots.txt DisallowNot for thisTreasure-map lineEdge 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 now

FAQ

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