GNU/LinuxAWS

AWS Roles Anywhere and Glacier

2024/03/16

AWS IAM Roles Anywhere

Over the years I’ve managed a number of servers for work. Some of which connect to AWS resources ( S3, EC2, Glacier, etc). Often the credentials were just strings stored in environment variables or a file the ./aws folder (with restricted permissions of course). These long-term credentials work but Amazon also provides a way to get temporary credentials.

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

Your jobs can use the same IAM policies and roles as AWS applications to access resources. But you no longer need to manage long-term credentials for workloads outside of AWS.

Non-AWS Workload Access

Workloads must use x.509 certificates issued by your Certificate Authority (CA).

You establish trust between IAM Roles Anywhere and your certificate authority (CA) by creating a Trust Anchor. A trust anchor is a reference to either an AWS Private CA or an external CA certificate. There can be several trust anchors in one AWS account.

Workloads outside of AWS authenticate with your trust anchor using certificates issued by your trusted CA. This lets you get temporary credentials.

IAM roles are IAM identities that you create in your account with specific permissions. 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. (aws:SourceArn must be set to the Trust Anchor’s ARN )

Profiles specify the roles IAM Roles Anywhere can access and what outside Workloads can do with the temporary credentials.

So basically we need the following things: 1. A Trusted Certificate Authority. Amazon has a way of dealing with it in the console but it isn’t free ($400 per private CA per month, 0.75 per certificate). For this article I’ll be using OpenSSL for my own CA. 2. A Trust Anchor 3. An IAM Role 4. An IAM Roles Anywhere Profile. 5. aws_signing_helper so my Python scripts can get temporary credentials.

Step 0. Preparing to Setup Roles Anywhere

Create Client Certificates

A key part of Roles Anywhere is proving your job / workload is who you say it is. This is done with signed certificates.

As a developer and Sys-Admin I’ve often needed self-signed certificates for various projects. I have some notes on creating a certificate authority and signing certificates here.

Important if you want to re-issue to the same name, update text.txt.attr to look like

unique_subject = no

First setup a folder for client certificates

cd .. 
mkdir client
cd client

Make a signing request and private key in the folder

openssl genrsa -out ggblog_key.pem 2048
openssl req -new -key ggblog_key.pem   -out ggblog_req.pem -outform PEM -subj /CN=www.greggallardo.com/O=blog/OU=ggblog -nodes   -config ../openssl.cnf

and sign it with the CA

cd ../CA
openssl ca -config ../openssl.cnf -in ../client/ggblog_req.pem -out ../client/ggblogcert.pem -notext -batch -extensions v3_client

This will create a certificate file named ggblog_clicert.pem. You will use this certificate and the private key to request temporary credentials once Roles Anywhere is setup.

If you want to set the validity period of the script instead of using the default value, use the -days flag.

cd ../CA
openssl ca -config ../openssl.cnf -in ../client/ggblog_req.pem -out ../client/ggblogcert.pem -notext -batch -extensions v3_client -days 7
Create Trust Anchor Policy

You may not need to do this step. I’ll depend on the permissions your AWS account has. When I setup a new mail server for a client, I had to go add a policy letting the my account create a trust anchor.

  1. Log in to AWS Management Console with an account that has the right privileges.

  2. Navigate to IAM: Go to the IAM dashboard.

  3. Go to policies on the left AWS Policies

  4. Press Create Policy

  5. Select JSON and set it to the following

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "rolesanywhere:CreateTrustAnchor",
                "rolesanywhere:ListTrustAnchors",
                "rolesanywhere:GetTrustAnchor",
                "rolesanywhere:UpdateTrustAnchor",
                "rolesanywhere:DeleteTrustAnchor",
                "rolesanywhere:CreateProfile",
                "rolesanywhere:ListProfiles",
                "rolesanywhere:GetProfile",
                "rolesanywhere:UpdateProfile",
                "rolesanywhere:DeleteProfile"
            ],
            "Resource": "*"
        }
    ]
}

AWS JSON Policy and press Next to go to the next screen.

  1. Set the name (in this case GgblogAws) and press Create Policy Create Policy

Once the policy is created or updated, make sure it shows up in your policies

Check for policy in policy list

You may need to wait for policy changes to propagate through the system, as there can sometimes be a short delay.

Step 1 of roles anywhere: Create a Trust Anchor

Important Make sure you’re in the right region when setting up your Roles Anyhere role. If things are missing, check your region

  1. Go to the IAM Roles Anywhere console. Amazon’s docs redirected me to east-1

IAM Roles Anywhere 2. Press Create a trust anchor 3. Give it a name in Trust anchor name. I went with “GGBlogAws” 4. For the source go with External certificate bundle

Paste the contents of your CA PEM file into it. CA Cert PEM 5. I skipped the optional data and went with Create Trust Anchor

Create Trust Anchor You should now see your new trust anchor in the list

New trust anchor in list

If your account doesn’t have the role to actually create trust anchor you’ll get an error like this:

User: arn:aws:iam::000000000000:user/balarm00  is not authorized to perform: rolesanywhere:CreateTrustAnchor on resource: arn:aws:rolesanywhere:us-east-1:000000000000:trust-anchor/* because no identity-based policy allows the rolesanywhere:CreateTrustAnchor action

You or a user with permission will need to add a Policy for working with Trust Anchors to your account.

Custom policy for the role

While AWS provides a policy that gives you full permissions on glacier resources, You might want to use custom policies to restric the role to specific actions.

  1. Navigate to IAM Policies: In the IAM console, go to the “Policies” section.
  2. Create Policy:
  • Click “Create policy”.
  • Choose the JSON tab.
    • Enter a custom policy that includes the specific permissions you need for Glacier, such as glacier:ListVaults and glacier:uploadArchive.
  1. Edit the JSON policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "glacier:ListVaults",
                "glacier:ListJobs",
                "glacier:UploadArchive",
                "glacier:UploadMultipartPart",
                "glacier:DescribeVault",
                "glacier:DescribeJob",
                "glacier:GetJobOutput",
                "glacier:InitiateVaultLock",
                "glacier:CompleteVaultLock",
                "glacier:AbortVaultLock",
                "glacier:InitiateJob"
            ],
            "Resource": "*"
        }
    ]
}

NOTE I have "Resource" set to *, which means the policy apply to all vaults. Which is OK for this blog post, but in the real-world you might want to restrict it to a specific value. You can use the ARN instead of "*" to restrict the resource

  1. Set the name. I named it GgblogS3Glacier

After creating the custom policy, it can be attached to the Roles Anywhere role you create.

Step 2: Create Role

To create the role, I navigated back back to Roles, scrolled to the bottom of the page, and pressed Manage under Roles Anywhere Manag Roles Anywhere I selected Step 2. Configure roles and pressed Create a New Role Create New Roll And went with Custom trust policy. Here you’ll edit the "Statement" section of the JSON Create Trust Policy

{
    "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:us-east-2:XXXXXXXXXXXX:trust-anchor/2017xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]},
                "StringEquals": {"aws:PrincipalTag/x509Subject/OU": "ggblog"}
            }
        }
    ]
}
  • condition ArnEquals ties this to the trust anchor. Your exact string will vary. You can get your Arn from the Trust Anchor page trust anchor ARN
  • condition StringEquals ties this to the client certificate with OU == ggblog. This was set when the certificate request was generated.

Press the next button to set the permissions. Since I want my roles anywhere jobs to access Glacier, I could add an existing policy Existing glacier policy Or use the custom policy I setup earlier by searching for it Custom S3 and Glacier Policy To finish up press Next again.

Give the new role a name. I went with “GgblogGlacierBackup” Name the role Then saved it by pressing Create Role.

A quick check under Roles shows it was created. New Role Created Thi should now be usable

Create a Profile

Also under Step 2 Configure roles is a Profiles section. Create a profile by pressing the Create a profile button Create a profile I set the name to ‘GgblogGlacierProfile’ and set Role to ‘GgblogGlacierBackup’ Configure Profile press the Create a Profile button to save it.

Step 3: Use Roles Anywhere

Amazon’s docs provide link to the AWS Signing Helper executable. Most of my servers are running linux, so I downloaded the Linux helper.

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

Running help on it shows me the basic flags:

$ ./aws_signing_helper credential-process --help
To retrieve AWS credentials in the appropriate format for external
credential processes, as determined by the SDK/CLI. More information can be
found at: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html

Usage:
  aws_signing_helper credential-process [flags]

Flags:
      --cert-selector string       JSON structure to identify a certificate from a certificate store. Can be passed in either as string or a file name (prefixed by "file://")
      --certificate string         Path to certificate file
      --debug                      To print debug output
      --endpoint string            Endpoint used to call CreateSession
  -h, --help                       help for credential-process
      --intermediates string       Path to intermediate certificate bundle file
      --no-verify-ssl              To disable SSL verification
      --pkcs11-lib string          Library for smart card / cryptographic device (OpenSC or vendor specific)
      --private-key string         Path to private key file
      --profile-arn string         Profile to pull policies from
      --region string              Signing region
      --reuse-pin                  Use the CKU_USER PIN as the CKU_CONTEXT_SPECIFIC PIN for private key objects, when they are first used to sign. If the CKU_USER PIN doesn't work as the CKU_CONTEXT_SPECIFIC PIN for a given private key object, fall back to prompting the user
      --role-arn string            Target role to assume
      --session-duration int       Duration, in seconds, for the resulting session (default 3600)
      --system-store-name string   Name of the system store to search for within the CERT_SYSTEM_STORE_CURRENT_USER context. Note that this flag is only relevant for Windows certificate stores and will be ignored otherwise (default "MY")
      --trust-anchor-arn string    Trust anchor to use for authentication
      --with-proxy                 To make the CreateSession call with a proxy

Which seems like a lot, but we don’t need all of them.

./aws_signing_helper credential-process \
    --certificate
    [--endpoint]
    [--region]
    [--intermediates]
    --private-key
    --profile-arn
    --role-arn
    [--session-duration]
    --trust-anchor-arn
    [--with-proxy]
    [--no-verify-ssl]

The most important flags are the certificate flags and ARNs of the ites we just created.

./aws_signing_helper credential-process \
    --certificate
    --private-key
    --profile-arn
    --role-arn
    --trust-anchor-arn

You can get the ARNs from AWS console. The certificate and private key files were created earlier. You just need to copy them somewhere you jobs can use them.

To get the --role-arn value go to IAM > Rolws and search for your Role. Once found there’s a link for copying it role arn To get the profile and trust anchor ARNs, goto Roles > Roles Anywhere. It has a list of your trust anchors and profiles. Navigating to these lets you copy your ARNsk Roles anywhere lists Once you have your ARNs and certificates in place, you can call aws_signing_helper as follows.

./aws_signing_helper credential-process \
    --certificate ./ggblogcert.pem \
    --private-key ./ggblog_key.pem \
    --role-arn    arn:aws:iam::XXXXXXXXXXXX:role/GgblogGlacierBackup \
    --profile-arn arn:aws:rolesanywhere:us-east-2:XXXXXXXXXXXX:profile/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX \
    --trust-anchor-arn arn:aws:rolesanywhere:us-east-2:518748733169:trust-anchor/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX

If all went well, you get something that looks like this:

{"Version":1, "AccessKeyId":"AXXXXXXXXXXXXXXXXXXX", "SecretAccessKey":"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY", "SessionToken":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ==", "Expiration":"2023-11-17T03:09:23Z"}

From here the temporary AccessKeyId, SecretAccessKey, and SessionToken can be used as needed with your scripts.

About Me

Greg Gallardo

I'm a software developer and sys-admin in Iowa. I use C++, C#, Java, Swift, Python, JavaScript and TypeScript in various projects. I also maintain Windows and Linux systems on-premise and in the cloud ( Linode, AWS, and Azure )

Github

Mastodon

YouTube

About you

IP Address: 18.118.93.61

User Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)

Language:

Latest Posts

Iowa City Weather

Overnight

42 ˚F / 46 ˚F

Friday Night

41 ˚F / 50 ˚F

Saturday Night

35 ˚F / 48 ˚F

Sunday Night

32 ˚F / 44 ˚F

Monday Night

30 ˚F / 35 ˚F

Tuesday Night

24 ˚F / 31 ˚F

Wednesday Night

19 ˚F / 28 ˚F