30

I am attempting to call the AssumeRole function using AWS sts in my PHP program since I want to create temporary credentials to allow a user to create an object for an AWS bucket.

Below is the fumction I am calling PHP:

  $sts = StsClient::factory(array(
                'key'    => 'XXXXXXXXXXXXXX',
                'secret' => 'XXXXXXXXXXXXXXXX',
                'token.ttd' => $timetodie
            ));             
  $bucket = "mybucket";             
            $result1 = $sts->assumeRole(array(          
                'RoleArn' => 'arn:aws:iam::123456789012:role/createPic',
                'RoleSessionName' => 'mytest',
                'Policy' => json_encode(array(
                        'Statement' => array(
                             array(
                                  'Sid' => 'Deny attributes',
                                  'Action' => array(
                                  's3:deleteObject', 
                                  's3:deleteBucket'
                                  ),
                                  'Effect' => 'Deny',
                                  'Resource' => array(
                                  "arn:aws:s3:::{$bucket}",
                                  "arn:aws:s3:::{$bucket}/AWSLogs/*"
                                  ),
                                  'Principal' => array(
                                  'AWS' =>   "*"
                                  )
                              ) 
                          )
                      )
                  ),
                'DurationSeconds' => 3600,
             //   'ExternalId' => 'string',
            ));
            
            $credentials  = $result1->get('Credentials');

However, I keep getting the following error:

User arn:aws:iam::123456789012:user/TVMUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/createPic

Below is my permissions policy for user TVMUser on my AWS console:

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":"ec2:RunInstances",
         "Resource":"*"
      },
      {
         "Effect":"Allow",
         "Action":"iam:PassRole",
         "Resource":"arn:aws:iam::791758789361:user/TVMUser"
      },
      {
         "Effect":"Allow",
         "Action":"sts:AssumeRole",
         "Resource":"arn:aws:iam::791758789361:role/createPic"
      }
   ]
}

Below is my role policy for the role createPic:

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":"ec2:RunInstances",
         "Resource":"*"
      },
      {
         "Effect":"Allow",
         "Action":"iam:PassRole",
         "Resource":"arn:aws:iam::791758789361:user/TVMUser"
      },
      {
         "Effect":"Allow",
         "Action":"sts:AssumeRole",
         "Resource":"arn:aws:iam::791758789361:role/createPic"
      }
   ]
}

Does anyone now what I am missing in my AWS policy statements and setup on AWS so I don't get the following error?

User arn:aws:iam::123456789012:user/TVMUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/createPic

Am I missing something?

alessiosavi
  • 2,753
  • 2
  • 19
  • 38
Dave
  • 873
  • 2
  • 15
  • 27
  • 4
    I assume the resource in the permission assumeRole 791758789361 is a typo and you mean 123456789012. – bennie j Feb 24 '14 at 12:08

3 Answers3

95

You also need to edit the Trust relationship for the role to allow the account (even if it's the same) to assume the role.

  1. open the role that you want to assume in the console
  2. click on the "Trust Relationships" tab
  3. click on "Edit RelationShip"
  4. add a statement for the account that you want to add (usually you'll only have the ec2 service in the "Trusted Entities") e.g.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/some-role"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

In this example I had to add the "AWS" principal with the proper account number, the ec2.amazonaws.com Service was already there.

After I've done that I was able to assume the role without issue. Took me literally hours to figure this out, hope that will help someone.

Old Pro
  • 24,624
  • 7
  • 58
  • 106
WispyCloud
  • 4,140
  • 1
  • 28
  • 31
  • 7
    This was a huge help, thank you. For anyone interested, this is documented [here](http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-sharing-logs-third-party.html). What's not clear is that this has to be done even for the account that owns the role. – Matt Cole Dec 20 '15 at 13:30
  • 2
    Dude you are a life saver. Took me hours and could not figure out why I was getting denied. – gkrizek Sep 30 '16 at 03:51
  • 1
    Glad it helps. Btw I updated the example to use a more restricted role than `root` which is better from a security perspective. – WispyCloud Sep 30 '16 at 10:40
  • Thanks a lot. It helped me to solve my issue. We need to give every user in trusted entities who wants to assume this role to perform operations – SASI Oct 11 '16 at 13:19
  • This really helped! – Emmanuel Gabriel Nov 23 '21 at 15:58
  • 1
    Thanks. Just to add that you may combine both statement into one by merging them inside the Principal object as different field where one is Service and the other is AWS. You can even put the field value as array of string instead of string if you have more than one same field Principal. – Sany Liew Jan 10 '22 at 15:46
  • 1
    After I add this to the target role's `Trust relationships` JSON, I get `error: You must be logged in to the server (Unauthorized)` when running an `aws` command. – Parziphal Feb 09 '22 at 05:20
8

I had the same error and spent hours trying to fix it with permissions and trust relationships... but that was not my problem.

I was following this tutorial and I deployed the cluster in US West (Oregon) as specified.

To make it work, I needed to activate STS for this region here.

enter image description here

Thierry G.
  • 295
  • 4
  • 13
2

Maybe you should assign your sts region and endpoint:

$sts = StsClient::factory(array(
    //...      
    'region'   => 'us-west-2',                                                                                                                                                                              
    'endpoint' => 'https://sts.us-west-2.amazonaws.com', 
));