HashiCorp Cloud Platform
Remediate leaked AWS secrets
HCP Vault Radar can scan for leaked Amazon Web Services (AWS) secrets using dynamic secrets, for a tutorial on how to use statics secrets, go to active secrets documentation.
Create an incident
Leaked secrets can lead to unauthorized access to your services. To prevent malicious activity, we recommend rotating and storing the secret in Vault.
- Follow your organization’s guidelines for emergency rotation of a secret.
- Contact your AWS account owner.
- Determine if your company already uses HashiCorp Vault.
Configure Vault's AWS secret engine
This example uses the AWS secrets engine and IAM auth method. If your application is already configured to access secrets in Vault, use existing secrets engines and auth methods. Click here for more information on AWS secret engine.
- Create an AWS policy with the permissions that your app needs to use AWS services. For more information about AWS policies, please refer to this document.
Set the following environment variables in your local environment:
VAULT_TOKEN VAULT_ADDR VAULT_NAMESPACE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
Enable the AWS secret engine in Vault.
$ vault secrets enable aws
Note
This command will default to aws/ as the path, you can specify any other path but make sure to change the path of the commands below.
Configure the root credentials.
$ vault write aws/config/root access_key=${AWS_ACCESS_KEY} secret_key=${AWS_SECRET_KEY}
Note
Find the necessary permissions for Vault to create dynamic AWS IAM users here. For more details on how to configure root credentials, refer to Vault docs
Create an IAM role with a policy. This IAM role needs to match the permissions required on AWS. For example, to create a Vault role to grant full access to AWS EC2 service, the command should look like this:
$ vault write aws/roles/my-role \ credential_type=iam_user \ policy_document=-<<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:*", "Resource": "*" } ] } EOF
Note
Follow the Vault docs for more configuration options like permissions boundary.
Another option is to use existing policy ARN. Click here to learn more.
Validate the access by trying to read a secret.
$ vault read aws/creds/my-role
Note
Secrets created by Vault using AWS secret engine have a default lease of 60 min. For more information on how to change the lease visit Vault docs.
Remove the secret from code
Now that the AWS secret is available from Vault, remove the hardcoded secret from the source code. This example uses an environment variable to store the secret from Vault.
Create an environment variable with the secret from Vault.
$ export MY_SECRET=$(curl \ --header "X-Vault-Token: ..." \ http://127.0.0.1:8200/v1/aws/static-creds/{my-role})
Remove the secret from source and add a reference to the secret stored at the environment variable
MY_SECRET
.mySecret = getenv(“MY_SECRET”)
Start your local server and test.
Note
Dynamic secrets need to be refreshed. If you are using an environment variable to read the secret, your application needs a way to refresh the secret value when it expires. Here are some ways to keep the dynamic secret value updated within your running application.
- Create secrets with the Vault secrets operator for Kubernetes. (When using VSO and dynamic secrets, the application will need to rotate the secret value).
- Read and reload secrets in Spring.
- If you do not use environment variables, refer to the Vault API documentation.
Revoke the secret
Revoke the secret to complete the remediation process.
- Validate the environment variable is populated from Vault.
- Deploy and test the application.
- Work with the AWS service owner to revoke the previous secret value.
Note
If the found secret is an AWS_ACCESS_KEY_ID
or AWS_SECRET_KEY
, they would need to be rotated at the same time.