Service Accounts using IAM Roles Anywhere

We have numerous use cases, wherein access to AWS services like S3 buckets is required without SSO-based authentication. To achieve that, we can create service accounts using AWS IAM service, but it comes with the below drawbacks,

  1. The overhead of maintaining/rotating secret Access Keys
  2. The risk associated with users copying the secrets out of designated machines

We can move away from service accounts, by implementing IAM Roles anywhere service provided by AWS.

Brief Overview

You can use AWS Identity and Access Management Roles Anywhere to obtain temporary security credentials in IAM for workloads such as servers, containers, and applications that run outside of AWS. To use IAM Roles Anywhere, you need to set up,

  • Trust anchors – TAs establish trust between IAM Roles Anywhere and your certificate authority (CA). We can create a Private CA on AWS, but citing its cost, we can create trust between our own organization’s CA established under the domain technokofe.com. Servers or Users, outside of AWS, authenticate with the trust anchor using certificates issued by the trusted CA in exchange for temporary AWS credentials.
  • Roles – For IAM Roles Anywhere to be able to assume a role and deliver temporary AWS credentials, the role must trust the IAM Roles Anywhere service principal.
  • Profiles – In a profile, we will define IAM session policies, which can be managed or inline, to limit the permissions created for a session. 

AWS Configuration

Step 1: The first step for the configuration is, setting up of trust anchor under IAM roles anywhere. The code for this is here.

Option 1

If we are using Certificate Authority setup on AWS, we can issue & download certificates from AWS Certificate Manager. All the codes for this setup are here

Option 2

If we are using self-hosted Root CA, we can download the certificate from Root CA and pass it over as a .pem file to Trust Anchor.

Step 2: As part of creating a profile, we need to create a role that can be assumed and associated permissions. The below config will be provided in a trust relationship.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "rolesanywhere.amazonaws.com"
                ]
            },
            "Action": [
              "sts:AssumeRole",
              "sts:TagSession",
              "sts:SetSourceIdentity"
            ],
            "Condition": {
              "ArnEquals": {
                "aws:SourceArn": [
                  "arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID"
                ]
              }
            }
        }
    ]
}

Step 3: This role is then associated with the new profile.

Step 4: Create associated permission to access relevant AWS services. Below is a sample config for assuming roles across different accounts,

    {
        "Statement": [
            {
                "Action": [
                    "sts:*"
                ],
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": [
                            "86.30.200.0/24"
                        ]
                    }
                },
                "Effect": "Allow",
                "Resource": "arn:aws:iam::330895451783:role/role-cross-account"
            }
        ],
        "Version": "2012-10-17"
    }

    Host-level Configuration

    While configuration on the AWS is one part, ultimately users have to be able to obtain temporary creds from AWS, by calling assume-role API. This is a two-step process.

    Step 1: To obtain temporary security credentials from AWS Identity and Access Management Roles Anywhere, use the credential helper tool that IAM Roles Anywhere provides.

    wget https://rolesanywhere.amazonaws.com/releases/1.1.1/X86_64/Linux/aws_signing_helper

    Step 2: Create a new CSR from the remote machine and get it signed with Root CA to obtain the certificate. This is not required if using AWS-hosted private CA as you can issue a signed certificate from AWS Private CA and AWS certificate manager.

    openssl req -newkey rsa:4096 -keyout roles.key -out roles.csr

    Optionally, the certificate may be downloaded in .cer format. Convert it to .pem before continuing.

    Step 3: AWS signing helper tool can only work with readable certificates in text format. Hence we have to extract it out.

    openssl x509 -text -noout -in certificate.pem
    openssl rsa -in roles.key -out roles.txt

    Finally, Obtain the access credentials by running the helper tool.

    ./aws_signing_helper credential-process --region eu-west-2 \
     --profile-arn arn:aws:rolesanywhere:eu-west-2:330895451783:profile/436d487c-a74c-42b3-84c5-aea767c8519b. \
     --role-arn arn:aws:iam::330895451783:role/iam-roles-anywhere \
     --trust-anchor-arn arn:aws:rolesanywhere:eu-west-2:330895451783:trust-anchor/a02ad918-e4e5-4d81-84ff-54b4ddf43477 \
     --certificate ./cert.txt \
     --private-key ./roles.txt --session-duration 43200

    Unique Challenges

    Well I got couple of challenges, which I will cover in my next blog.

    • If we are using Roles chaining, i.e. a role assuming another role, maximum duration for the session is 1 hour. To overcome that I had to write a SDK with refreshable creds.
    • SDKs, relies on ~/.aws/config file to authenticate, hence I had to add a static entry to run AWS Helping tool under it (which thankfull is supported 🙂 )

    Comments

    No comments yet. Why don’t you start the discussion?

    Leave a Reply

    Your email address will not be published. Required fields are marked *