Blog by Saw Win Naung

Official

Securing External Workloads with AWS IAM Roles Anywhere


In this post, I’ll walk you through setting up IAM Roles Anywhere with a CFSSL certificate infrastructure. We’ll cover everything from certificate requirements to practical implementation, giving you a production-ready solution for secure external authentication.

What is AWS IAM Roles Anywhere?

AWS IAM Roles Anywhere extends the familiar IAM role model to workloads outside of AWS. Instead of managing static access keys, your external applications can use X.509 certificates to assume IAM roles and obtain temporary, scoped credentials. This approach provides several key benefits:

Let’s dive into how to implement this securely.

Understanding Certificate Requirements

Before we jump into implementation, it’s crucial to understand what AWS expects from your certificates. IAM Roles Anywhere is particular about certificate formats and extensions.

CA Certificate Requirements

Your Certificate Authority (CA) certificate needs to meet specific criteria to serve as a Trust Anchor:

Client Certificate Requirements

The client certificates that your workloads will use have their own set of requirements:

Getting these requirements right is critical - AWS will reject certificates that don’t meet these specifications.

Install CFSSL with Ansible

To streamline the CFSSL installation and configuration process, I’ve created a comprehensive Ansible role that automates the entire PKI setup. This role handles everything from binary installation to CA certificate generation.

CFSSL Certificate Authority Ansible Role

This role installs and configures CFSSL, CloudFlare’s PKI/TLS toolkit, to create a Certificate Authority (CA) for your infrastructure.

Key Features

Quick Start

- hosts: ca_server
  roles:
    - cfssl

Custom Configuration

- hosts: ca_server
  vars:
    ca_common_name: "My Company Root CA"
    ca_organization: "My Company"
    cfssl_api_bind_address: "0.0.0.0" # Allow external access
  roles:
    - cfssl

Role Variables

The role provides extensive customization options:

CA Configuration:

API Server:

Post-Installation Usage

After running the Ansible role, you can immediately start issuing certificates:

# Issue a server certificate via API
curl -X POST -H "Content-Type: application/json" \
  -d @server-csr.json \
  http://127.0.0.1:8888/api/v1/cfssl/newcert

The role creates three certificate profiles:

Preparing Your CA Certificate

The first step in setting up IAM Roles Anywhere is preparing your CA certificate for use as a Trust Anchor. If you’re using CFSSL like I am, this process is straightforward.

./scripts/export-ca-for-aws.sh

This handy script handles the heavy lifting:

For a 2-tier PKI setup, you’ll want to use the intermediate CA certificate (./certs/intermediate-ca.pem) as your Trust Anchor in AWS. This gives you better operational flexibility while maintaining security.

Creating Client Certificates

Now for the fun part - generating client certificates that your workloads will use for authentication. I’ve created a script that handles all the AWS-specific requirements:

./scripts/generate-aws-client-cert.sh -n client-name

The script offers several useful options:

What makes this script special? It automatically:

No more guessing whether your certificates will work - the script ensures they meet AWS specifications from the start.

Configuring AWS IAM Roles Anywhere

With your certificates ready, it’s time to configure the AWS side. This involves three key components: Trust Anchors, Profiles, and IAM Roles.

Creating a Trust Anchor

The Trust Anchor tells AWS which CA certificates to trust. Think of it as registering your PKI with AWS:

  1. Navigate to the AWS IAM Roles Anywhere console
  2. Click “Create trust anchor”
  3. Give it a descriptive name and optional description
  4. Select “Certificate bundle” as the source type
  5. Upload your intermediate CA certificate (./certs/intermediate-ca.pem)
  6. Click “Create trust anchor”

Setting Up a Profile

Profiles act as a bridge between your certificates and IAM roles. They define which roles can be assumed and any additional session policies:

  1. In the IAM Roles Anywhere console, navigate to “Profiles”
  2. Click “Create profile”
  3. Enter a meaningful name and description
  4. Optionally add session policies for additional restrictions
  5. Click “Create profile”

Configuring IAM Role Trust Relationships

Here’s where the magic happens. You need to modify your IAM role’s trust policy to allow IAM Roles Anywhere to assume it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rolesanywhere.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "YOUR_ACCOUNT_ID"
        },
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:rolesanywhere:REGION:ACCOUNT_ID:trust-anchor/TRUST_ANCHOR_ID"
        }
      }
    }
  ]
}

This trust policy is crucial for security. The conditions ensure that only requests from your specific account and Trust Anchor can assume the role. Replace the placeholder values with your actual account ID, region, and Trust Anchor ID.

Putting It All Together: Authentication in Action

Now comes the exciting part - actually using your certificates to authenticate with AWS. You’ll need the AWS Signing Helper, a tool that handles the certificate-based authentication flow.

Installing the AWS Signing Helper

First, let’s get the signing helper installed:

# Download the AWS Signing Helper
curl -Lo aws_signing_helper https://rolesanywhere.amazonaws.com/releases/1.7.0/X86_64/Linux/aws_signing_helper

# Make it executable
chmod +x aws_signing_helper

# Move to a directory in your PATH
sudo mv aws_signing_helper /usr/local/bin/

Getting Temporary Credentials

The signing helper can obtain credentials directly:

aws_signing_helper credential-process \
  --certificate ./certs/client-name.pem \
  --private-key ./certs/client-name-key.pem \
  --trust-anchor-arn arn:aws:rolesanywhere:REGION:ACCOUNT_ID:trust-anchor/TRUST_ANCHOR_ID \
  --profile-arn arn:aws:rolesanywhere:REGION:ACCOUNT_ID:profile/PROFILE_ID \
  --role-arn arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME

Seamless AWS CLI Integration

For the best experience, integrate this with the AWS CLI by adding a profile to your ~/.aws/config:

[profile roles-anywhere]
credential_process = aws_signing_helper credential-process --certificate ./certs/client-name.pem --private-key ./certs/client-name-key.pem --trust-anchor-arn arn:aws:rolesanywhere:REGION:ACCOUNT_ID:trust-anchor/TRUST_ANCHOR_ID --profile-arn arn:aws:rolesanywhere:REGION:ACCOUNT_ID:profile/PROFILE_ID --role-arn arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME

Now you can use AWS CLI commands seamlessly:

aws s3 ls --profile roles-anywhere

The credentials are obtained automatically using your certificate - no static keys in sight!

Manual Certificate Inspection

Sometimes you need to dig deeper. These OpenSSL commands are invaluable:

# View detailed certificate information
openssl x509 -in ./certs/client-name.pem -noout -text

# Verify the certificate chain
openssl verify -CAfile ./certs/ca-chain.pem ./certs/client-name.pem

Look for the key usage extensions and basic constraints to ensure they match AWS requirements.

Additional Resources