This article will introduce you to IAM Roles Anywhere, the underlying concept of public key infrastructure, and finally, a demo shell script that showcases the steps required to use IAM Role Anywhere as well as the steps required to generate certificates for it.
Before we jump into IAM Roles Anywhere, it is important to understand some basic concepts related to PKI:
It uses a pair of a public key (not secret) and a private key (secret). It can be used for encryption or digital verification, as illustrated by the following diagrams from Wikipedia The public key can be used to encrypt text, and the encrypted text can only be decrypted by someone who has the corresponding private key. Alternatively, the private key can be used to sign text, and the public key can be used to verify that the text was signed using the private key.
Since asymmetric cryptography is computationally expensive, it is usually combined with symmetric cryptography. This is done by using asymmetric cryptography to encrypt and exchange a symmetric key (a single key used to both encrypt and decrypt data) which is then used to encrypt the actual data being exchanged.
The Certificate Authority verifies that a public key is actually associated with the claimed user since the public key needs to be uncompromised (not modified by a man-in-the-middle attack for example) for asymmetric key based communication between two entities to be actually secure. It does the verification using its own private key, so it is important for any entity using the Certificate Authority for verification to already have built-in trust in the Certificate Authority.
X.509 is an International Telecommunication Union (ITU) standard that defines the format used for public key certificates. It associates a public key with an identity using a digital signature.
IAM Roles Anywhere use Public Key Infrastructure to verify the identity of an on-premise workload and then generate valid AWS credentials for the workload.
In order to use IAM Roles Anywhere, you need to register a Certificate Authority (CA) with IAM Roles Anywhere. IAM Roles Anywhere uses the term trust anchor for registered certificate authorities.
There are two options for Certificate Authorities with IAM Roles Anywhere:
An IAM Role is an IAM identity in an AWS account that has a specific set of permissions. Based on its trust policy, it can be assumed by whoever needs access to it. This can be an AWS service, a program, a human user, etc. based on how it is configured. IAM Roles Anywhere allows entities outside AWS to assume IAM Roles and generate temporary AWS credentials, without having to use long-term credentials which can be potentially compromised. In order for a role to be usable with IAM Roles Anywhere, it should trust rolesanywhere.amazonaws.com
in its trust policy. More details on different trust policy configurations and how they should be restricted can be found here.
Important: The demo script given below uses a very simple trust policy with no condition keys, but for actual production implementations, it is highly recommended to add condition keys to your trust policy.
A profile is created in IAM Roles Anywhere to determine which Roles can be assumed by a workload through IAM Roles Anywhere. Optionally, you can also add IAM policy statements to further restrict actions that are allowed, so that the workload only has a subset of the permissions provided by the IAM Role. Note that IAM policies added here cannot be used to grant additional permissions which are not already allowed by the role, they can only restrict permissions allowed by the role.
Certificates for your certificate authority need to fulfill the following requirements (Reference):
Certificates for your end entity need to fulfill the following requirements (Reference):
You can find all the scripts used for the demo and supporting config files here.
1{2 "Version": "2012-10-17",3 "Statement": [4 {5 "Sid": "IAM",6 "Effect": "Allow",7 "Action": [8 "iam:PassRole",9 "iam:CreateRole",10 "iam:DeleteRole"11 ],12 "Resource": "arn:aws:iam::*:role/demo-rolesanywhere"13 },14 {15 "Sid": "RolesAnywhere",16 "Effect": "Allow",17 "Action": [18 "rolesanywhere:DeleteTrustAnchor",19 "rolesanywhere:ListProfiles",20 "rolesanywhere:DeleteProfile",21 "rolesanywhere:ListTrustAnchors",22 "rolesanywhere:CreateTrustAnchor",23 "rolesanywhere:CreateProfile"24 ],25 "Resource": "*"26 }27 ]28}
The following script is used to generate:
certificate_authority_private.key
certificate_authority_cert.pem
client_private.key
client.csr
client_cert.pem
1# openssl commands are adapted from https://jimmydqv.com/iam-anywhere/23# The following files are required:4# - certificate_authority.conf Configuration for CA certificate5# - client.conf Configuration for client CSR6# - client_v3.ext Extensions file for CSR7# See repository code for samples89# Generate private key for CA10openssl genrsa -out certificate_authority_private.key 409611# Generate certificate for CA12openssl req -new -x509 -days 365 -config certificate_authority.conf -key certificate_authority_private.key -out certificate_authority_cert.pem -extensions v3_ca13# Show certificate for CA14openssl x509 -text -noout -in certificate_authority_cert.pem1516# Generate private key for client17openssl genrsa -out client_private.key 409618# Generate Certificate Signing Request19openssl req -new -config client.conf -key client_private.key -out client.csr20# Show CSR21openssl req -text -in client.csr22# Generate certificate signed using CA23openssl x509 -req -in client.csr -CA certificate_authority_cert.pem -CAkey certificate_authority_private.key -set_serial 01 -out client_cert.pem -days 365 -sha256 -extfile client_v3.ext24# Show certificate for client25openssl x509 -text -noout -in client_cert.pem
The following script is used for the following:
aws sts get-caller-identity
to verify credentials1# Get value of CA certificate2value=`cat certificate_authority_cert.pem`3# Create roles anywhere trust anchor using CA certificate4trust_anchor_arn=$(aws rolesanywhere create-trust-anchor --enabled --name demo-trust-anchor --source "sourceData={x509CertificateData=$value},sourceType=CERTIFICATE_BUNDLE" --query 'trustAnchor.trustAnchorArn' --output text)5# Create IAM role which will be assumed6role_arn=$(aws iam create-role --role-name demo-rolesanywhere --assume-role-policy-document file://iam_role_trust_policy.json --query 'Role.Arn' --output text)7# Create roles anywhere profile linking trust anchor to role8profile_arn=$(aws rolesanywhere create-profile --enabled --name demo-profile --role-arns "$role_arn" --query 'profile.profileArn' --output text)9# Sleep to allow above changes to propogate10echo "Sleeping for 20 seconds"11sleep 2012# Generate credentials13credentials=$(./aws_signing_helper credential-process \14 --certificate client_cert.pem \15 --private-key client_private.key \16 --trust-anchor-arn $trust_anchor_arn \17 --profile-arn $profile_arn \18 --role-arn $role_arn)19access_key_id=$(echo $credentials | jq -r ".AccessKeyId")20secret_access_key=$(echo $credentials | jq -r ".SecretAccessKey")21session_token=$(echo $credentials | jq -r ".SessionToken")22# Verify credentials23AWS_ACCESS_KEY_ID=$access_key_id AWS_SECRET_ACCESS_KEY=$secret_access_key AWS_SESSION_TOKEN=$session_token aws sts get-caller-identity
The following script is used for the following:
1# Remove all private keys, certificates and CSR2rm *.key3rm *.pem4rm *.csr5# Get profile ID using name6profile_id=$(aws rolesanywhere list-profiles --query 'profiles[?name==`demo-profile`].profileId' --output text)7# Get trust anchor ID using name8trust_anchor_id=$(aws rolesanywhere list-trust-anchors --query 'trustAnchors[?name==`demo-trust-anchor`].trustAnchorId' --output text)9# Delete profile10aws rolesanywhere delete-profile --profile-id $profile_id11# Delete role12aws iam delete-role --role-name demo-rolesanywhere13# Delete trust anchor14aws rolesanywhere delete-trust-anchor --trust-anchor-id $trust_anchor_id
While IAM Roles Anywhere does not use traditional long-lived AWS credentials like those associated with an IAM user, it still relies on the private key for your certificates remaining secret. It is important that your CA or client private keys are not compromised, otherwise, it is possible for an attacker to generate AWS credentials for your account.