This content originally appeared on DEV Community and was authored by John McCracken
Introduction
IAM user access keys are the normal way to access AWS from an external source. Generally this is the method to use for machine/code access to your AWS estate.
This is ok, but come with some issues:
- Long lived credentials expand the window of opportunity for an attacker to exploit the access key.
- Rotating secrets can be hard to manage; synchronising credentials rotating with third parties can be complex.
- It just doesn't scale, anything over a handful of access keys becomes hard to manage.
The AWS preferred solution is to use AWS IAM Roles Anywhere for workloads outside of AWS.
- Short term rotating credentials
- Uses industry standard X.509 certificates
- Reduces management complexity
Although a bit more complex to set up, AWS IAM Roles Anywhere is a much more elegant, scalable solution for workloads. It also ticks all current AWS security best practices.
How does IAM Roles Anywhere work?
- Workloads use SSL Certificates (end-entity certificate) which have been signed by a Certificate Authority (CA). The CA can either be external or provided by AWS.
- Create a Trust Anchor between IAM Roles Anywhere and the CA
- Create a Profile, which defines the IAM policy to apply after successful authentication
Be aware that although IAM Roles Anywhere is free, if you use AWS Private CA there will be a cost, it’s around $400 per month! I believe you can cancel within the first 30 days free of charge.
In this demo, I’ll stick with a free external self generated one. Its a bit of a pain to generate, but hopefully this demo makes it as painless as possible.
What this guide intends to do
- Generate an external CA
- Generate an end-entity certificate which is signed off against the CA.
- Setup a IAM Roles Anywhere Trust Anchor with the CA certificate
- Setup a IAM Roles Anywhere Profile and link a IAM Policy
- Setup a local machine to use aws_signing_helper in an AWS Profile.
- Demonstrate it works with AWS CLI and Python/boto3. ##Setting up IAM Roles Anywhere
I’ve tried to script as much as possible, that way you can get it running as quickly as possible and it still offers the full details for those who want to dig deeper under the hood.
I’ve created a repo for all this goodness: aws-iam-roles-anywhere-public-demo
This contains the following:
- Shell script to generate CA and end certificates
- Terraform to deploy to AWS
- Python example script to test access
All instructions are for Linux/MacOS. If you're using Windows, you've got bigger problems than trying to follow this blog.
Generate a Certificate Authority and a End Entity Certificate
On the CLI and clone the repo and go to the root directory. There is a bash script located here called create-ca.sh
which can be used to automatically generate the required Certificates.
This uses a config file root-ca/root-ca.conf
, you can use the default values or edit to suit your requirements.
Open the script create-ca.sh and have a look over what it's actually doing, the comments hopefully help clarify.
The certificates values are stored in root-ca.conf and client-ca.conf.
Once you're comfortable with the contents, run the script:
sh ./create-ca.sh
When prompted, select Y for any prompts.
You should now have the following created in the root-ca folder:
- certs folder containing a CA .pem file
- db folder with CA version data
- private folder with a private key and certificate signing request file
- clients folder with end-entity certificate key/pem file
This is all the files required to get started. Be aware this is all basic stuff and shouldn't be used in a production environment.
Note: this script copies the following files from the ./clients/ folder into your ~/.ssh folder:
~/.ssh/iam-roles-anywhere-demo.key
~/.ssh/iam-roles-anywhere-demo.crt
Please delete these manually afterwards.
Deploy the Infrastructure as Code
Feel free to deploy by click-ops, it's pretty self explanatory, but everything really should be IaC.
Make sure you have authenticated to the AWS account you wish to use, by pasting Access keys into the CLI or however you normally do it.
From the root directory, cd terraform
then
terraform init
terraform apply
Plan output should create the following:
aws_rolesanywhere_trust_anchor
Create a Trust Anchor, this connects IAM Roles Anywhere to the certificate.
aws_iam_role
This is the role used by IAM Anywhere, it has a condition that the certificate Common Name (CN) must be ‘IAM Anywhere Demo’.
aws_iam_role_policy_attachment
Attach the managed policy AmazonS3ReadOnlyAccess to the role
aws_rolesanywhere_profile
Create an IAM Roles Anywhere Profile called ‘iam-roles-anywhere-demo’. Note that the profile also is linked to the managed policy AmazonS3ReadOnlyAccess. The profile can set the maximum permission boundary.
For example, if I had attached AmazonS3FullAccess to the role, the Profile permissions would restrict S3 permissions to read only.
Check over the plan and if all looks good to you, type yes to deploy.
If all goes well, the resources should be deployed to your specified AWS Account.
The output should contain a key credential_process, copy the value for this key and paste it somewhere safe for now. This outputs the aws command required later to authenticate. It should be something similar to this:
credential_process = "~/.aws/aws_signing_helper credential-process --certificate ~/.ssh/iam-roles-anywhere.crt --private-key ~/.ssh/iam-roles-anywhere.key --trust-anchor-arn arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:trust-anchor/880ee543-af45-48c7-b5cd-bf0b73e95059 --profile-arn arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:profile/048f1bf7-da4c-41cd-99ed-ee6b93021297 --role-arn arn:aws:iam::ACCOUNTID:role/iam-roles-anywhere-demo"
profile-arn = "arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:profile/048f1bf7-da4c-41cd-99ed-ee6b93021297"
role-arn = "arn:aws:iam::ACCOUNTID:role/iam-roles-anywhere-demo"
trust-anchor-arn = "arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:trust-anchor/880ee543-af45-48c7-b5cd-bf0b73e95059"
Test AWS Access
If you want to view the resources in the AWS console, go to the IAM Dashboard, then Roles and then scroll to the bottom of the main window.
Firstly, AWS provide aws_signing_helper to simplify access, download and install, make sure its in your PATH
.
You can use this file to retrieve short term credentials and then add them to environmental variables as you can with AWS IAM access keys, but I have found a better way is to update the ~/.aws/config
file:
Open ~/.aws/config
and create a new entry profile:
[profile iam-roles-anywhere-demo]
Now directly below this, paste the Terraform output mentioned previously, so it should end up something like this:
[profile iam-roles-anywhere-demo]
credential_process = aws_signing_helper credential-process --certificate ~/.ssh/iam-roles-anywhere.crt --private-key ~/.ssh/iam-roles-anywhere.key --trust-anchor-arn arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:trust-anchor/880ee543-af45-48c7-b5cd-bf0b73e95059 --profile-arn arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:profile/048f1bf7-da4c-41cd-99ed-ee6b93021297 --role-arn arn:aws:iam::ACCOUNTID:role/iam-roles-anywhere-demo
profile-arn = "arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:profile/048f1bf7-da4c-41cd-99ed-ee6b93021297"
role-arn = "arn:aws:iam::ACCOUNTID:role/iam-roles-anywhere-demo"
trust-anchor-arn = "arn:aws:rolesanywhere:eu-west-1:ACCOUNTID:trust-anchor/880ee543-af45-48c7-b5cd-bf0b73e95059”
Now save and exit file
Note: You might need to replace /.ssh
with the full path, in my case this was /Users/john.mccracken/.ssh
Testing with AWS CLI
aws sts get-caller-identity --profile iam-roles-anywhere-demo
{
"UserId": "XXXX",
"Account": "1234567890",
"Arn": "arn:aws:sts::1234567890:assumed-role/iam-roles-anywhere-demo/00bc75fc5a6709cca9402a061453a2f3a9"
}
Then try
aws s3 ls --profile iam-roles-anywhere-demo
Testing programmatically with Python/boto3
In the python-iam-anywhere-test folder, there is a test.py file which will list buckets from the Account, there is a poetry.lock file with the required dependencies (boto3).
From the root directory, cd python-iam-anywhere-test
then
poetry install
poetry run python test.py
This should list all S3 buckets.
Conclusion
IAM Roles Anywhere is a great elegant solution for external access to AWS resources. Setting up your own CA is a pain, but it's once done, the integration with AWS is pretty seamless and straightforward.
aws_signing_helper makes life really simple, if you want an idea of how complex the process is under the hood, check out the repo.
Now I have IAM Roles Anywhere setup, I intend to use it going forward rather than access keys.
Any feedback, please get in touch. I'd love to hear from you.
Additional links
Always standing on the shoulder of giants:
This content originally appeared on DEV Community and was authored by John McCracken

John McCracken | Sciencx (2025-08-24T19:00:20+00:00) AWS IAM Roles Anywhere Demo. Retrieved from https://www.scien.cx/2025/08/24/aws-iam-roles-anywhere-demo/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.