Assuming an IAM role from an EC2 instance with its own assumed IAM role

In AWS IAM’s authentication infrastructure, it’s possible for one IAM role to assume another. This is useful if, for example, a service application runs as an assumed role on EC2, but then wishes to assume another role.

We wanted one of our applications to be able to get temporary credentials for a role via the AWS Security Token Service (STS).

In our application (Clojure) code, this looked something like:

(defn- get-temporary-assumee-role-creds []
  (let [sts-client (AWSSecurityTokenServiceClient.)
        assume-role-req (-> (AssumeRoleRequest.)
                            (.withRoleArn "arn:aws:iam::111111111111:role/assumee")
                            (.withRoleSessionName "assumer-service"))
        assume-role-result (.assumeRole sts-client assume-role-req)]
    (.getCredentials assume-role-result)))

This code is running as role assumer and wants to assume IAM role assumee.

The assumer role must have an attached policy giving it the ability to assume the assumee role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111111111111:role/assumee"
        }
    ]
}

And, importantly, the assumee role must have a trust policy like:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:role/assumer"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The above trust policy is for the assumee role and explicitly grants the assumer role the ability to assume the assumee role (whew).

Without the roles and policies properly configured, it isn’t possible to assume the role. An example error:

assumer-box$ aws sts assume-role --role-arn arn:aws:iam::111111111111:role/assumee --role-session-name sess

A client error (AccessDenied) occurred when calling the AssumeRole operation: User: arn:aws:sts::111111111111:assumed-role/assumer/i-06b6226fe698e565e is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/assumee