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:
- Enhanced Security: No more long-lived credentials to manage or rotate
- Familiar Model: Uses the same IAM roles and policies you already know
- Audit Trail: All credential requests are logged in CloudTrail
- Fine-grained Control: Leverage IAM’s powerful permission system
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:
- X.509 v3 format - Modern certificate standard
- Basic Constraints: Must include
CA:TRUE - Key Usage: Digital Signature, Certificate Sign, and CRL Sign
- Signing Algorithm: SHA256 or stronger (no SHA1!)
Client Certificate Requirements
The client certificates that your workloads will use have their own set of requirements:
- X.509 v3 format - Consistency with the CA
- Basic Constraints: Must include
CA:FALSE(these aren’t CAs themselves) - Key Usage: Digital Signature capability
- Extended Key Usage: Client Authentication is essential
- Signing Algorithm: SHA256 or stronger
- Chain of Trust: Must be signed by your registered Trust Anchor
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
- Automated Installation: Downloads and installs CFSSL binaries from official GitHub releases
- Complete PKI Setup: Creates both Root CA and Intermediate CA certificates
- API Server Configuration: Sets up CFSSL API server for programmatic certificate issuance
- Security Best Practices: Implements dedicated user accounts and proper file permissions
- Service Management: Configures systemd service for automatic startup
- Multiple Profiles: Supports server, client, and peer certificate profiles
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:
ca_common_name: Root CA common name (default: “SWN Lab Root CA”)ca_organization: Organization name (default: “SWN Lab”)ca_expiry: Root CA expiry (default: “87600h” - 10 years)ca_key_algorithm: Key algorithm (default: “rsa”)ca_key_size: Key size (default: 4096)
API Server:
cfssl_api_enabled: Enable API server (default: true)cfssl_api_port: API server port (default: 8888)cfssl_api_bind_address: Bind address (default: “127.0.0.1”)
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:
- server: For TLS server authentication
- client: For TLS client authentication
- peer: For both server and client authentication
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:
- Exports both root and intermediate CA certificates
- Creates a combined CA chain for verification
- Validates the certificate chain integrity
- Provides clear guidance on which certificate to upload
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:
-n, --name: Certificate name (required)-e, --email: Email address for the certificate subject-o, --output: Output directory (defaults to ./certs)-a, --api: Use CFSSL API instead of local files--org,--ou,--country,--state,--city: Subject information
What makes this script special? It automatically:
- Generates certificates with AWS-compatible constraints
- Sets the correct key usage flags
- Includes Subject Alternative Names (SAN) when needed
- Verifies compatibility with IAM Roles Anywhere requirements
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:
- Navigate to the AWS IAM Roles Anywhere console
- Click “Create trust anchor”
- Give it a descriptive name and optional description
- Select “Certificate bundle” as the source type
- Upload your intermediate CA certificate (
./certs/intermediate-ca.pem) - 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:
- In the IAM Roles Anywhere console, navigate to “Profiles”
- Click “Create profile”
- Enter a meaningful name and description
- Optionally add session policies for additional restrictions
- 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
- GitHub Repository: CFSSL Ansible Role and Scripts
- CFSSL Documentation: CloudFlare PKI Toolkit