AWS Security Blog

How to access secrets across AWS accounts by attaching resource-based policies

October 29, 2021: AWS KMS is replacing the term customer master key (CMK) with AWS KMS key and KMS key. The concept has not changed. To prevent breaking changes, AWS KMS is keeping some variations of this term. More info.


You can use AWS Secrets Manager to rotate, manage, and retrieve secrets such as database credentials and API keys throughout their lifecycle. And you can now use these secrets across AWS accounts by attaching resource-based policies to secrets. For example, you can manage secrets in one AWS account and grant employees or applications in other AWS accounts permissions to use these secrets. Similarly, you can share a secret with a business partner, such as a managed service provider (MSP), without transmitting the secret through channels such as email and handwritten notes. Resource-based policies also enable you to control who can manage permissions on a secret. For example, you can grant an employee permission to administer a specific secret.

When granting access to secrets, it’s important to keep in mind that, by default, IAM principals (users and roles) don’t have permission to access secrets. In addition to policies attached to IAM principals in your account, you can use resource-based policies to control this access within your AWS account or across accounts. When you grant access to a secret, IAM principals also need access to the encryption keys used to encrypt secrets. Therefore, to enable cross-account access, you must grant permissions to access the secret and the encryption key used to encrypt the secret.

In this blog, I show how to grant employees in an AWS account permission to use secrets in another account. I use the AWS Command Line Interface (AWS CLI) to show you how to grant an IAM role in your PRODUCTION account (the account where you run applications) permission to retrieve secrets from your CENTRAL_SECURITY account (the account where you manage secrets). I will use the placeholder MY_TEST_SECRET to denote an existing secret, the placeholder MY_CMK to denote the AWS KMS key (KMS key) that’s used to encrypt MY_TEST_SECRET, and the placeholder PRODUCTION_SECRET_ROLE to denote the IAM role I want to grant access to. The instructions require four steps:

  1. Create a resource-based policy and attach it to the secret in the CENTRAL_SECURITY account.
  2. Update the key policy for the KMS key in the CENTRAL_SECURITY account.
  3. Grant IAM role permissions to retrieve this secret in the PRODUCTION account.
  4. Verify access by retrieving the secret in the PRODUCTION account.

Here’s a diagram that depicts these four steps:
 

Figure 1: Diagram representing the steps in the process

Figure 1: Diagram representing the steps in the process

Step 1: Create a resource-based policy in your CENTRAL_SECURITY account and attach it to the secret, MY_TEST_SECRET

  1. Paste the following text in a file that you save with the name RESOURCE_POLICY.json. For this blog, I’ll create a policy that grants permissions to read the secret MY_TEST_SECRET. I’ll use the Principal element of the policy to define the role that can access this secret, and the Condition element of the policy to restrict access to the most recent version of the secret.
    
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Effect": "Allow",
          "Principal": {"AWS": "arn:aws:iam::PRODUCTION:role/PRODUCTION_SECRET_ROLE"},
          "Action": "secretsmanager:GetSecretValue",
          "Resource": "*",
          "Condition": {"ForAnyValue:StringEquals": {"secretsmanager:VersionStage": "AWSCURRENT"}}
        }
      ]
    }
    
  2. Next, from the AWS CLI, run the Secrets Manager put-resource-policy command to attach this policy to the secret.

    $aws secretsmanager put-resource-policy –secret-id MY_TEST_SECRET –resource-policy file://RESOURCE_POLICY.json

Here’s what the response looks like:

{
“ARN”: “arn:aws:secretsmanager:us-east-2:CENTRAL_SECURITY:secret:MY_TEST_SECRET”,
“Name”: “MY_TEST_SECRET”
}

You’ve successfully updated the permissions for this secret.

When the PRODUCTION account no longer needs access to your secret, you can use the delete-resource-policy command to remove the resource-based policy. You can also manage access by updating the content of the resource-based policy and using the put-resource-policy command to attach this updated policy to the secret.

Step 2: Update the key policy in your CENTRAL_SECURITY account

Secrets Manager encrypts secrets by default and entities retrieving these secrets need access to decrypt them using the MY_CMK.

  1. To grant these permissions, run the get-key-policy command to view the key policy for MY_CMK.
  2. Next, update the key policy by adding the following permissions to the key policy. For this example, I grant the IAM role, PRODUCTION_SECRET_ROLE, permission to use MY_CMK. The policy below grants the capability to use the Decrypt and DescribeKey commands with MY_CMK.
    
    {
       "Sid": "AllowUseOfTheKey",
       "Effect": "Allow",
       "Principal": 
               {"AWS": "arn:aws:iam::PRODUCTION:role/PRODUCTION_SECRET_ROLE"},
       "Action": [
       "kms:Decrypt",
       "kms:DescribeKey"
        ],
       "Resource": "arn:aws:kms:us-east-2:CENTRAL_SECURITY:key/MY_CMK"
    }
    
  3. Finally, from the AWS CLI, call the put-key-policy command to update the policy attached to MY_CMK.

Note: Steps 1 and 2 enable you to independently control who can access secrets across AWS accounts. You must grant both sets of permissions to enable cross-account access to secrets.

Step 3: Grant the IAM role in the PRODUCTION account permissions to retrieve the secret

I perform the next steps in the PRODUCTION accounts as an IAM administrator. To retrieve the secret from the CENTRAL_SECURITY account, the cross-account role also needs IAM permissions to retrieve the secret and decrypt it using the central security KMS key.

  1. To grant these permissions, paste the following text in a file and save it with the name PERMISSIONS_POLICY.json.
    
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Effect": "Allow",
          "Action": "secretsmanager:GetSecretValue",
          "Resource": " arn:aws:secretsmanager:us-east-2:CENTRAL_SECURITY:secret:MY_TEST_SECRET"
        },
        {
          "Effect": "Allow",
          "Action": "kms:Decrypt",
          "Resource": "arn:aws:kms:us-east-2:CENTRAL_SECURITY:key/MY_CMK"
        }
      ]
    }
    
  2. Next, use the IAM create-policy create-policy command to create the permissions policy, SECRETS_MANAGER_PERMISSIONS_POLICY.
  3. Then, use the IAM attach-role-policy command to attach this permissions policy to the IAM role, PRODUCTION_SECRET_ROLE.
     
    $aws iam create-policy –policy-name SECRETS_MANAGER_PERMISSIONS_POLICY –policy-document file://PERMISSIONS_POLICY.json
     
    $aws iam attach-role-policy –role-name PRODUCTION_SECRET_ROLE –policy-arn arn:aws:iam::aws:policy/SECRETS_MANAGER_PERMISSIONS_POLICY

You’ve now successfully granted the IAM role permissions to read the secret.

Step 4: Verify by retrieving the secret from Secrets Manager

To test the configuration, use the PRODUCTION_SECRET_ROLE to run the get-secret-value command from the PRODUCTION account.

$aws secretsmanager get-secret-value –secret-id arn:aws:secretsmanager:us-east-2: CENTRAL_SECURITY:secret:MY_TEST_SECRET –version-stage AWSCURRENT

Here’s what the response looks like:


{
 “ARN”: “arn:aws:secretsmanager:us-east-2: CENTRAL_SECURITY:secret:MY_TEST_SECRET”,
 “Name”: “MY_TEST_SECRET”,
 “SecretString”: “The Secret String”,
 “CreatedDate”: 123456789,
 “VersionId”: “64c4250d-0b81-42e0-9a0c-e189d3c9aea8”,
 “VersionsStages”: [“AWSCURRENT”]
}

You’ve successfully retrieved the secret, MY_TEST_SECRET, from your PRODUCTION account.

Summary

In this post, I showed you how to access secrets in Secrets Manager across AWS accounts. This allows you to manage secrets in one AWS account and grant employees or applications in other AWS accounts permissions to use these secrets.

To get started managing secrets, open the Secrets Manager console. To learn more, read the Secrets Manager documentation.

If you have comments about this post, submit them in the Comments section below. If you have questions about anything in this post, start a new thread on the Secrets Manager forum or contact AWS Support.

Want more AWS Security news? Follow us on Twitter.