This article was translated with the help of AI.
Are you issuing access keys just to use the AWS CLI?
I used to do exactly that. Access keys are convenient, aren't they?
Once you set them up with aws configure
, they keep working forever.
But behind that convenience lies a scary story.
A leak can mean a bill of tens of thousands of dollars, leaked data, and lost trust. And once it's out, you can't take it back.
This article covers how to deal with access keys, how to stop using them, and how to keep them from leaking.
Let's quickly review what access keys are.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html
An access key is a credential tied to an IAM user, made up of a pair: an access key ID and a secret access key.
You use them to operate AWS from the AWS CLI or SDKs.
And here's the reality waiting for you when one does leak.
"It's just one access key" can turn into something this big.
That's why I say access keys are scary.
So you want to stop using access keys. What should you use instead?
There's an alternative prepared for each scenario.
| Scenario | Access key | Alternative |
|---|---|---|
| Developer | Set up with aws configure |
|
aws login / aws sso login |
||
| CI/CD (GitHub Actions, etc.) | Register in Secrets | OIDC |
| AWS resources (EC2/Lambda/ECS) | Embed in the resource | IAM role |
| On-prem / external servers | Distribute to servers | IAM Roles Anywhere |
Let's go through them one by one.
This is the case for us developers.
What you use is aws login
.
https://docs.aws.amazon.com/cli/latest/reference/login/ Once you authenticate in the browser, it automatically sets up temporary credentials for you.
It works with the same feel as aws sso login
, which you use in environments that have IAM Identity Center.
It's a good fit for environments where "setting up IAM Identity Center is overkill."
With this, running your operations without access keys becomes easy to achieve.
This is the case for CI/CD like GitHub Actions.
Instead of registering an access key in Secrets, you use OIDC.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc.html
It ties GitHub and an IAM role together and issues access permissions temporarily, so you can access AWS without any access key.
This is the case for AWS resources like EC2, Lambda, and ECS.
Instead of embedding an access key, you use an IAM role.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
When you attach a role, temporary credentials are handed over automatically, so you don't need to hold an access key.
This is the case for operating from on-prem or servers outside AWS.
Instead of distributing an access key, you use IAM Roles Anywhere.
https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html
It establishes trust with X.509 certificates and lets you obtain temporary credentials, so you can operate servers outside AWS without handing out access keys either.
When you line them up like this, you notice a shared idea.
Unlike long-term credentials with no expiration such as access keys, every one of them uses temporary credentials with an expiration.
Shifting over to temporary credentials like this is what matters.
"So is there even any scenario left where you'd use an access key?" you might think.
If anything is left, it's roughly the stuff that can't be migrated.
For example:
These are the "no way around it" situations. If you can't stop using them, then harden your defenses.
This "keeping them from leaking" isn't only for people who keep using access keys.
Secrets aren't just access keys.
Database passwords and API tokens leak the same way.
Even if you stop using access keys, "keeping secrets from leaking" follows you for life.
So, how do you think secrets actually leak?
Let me group it into three broad categories.
.env
or credentials files as-isLeaks happen in all sorts of ways, but what they share is that "careless mistakes" vastly outnumber "malicious attacks."
Let's stop those careless mistakes with mechanisms.
Specifically, defense in three layers: prevention, mitigation, and detection.
Note that the following uses the most common case, mixing secrets into code (Git), as the example. The idea applies to other leak paths too.
Stop it before you leak it, right at the entrance. There are two places to stop it: the client and the server.
On the client, gitleaks.
Set up a pre-commit hook, and it rejects secrets the moment you try to commit.
https://github.com/gitleaks/gitleaks On the server side, GitHub's Push Protection.
It blocks changes that contain secrets at the moment you push.
https://docs.github.com/en/code-security/secret-scanning/introduction/about-push-protection Even if something leaks, minimize the damage.
With a least-privilege policy, narrow down what that access key can do.
With IAM policy Conditions (like aws:SourceIp
), limit where access can come from.
Rotate regularly so old credentials don't linger.
Even if something leaks, notice it quickly. There are two things to watch.
One is whether a secret has been mixed into your code.
By building gitleaks into CI and running it on every push, you can catch any contamination immediately.
The other is whether a leaked access key is being used.
GuardDuty analyzes sources like CloudTrail and detects abnormal credential usage, such as use from outside AWS.
[https://aws.amazon.com/guardduty/](https://aws.amazon.com/guardduty/)
If it does leak, the first response is what counts.
🚨 If a secret leaks, revoke it immediately, before you even think about deleting the commit.
Git keeps history, so deleting the commit is meaningless.
Once you revoke it, the value left in the history can no longer be used.
Security is the foundation of business. That said, don't overthink it. Just start with aws login
right at hand.