AWS IAM

Prerequisites

  • Be familiar with Dynamic Secrets.
  • Be familiar with AWS IAM
  • [Optional] CLI v3.38.0 or greater
  • Doppler Enterprise plan. If you're not on the Enterprise plan and are interested in Dynamic Secrets, reach out to [email protected]

Overview

Dynamic Secrets are a powerful way to improve the auditability and security of your secrets.

Typically, when an AWS IAM user ("IAM user") is created, it is given an IAM policy and then used in code. If and when the IAM user is rotated or revoked is dependent on your security posture and policies. This unbound usage allows secrets to sprawl indiscriminately.

By adopting a dynamic secrets pattern with your IAM users, you are able to make assumptions about where your IAM users are deployed and how old they are. Each time you lease an IAM user when using dynamic secrets, a new, unique user is provisioned with a mandatory TTL. No more rotation or de-provisioning is required on your part.

Requirements

In order to create a dynamic secret, two items must be configured

Dynamic Secret Integration

  • An integration which Doppler utilizes to facilitate the leasing and revoking of IAM users (this can be used across dynamic secrets). This will establish an IAM user with an IAM Policy that allows Doppler to create and delete IAM users

Dynamic Secret Configurations

  • An IAM Policy that you define which Doppler will apply to each leased IAM user

The diagram below highlights how a single dynamic secret integration can be configured to lease multiple dynamic secrets types, each with a different IAM policy. This flexible model allows finely scope IAM user to be provisioned just-in-time.

Configuration

Create the Managing User IAM Role Policy

Doppler uses an IAM role you provide to assume into your account. This role requires a specific IAM policy.

  1. Navigate to the Create New Policy section in the AWS IAM console
  2. Switch to the JSON tab
  3. Enter the following minimally scoped policy
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "iam:DeleteAccessKey",
                    "iam:PutUserPolicy",
                    "iam:DeleteUserPolicy",
                    "iam:DeleteUser",
                    "iam:ListUserPolicies",
                    "iam:CreateUser",
                    "iam:CreateAccessKey",
                    "iam:ListAccessKeys"
                ],
                "Resource": "*"
            }
        ]
    }
    
  4. Optionally provide tags
  5. Name your policy and hit create

Create the Managing User IAM Role

To issue IAM users, Doppler uses an IAM role you provide to assume into your account

  1. Navigate to the create role section of the AWS IAM console
  2. Select AWS account for the Trusted entity type
  3. Select Another AWS account under An AWS account
    1. Enter 299900769157 for the Account ID. This is the account ID for Doppler's rotator service.
  4. Under Options check Require external ID
    1. Enter your workplace slug for the External ID. You can obtain your workplace slug by visiting the Doppler dashboard. In the URL, grab the value after /workplace/
    2. Leave require MFA unchecked
  5. On the next screen, search for and select the policy you created above. Click next
  6. Name your role and optionally complete the other fields
  7. Create your role. Make note of the ARN

Dynamic Secret Integration

  1. Navigate to the config that you want to add the dynamic secret to
  2. In the Dynamic Secrets section, click Add Dynamic Secret

  1. Select AWS IAM as the integration type

  1. If you've previously created an integration you'd like to re-use, select it. Otherwise, select Create New Connection
  2. Name the integration and enter the ARN of the Managing User you created above and click Connect
  3. Enter the IAM policy to be used each time a new IAM User is leased

Usage

Leasing an IAM user can be done via the CLI or API. As a reminder, each time you lease a user, a new IAM user is created, with its properties returned to you.

📘

Dynamc Secret taxonomy

In the examples below, you'll notice AWS_USER is prepended to each IAM user property (i.e. AWS_USER_ARN). This is the name of the example dynamic secret created for these docs. In your specific situation, the prepended value will be whatever you named your dynamic secret.

CLI

Dynamic secrets are supported in the doppler secrets download and doppler run commands. Both options are great for local development and deploying production apps alike.

For example, to use an IAM user locally, you can leverage doppler secrets download --no-file | jq . (jq isn't required, it just prints the output nicely).

doppler secrets download --no-file | jq .
{
  "AWS_USER_ACCESS_KEY_ID": "AKIXXXXXXXXXXXXI",
  "AWS_USER_ARN": "arn:aws:iam::36XXXXXXXX0:user/doppler/Doppler-Dynamic-yR9Y8hSHAzTwt",
  "AWS_USER_LEASE_EXPIRATION": "2022-02-15T17:04:54.782Z",
  "AWS_USER_LEASE_ID": "969eb8c9-f186-475b-8c32-3556de0aef21",
  "AWS_USER_POLICY_NAME": "doppler-policy-IsIklv03vqi12",
  "AWS_USER_SECRET_ACCESS_KEY": "RQ6R7aegXXXXXXXXXXXXMiJFdW/cPXXXXXoz",
  "AWS_USER_USERNAME": "Doppler-Dynamic-yR9Y8hSHAzTwt",
  "AWS_USER_USER_ID": "AXXAVKXXXXXXXXFOAO",
  "DOPPLER_CONFIG": "dev",
  "DOPPLER_ENVIRONMENT": "dev",
  "DOPPLER_PROJECT": "dynamic-secret"
}

As well, you can also use doppler run to inject a user into a new shell, in this example zsh. After you run the command, the secret values will be part of your active env

doppler run -- zsh
printenv
...
AWS_USER_LEASE_ID=5d4a9800-7c7e-4009-9113-2a3dda2e9ff1
AWS_USER_LEASE_EXPIRATION=2022-02-15T17:15:16.586Z
AWS_USER_ACCESS_KEY_ID=AKIXXXXXXXXXXXXF6S
AWS_USER_POLICY_NAME=doppler-policy-sWQX6NpNVQHpv
AWS_USER_ARN=arn:aws:iam::366XXXXXXXXXXXX10:user/doppler/Doppler-Dynamic-0jflFuO4EXVZF
AWS_USER_USER_ID=AIDAVKXXXXXXXXXXXXFLP
AWS_USER_USERNAME=Doppler-Dynamic-0jflFuO4EXVZF
AWS_USER_SECRET_ACCESS_KEY=+Q7Z1myOJXXXXXXXXXXXX7tBR8cWdKjRAXXXXXXXXXXXXhB

If you're deploying an app with doppler run, the normal syntax of doppler run -- your_app_executable still works seamlessly - just be sure to account for your lease TTL.

In case you want to leverage the user for longer than 30 min, you can provide a --dynamic-ttl value to set the lease TTL. s and h are supported for seconds and hours, respectively.

date -u && doppler secrets download --dynamic-ttl 3h --no-file \
        | jq ."AWS_USER_LEASE_EXPIRATION"
Tue Feb 15 17:08:37 UTC 2022
"2022-02-15T20:08:37.868Z"

Example

The example below demonstrates how to leverage a dynamic secret lease in conjunction with the aws cli.

Note: in the example, the dynamic secret is named AWS_USER - replace that value with whatever you named your dynamic secret.

doppler run -- zsh
AWS_ACCESS_KEY_ID=$AWS_USER_ACCESS_KEY_ID \
        AWS_SECRET_ACCESS_KEY=$AWS_USER_SECRET_ACCESS_KEY \
        aws ec2 describe-instances \
        --output table \
        --region us-east-1 \
        --filters --query "Reservations[].Instances[].InstanceId"
-------------------------
|   DescribeInstances   |
+-----------------------+
|  i-0ca2eac84e626db17  |
+-----------------------+

API

Leasing dynamic secrets via the API is analogous to leasing them via the CLI. The /config/secrets/download and /config/secrets/ endpoints each allow IAM users to be leased. Be sure to set include_dynamic_secrets to true at request time. dynamic_secrets_ttl_sec is also available for overriding the 30m TTL default.