Your AWS access key is exposed
An AWS access key is never safe to expose. The access key ID (AKIA...) plus its secret access key let anyone act as that IAM user, so deactivate the key in IAM right away, check CloudTrail for what it did, and replace it with a role or a tightly scoped key kept on the server.
Updated
Check your live site now
Free, no signup, read only. A grade and plain fixes in seconds.
The two halves of an AWS key
- Access key ID: 20 characters. AKIA means a long-term key for an IAM user (or, worse, the root user). ASIA means temporary credentials from STS, which also need a session token.
- Secret access key: 40 characters with no fixed prefix. AWS shows it once, when the key is created.
The ID alone can't sign requests. But the ID and the secret almost always travel together, in the same env file or the same config object, so a visible AKIA usually means the secret is sitting right next to it. Scanners, ours included, look for the ID because the secret has no recognisable shape.
The root user should have no access keys at all. If the exposed key belongs to root, treat the whole account as compromised.
What someone can do with a leaked AWS key
Whatever the IAM user's policies allow. Keys made for a small job often carry AdministratorAccess because that's what made an error go away during setup. With broad permissions, someone can:
- Read, copy or delete your S3 data.
- Launch compute in any region, often for crypto mining, billed to you.
- Create new IAM users and access keys so they keep access after you kill the first key.
- Send email through SES, or read values from Secrets Manager and Parameter Store.
Automated tools search public code and repositories for AKIA keys. Assume a key in a public bundle or repo has already been found.
What to do if your AWS key is exposed, in order
- Deactivate it. In the IAM console open Users, pick the user, open the Security credentials tab and set the access key to inactive. If you don't know which user owns it, aws sts get-caller-identity run with that key tells you.
- Look for persistence. Check IAM for users, access keys, roles, policies and console passwords created recently. Deactivating one key doesn't remove a second one the attacker made.
- Read CloudTrail Event history, filtered by the access key ID, to see what the key did. Check every region, not just the one you use.
- Check billing and Cost Explorer for services and regions you don't use, and shut down anything you didn't launch.
- Create the replacement (ideally a role, not a key), update your apps, confirm they work, then delete the old key.
- Remove it from your code and git history, and open a support case with AWS if there are charges you didn't cause.
# Which account and user does this key belong to?
AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... aws sts get-caller-identity
# Kill it, then delete it once you're sure
aws iam update-access-key --user-name app-uploader --access-key-id AKIA... --status Inactive
aws iam delete-access-key --user-name app-uploader --access-key-id AKIA...
# What did it do? (management events, last 90 days, current region)
aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIA...AWS also watches some public sources, such as GitHub, for exposed keys. When it finds one it may email you and attach a quarantine policy that blocks some actions. That helps, but it doesn't replace any of the steps above, and you can't count on it spotting a key in your site's JavaScript.
How to avoid long-lived AWS keys
- Code running on AWS (Lambda, ECS, EC2) should use an IAM role. No key to leak.
- CI and hosting outside AWS can often use OIDC federation to assume a role with short-lived credentials. GitHub Actions supports this.
- Browser uploads to S3 should use presigned URLs created by your server, so the browser gets a single-use permission, never a key.
- Browser access to AWS services goes through Cognito identity pools, which hand out temporary, scoped credentials.
If you must use a long-lived key, give it its own IAM user with a policy for exactly one job, keep it in a server-only env var, and rotate it on a schedule.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject"],
"Resource": "arn:aws:s3:::my-app-uploads/*"
}
]
}Questions
Is the AWS access key ID a secret?
On its own it can't sign requests, but treat it as sensitive. It points to your account (aws sts get-access-key-info returns the account ID) and it's usually found next to the secret.
Can I use AWS keys in a front end if the IAM policy is small?
Don't. Even a small policy gets abused at your expense, and nothing stops people copying it. Use presigned URLs or Cognito for browser access.
Does your scan detect AWS keys?
It flags AKIA access key IDs in your page HTML and your site's own JavaScript, and it checks whether files like /.env are publicly downloadable. It doesn't detect temporary ASIA keys or a secret access key on its own.
Does GitHub catch AWS keys?
Yes. GitHub secret scanning recognises AWS access keys, and push protection can block a commit that contains one. Your deployed site is a separate place to check.