Description
Real AWS secrets in EC2 user_data can be exposed to people who can access the playbook or user data. Use an instance role with only the required permissions and temporary credentials instead of long-term access keys.
An access key ID alone cannot authenticate an AWS request. The secret access key is also required, and temporary credentials additionally require a session token. Check whether a suspicious value is a documentation example or a real credential. If a real secret was exposed, removing it from the current file is not sufficient.
Potential impact
- An exposed, valid credential set can be used for unwanted AWS requests within its permission scope.
- Copies can remain in repository history, user data or deployment records. Rotating a shared key may also require changes to dependent workloads.
Remediation
- Remove real secrets from
user_dataand attach a least-privilege IAM role through an instance profile. Configure the application to use temporary credentials through a supported SDK's default credential provider. - Promptly deactivate or revoke and replace a valid exposed key while accounting for dependent workloads. Check repository history and existing user-data copies as well as current files.
- Investigate relevant access records and verify that required workloads continue to function with the new authentication method.
Examples
The key strings are public documentation examples, not real credentials. Choose an AMI, instance type and subnet for your environment. For the after-example, prepare an instance profile containing the required role and give the deployment identity permission to attach it.
Before
- name: start an instance
community.aws.ec2_instance:
name: credential-example
image_id: "{{ ami_id }}"
instance_type: "{{ instance_type }}"
vpc_subnet_id: "{{ subnet_id }}"
user_data: |
#!/bin/bash
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
The startup script embeds a key pair. Using real keys this way leaves secrets in the user data and playbook.
After
- name: start an instance
community.aws.ec2_instance:
name: credential-example
image_id: "{{ ami_id }}"
instance_type: "{{ instance_type }}"
vpc_subnet_id: "{{ subnet_id }}"
iam_instance_profile: "{{ instance_profile_name }}"
An instance profile replaces the embedded keys. Verify that the application uses temporary credentials and has only the required permissions. This change does not revoke keys that were already exposed.