Information security in the cloud depends on properly managing secrets, including AWS access keys. Authorized users and code must authenticate to use cloud resources. Authentication relies on shared secrets, but shared credentials may create security vulnerabilities, especially when shared naively by embedding them in application code. 

Embedding AWS access keys in code seems an efficient solution when, for example, your code needs to interact with the S3 API to store data in a bucket. However, it exposes the keys to anyone who sees the code.

AWS keys are often exposed in this way when code is uploaded to version control services like GitHub. However, publicly exposed code isn’t the only vulnerability to embedded access keys. Anyone inside the company with code access can view credentials they may not be authorized to use, undermining authentication and access control strategies.

Like giving out copies of your house key or leaving a spare under the mat, using AWS access keys in your code might seem handy, but it’s risky. If your code gets shared online, it’s like telling everyone where that spare key is. And even at work, not everyone should have a key to every door.

Below, we explore secure alternatives to embedding AWS access keys and other secrets in code.

What is an AWS Access Key?

Access keys are AWS’s primary long-term credential for programmatic authentication.  An AWS access key consists of an access key ID and a secret access key; together, they authenticate requests to AWS APIs, allowing users to interact with AWS services from their code, including via AWS CLI clients and SDKs. 

AWS access keys are associated with users in the AWS Identity and Access Management (IAM) platform. Because they are the programmatic equivalent of a username and password, they should be protected with the same diligence. Just as you wouldn’t embed your password in code, you should not embed your access key. 

How to Manage AWS Access Keys Securely

We’ll look at two ways to manage AWS access keys securely. The first is to avoid using them altogether, instead using temporary security credentials associated with AWS roles. The second takes advantage of AWS features to use access keys without exposing them needlessly.

Before discussing secure key management, a word of warning about the root users’ access key: the IAM root user has unconstrained access to every AWS resource. A bad actor may shut down servers, delete data, create and destroy users, or any other AWS API capability with the root user’s key.

For this reason, you should not use the root access key, and you should disable root user access keys already in use. In fact, it is good practice to avoid using the root account unless it’s strictly necessary, as we discussed in 10 Top Tips For Better AWS Security Today.

IAM Roles vs. IAM Users

An IAM role is an AWS identity with a set of permissions for making requests to AWS resources, but, unlike AWS users, roles are not associated with an individual. Users and applications can “assume” an IAM role, which allows them to take on the role’s permissions. Essentially, roles enable AWS customers to delegate permissions to other entities.

Roles have a couple of major advantages. First, a role can be attached to entities such as EC2 instances. That means the EC2 instance can request resources in line with the role’s permissions, obviating the need to embed an IAM user’s AWS access key in the code.

Second, roles can be used to create temporary credentials. IAM access keys are permanent until they are deleted, whereas a role’s temporary credentials automatically become invalid once a configurable time has elapsed.

Secure Use of AWS Access Keys

In some cases, you may prefer to use an IAM user’s access key instead of an AWS role, but you should not embed credentials in the code. Instead, you can safely store the access key in a location your code can read.

One option is to create an environment variable within your code’s operating environment to store the key. Environment variables are managed by the environment’s operating system and can be accessed via system libraries or the AWS SDK for your preferred programming language. Several Amazon services can use AWS Secrets Manager to retrieve secrets to inject into the environment variables of containers and other resources.

Another option is the AWS credentials file. The credentials file is a text file containing an access key. AWS SDKs and the AWS CLI will look for a credentials file and use the access key when making requests for other resources.

These methods—roles, environment variables, and credential files—are appropriate for different scenarios, but the critical point is this: embedding the AWS access key into your code is a bad idea.

How to Rotate AWS Access Keys

Rotation replaces an old key with a new key and retires the old key. AWS access keys are long-lasting credentials. If exposed, they may be exploited until the user or key is deleted. Key rotation limits the usefulness of leaked keys to bad actors.

AWS users can rotate keys in IAM without interrupting their software’s access to resources. The preferred approach is to create a new access key, update software to use the new key, and then make the old key inactive.

Once the user is satisfied all software is using the new key, they can delete the original.  AWS access key rotation can be carried out in the IAM web console, the AWS CLI, and the AWS API. 

Mitigating Risk When AWS Access Keys are Exposed

While AWS users can prevent the exposure of AWS keys, what should they do if a key is exposed? First, you must immediately invalidate the key. However, doing so will also prevent legitimate use, which could result in service disruption. Leaked keys should be invalidated as soon as possible, but you may want to rotate mission-critical software keys first. 

The exposed key may already have been used, so you must also check all resources the key grants access to. Depending on the user’s access permissions, their key may have allowed a bad actor to exfiltrate sensitive data or infiltrate malicious software. 

Finally, use S3 logs and AWS CloudTrail to investigate whether the key was exploited and take action to mitigate potential risks and vulnerabilities. 

Securely Storing other Secrets with AWS Secrets Manager

You may need to securely manage other secrets in addition to AWS access keys, including SSH keys, database credentials, and third-party API keys. AWS Secrets Manager provides a solution for storing, rotating, managing, and retrieving a wide variety of secrets. 

For example, to give an application access to a database, you would store database credentials encrypted in AWS Secrets Manager. The application can query Secrets Manager, which will decrypt and return the database credentials over an encrypted connection. Access to data stored in AWS Secrets Manager is controlled by IAM permissions policies for users, groups, and roles, providing fine-grained access control. 

Partner with an Expert to Strengthen Your Cloud Security

To learn more about AWS cloud security, visit KirkpatrickPrice’s AWS Security Services to find a wealth of cloud security and AWS audit educational content.

If you would like to discuss AWS audits with an experienced auditor, contact KirkpatrickPrice today.

Containers are used to host code without the complexity and resource demands of virtual machines. They allow developers to combine code and dependencies into a standardized package that runs anywhere, making them the ideal foundation for cloud-native applications and microservices.

But containers pose a problem. How do developers and DevOps professionals manage container creation, hosting, networking, and security? A business may deploy dozens of containers to host its apps and services. It’s challenging to manage all of them individually, so, ideally, container management should be automated.

That’s the role of container orchestration software. Container orchestration tools manage the container lifecycle: provisioning, deployment, scaling, networking, and more. Kubernetes—originally developed by Google—is one of the most widely used container orchestration tools.

Amazon Web Services offers a number of container and container orchestration services, including Amazon Fargate, Amazon Elastic Container Service (ECS), and Amazon Elastic Kubernetes Service (EKS). Although all play a role in container hosting and orchestration, they are not identical, and it can be a challenge to understand which is the right orchestration tool for your AWS environment.

This article focuses on the differences between the main AWS container orchestration services: ECS and EKS, and on container security more generally. But to understand those, we have to start with Amazon Fargate.

What is Amazon Fargate?

Amazon Fargate is a serverless infrastructure platform for containers. In this context, “serverless” doesn’t mean containers don’t run on servers. It means the user doesn’t have to concern themselves with managing and paying for servers. Instead, they pay for just the compute resources their containers consume.

It’s useful to contrast Amazon Fargate to EC2, Amazon’s virtual server platform. To host containers on EC2, you have to provision EC2 instances with specific storage, compute, and memory capacities; configure them to run containers securely, and then manage both the containers and the EC2 instances. You pay the full cost of the instances while they’re running.

In contrast, Amazon Fargate allows you to build container images, specify memory and compute resources, and deploy. You don’t have to manage, configure, or scale servers, and you only pay for the compute resources your containers consume.

You’ll note that we’ve not mentioned container orchestration yet. That’s because Amazon Fargate is not a container orchestration service. It’s a serverless container platform on which you can deploy containers managed by a container orchestration service. On AWS, you have two main orchestration options to manage containers running on Fargate: ECS and EKS.

What is Amazon ECS?

Amazon ECS is a managed container orchestration service that runs Docker and Windows containers. It offers a complete orchestration solution with support for Docker image repositories, versatile container deployment and management tools, networking services including service discovery, and container monitoring and logging via Amazon CloudWatch and CloudTrail.

By default, ECS deploys containers to Fargate, although it can manage containers hosted on EC2 or on-premises infrastructure with ECS Anywhere or AWS Outposts. That makes it an excellent choice for businesses that want a fully managed solution and that don’t need Kubernetes compatibility.

It’s important to note that Amazon ECS is based on proprietary Amazon technology. It is not fully portable between cloud platforms.

What is Amazon EKS?

Amazon EKS is a managed Kubernetes service to orchestrate containers hosted in AWS and on-premises. Like ECS, it can orchestrate containers running on AWS Fargate and on EC2 instances. The key benefit of EKS is that it is fully compatible with Kubernetes—it’s based on upstream Kubernetes, so clusters that run on-premises or on other cloud vendor platforms can be moved to EKS with no modification.

Amazon EKS vs Amazon ECS: Choosing A Container Service

The most important distinction between ECS and EKS is that EKS runs Kubernetes. If your business relies on the tooling and architecture provided by Kubernetes, then EKS is probably the best choice. EKS also provides more granular control over how containers are managed, but more control leads to greater complexity.

In contrast, ECS is a simpler container orchestration system. It is intended for businesses that don’t want or need granular control over every aspect of container deployment and management. ECS also integrates tightly with other AWS services, such as CloudWatch and Route 53. That’s a benefit if you want to use those tools, but a drawback if you’d prefer to use different tooling.

AWS Container Security Best Practices

Whichever AWS container orchestration tool you select, your organization is responsible for securing containers and the code and data they contain. As with servers, container misconfiguration is a significant risk vector. Amazon Fargate helps to reduce risk because users don’t manage the underlying server and network infrastructure. However, businesses must nevertheless follow container security best practices.

Use Minimal Images

Containers should run as little code as is practical. Each additional library or service increases the attack surface area. Ideally, containers include only your code and its essential runtime dependencies, excluding development dependencies and other redundant code. If possible, use distroless images or a security-focused lightweight distribution such as Alpine.

Minimal images are also significantly smaller, which means they consume fewer resources and are easier to audit and scan for security purposes.

Use Curated Images from a Secure Container Repository

Image repositories are a potential source of malicious code. It’s estimated that 20% of the most popular images in major public repositories contain vulnerable or malicious code.

Bad actors seeking to infiltrate malware may target insecure public and private repositories in so-called supply-chain attacks. If they can get malicious code into an image hosted in a container repository, that code may find its way inside your networks.

To combat this risk, businesses should create a set of curated images free of known security vulnerabilities. They should store images in a secure repository service, such as Amazon Elastic Container Registry. ECR integrates securely with Amazon ECS and Amazon EKS, and it allows users to create repositories with access permissions managed by AWS Identity and Access Management (IAM).

Don’t Run Containers or Processes Within Containers as Root

Containers should not run as the root user and nor should processes within the container.

  • If a process running as root is compromised, the attacker may use root privileges to modify the container’s contents.
  • If the container itself runs as root, a bad actor may be able to escalate their privileges on the container’s host operating system in the unlikely event of a container breakout.

Unfortunately, containers often run as the root user by default, so Dockerfiles should be modified to use the USER directive to specify a non-root user.

Don’t Hardcode Credentials

Avoid hardcoding credentials such as passwords or API keys in code that will run in a container, including AWS credentials. If systems that store or process the code are compromised, an attacker will gain access to the credentials.

AWS provides several methods for storing secrets and securely injecting them into containers, including the AWS Secrets Manager. Secrets Manager also enables users to easily rotate secrets, which may not be possible when they are included in production code.

To learn more about container security and all aspects of AWS security, visit our extensive library of AWS security resources.