Ditching AWS access keys (including easy wins regardless of scale)

Get rid of AWS Access Keys

It wasn’t that long ago when access keys were one of the primary methods for accessing AWS resources and environments. You would create an IAM user, give them a username and password, and/or give them access keys. The user would then use that username/password to log into the AWS console, and they would use the access keys to configure their AWS CLI or within environment variables for local development.

While this approach technically works fine, one problem is that access keys are designed to provide long-term access. Once created, they live forever until someone either rotates them or deactivates and deletes them. Over time, individuals and organizations end up with access keys that they’ve long forgotten about and that are hanging out in code repositories, log files, backups, etc… Even if a threat actor finds an access key years later, it could still work and give access! Not great.

The second problem is that, as we saw in our IAM Privilege Escalation Labs course, misconfigured policies for IAM users can turn into critical vulnerabilities very quickly. It doesn’t take much — one missed restriction can be the difference between a secure AWS environment and an admin-level PrivEsc in minutes.

Combine the fact that access keys live forever with the potential for policy misconfiguration, and you have security incidents like these.

Does that mean that AWS and the cloud aren’t secure? Absolutely not. It just means we need to get rid of and stop using access keys. Here’s how.

Alternative to access keys

Instead of using long-term access keys, we can use temporary security credentials through the AWS Security Token Service (STS).

Temporary credentials work almost the same as access keys but with two major differences:

  1. Temporary security credentials are short-term and expire after anywhere from a few minutes to hours (length of time depends). After they’ve expired, they no longer work and can’t be re-used.
  2. Temporary security credentials are generated only when they are needed instead of being stored with the user. New credentials can be generated as they expire, or even before they expire, and you don’t have to revoke them when they’re no longer needed

You can use these temporary security credentials with IAM roles and identity federation (which we’ll explain in a little bit), which means that once you get rid of access keys, you can start to get rid of (most) IAM Users. Let’s find out how.

Remove unused access keys

The easiest win possible here is to get rid of all unused AWS access keys. You can easily find them by looking at your credentials report. Alternatively, you can also use AWS Config with iam-user-unused-credentials-check for an automated and regular (but more expensive) approach and which also integrates with Security Hub controls.

The CIS Benchmark recommends removing access keys that haven’t been used in 90 days, but even that could be too generous. What you choose is up to you, but again, removing unused access keys is going to be an easy win.

Once you’ve removed unused access keys, you can look for IAM users that no longer have any credentials. Without credentials, those users can’t do a whole lot, so you can just go ahead and remove them. You can do that via the same credentials report.

Remove root access keys

The next easy win is to remove root access keys. You should almost never have root user accounts with access keys in AWS. Heck, even AWS strongly recommends that you disable the root user entirely via SCPs (Service Control Policies).

If you do have access keys for root users, you’ll want to figure out why first, and re-work the app or system using them, but after that, go ahead and remove those access keys ASAP.

If you have multiple AWS accounts, finding whether there are any root account access keys is best done using the aws iam get-account-summary CLI command. The output of that command will look something like this:

{
    "SummaryMap": {
        [...]
        "SigningCertificatesPerUserQuota": 2,
        "AccountAccessKeysPresent": 0,
        "AccountSigningCertificatesPresent": 0,
	[...]
    }
}

Code language: JavaScript (javascript)

The important piece of information here is the AccountAccessKeysPresent. If you see a 0 as we do in this example, then that means there are no access keys for the root account and you’re good to go.

Or, again, for a more automated approach, you can use AWS Config and Security Hub if you already have those service enabled!

Find AWS resources using access keys

While using access keys with resources that reside within AWS has never been recommended, some people have used them anyway and so it’s worth mentioning here: find and remove all AWS resources using access keys. They should be using roles instead!

Since the AWS SDK automatically checks multiple sources for the right credentials, you can update an AWS compute resource (like an EC2 instance or Lambda function) to use a role instead, and then disable the access key. Applications on instances will then be able to access the temporary credentials through an instance profile attached to the instance, and that instance profile contains the role that can provide temporary credentials. More information on that here.

Change how humans access your AWS environments

As AWS continues to push towards avoiding using long-term credentials, they’ve been strongly recommending using IAM Identity Center instead of creating IAM Users. There are multiple benefits to doing this, but the overarching benefit is that it helps you centrally manage your workforce’s access to multiple AWS accounts and applications without using long-term credentials.

With Identity Center, you can either manage user identities in AWS, or you can connect to your existing third party identity provider (IdP) like Microsoft AD, Okta, etc…

Once you’ve set that up, your employees can use Single Sign-On (SSO) to access AWS resources. Having to manage one less username/password is always nice.

For third-party contractors, you can either add them to your IdP or they can authenticate in their own AWS account through SSO and then use IAM roles to access approved resources in your accounts (with cross-account access using trust relationships).

As a starting point, if you already have IAM Users set up with password logins, you can find them through the same credentials report we mentioned previously and you can use that to prioritize which ones to switch over to Identity Center first.

Find external apps using access keys

A common scenario for using access keys is when developing applications locally. It’s convenient and easy, but it’s no longer the recommended approach. Instead, since we’ve just set up AWS IAM Identity Center from the prior section, we can use that for local development as well.

What about for applications, containers, or other workloads running outside of AWS but where we can’t use something like Identity Center? They could be on-prem, in an external CI/CD pipeline (like on GitLab), etc… Up until fairly recently, you couldn’t use the same roles that we talked about for EC2 instances, Lambda functions, or ECS. Now, you can. It’s called IAM Roles Anywhere.

IAM Roles Anywhere uses “public key infrastructure (PKI) to establish trust between your AWS account and certificate authority (CA) that issues certificates to your on-premises workloads.” (Source and more info)

Your on-prem applications then use IAM Roles Anywhere to exchange X.509 certificates for temporary AWS credentials.

For more information on using this with CI/CD tools, check out this blog post from AWS.

As an alternative to using IAM Roles Anywhere, if you are using GitHub, GitLab, or Bitbucket for your CI/CD, they provide support for OIDC which will accomplish a similar goal: getting rid of those long-term creds.

Prevent creating new access keys

Once you’ve gone through all of the trouble of removing as many access keys as possible, the last thing you want is for people to go back and create more and then have to start this process all over again.

An easy and straightforward way of preventing creating more keys is to use this policy:

{ 
    "Version": "2012-10-17", 
    "Statement": { 
        "Effect": "Deny", 
        "Action": "iam:CreateAccessKey", 
        "Resource": "*" 
    } 
}

Code language: JSON / JSON with Comments (json)

This, by the way, will also help protect against the iam:CreateAccessKey PrivEsc we learned about here.

If you want to take it a step further, you can even prevent the creation of new users entirely:

{ 
    "Version": "2012-10-17", 
    "Statement": { 
        "Effect": "Deny", 
        "Action": [
		"iam:CreateAccessKey", 
		"iam:CreateUser"
	], 
        "Resource": "*" 
    } 
}

Code language: JSON / JSON with Comments (json)

You would deploy this as an SCP so that it applies to all of your AWS accounts.

Conclusion

AWS has made giant leaps in recent years when it comes to reducing the need for long-term credentials like passwords and access keys. Features like IAM Roles Anywhere are game changers, no doubt. The challenge is getting organizations that have been using AWS for years to adopt some of these new features, because it’s definitely not as easy as just flipping a switch.

Hopefully this article gave you a starting point and outlined some easy wins to get you going. Some of the other efforts will take longer, but it will be worth it!

By the way, if you or your team needs to learn more about what was discussed in this article, we’ve got you:

Learn how to get rid of access keys and use AWS IAM Identity Center (SSO) with Cybr’s training

Already have a Cybr Membership? Access our Identity Center training here.

Looking to upskill or reskill your team in AWS security? Get a demo of our hands-on training.

Looking for individual training? View our pricing here.

Related Articles

Responses

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.