(MalformedPolicyDocument) AssumeRole policy may only specify STS AssumeRole actions - amazon-iam

This question has been answered here but it didn't solve my problem.
I get the An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: AssumeRole policy may only specify STS AssumeRole actions when I try to call aws iam create-role --role-name AutoscalingRole-Name --assume-role-policy-document file://./IAM_Trust_Policy.json
If my IAM_Trust_Policy.json contains only this code:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
}
It's working like a charm. But I needed something more, I'm creating an autoscaling role and I have a policy with these requirements:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"autoscaling.amazonaws.com"
]
},
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeLaunchTemplateVersions"
]
}
}
And for some reason I get the An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: AssumeRole policy may only specify STS AssumeRole actions
Can anyone see where I'm wrong? Thanks

As #luk2302 commented, you are mixing up two policy types. Both are required for your Role to be useful:
Trust Policy: whom you allow to assume the role
This is your first policy document
Principal is required - this is whom you allow
Use this as the AssumeRolePolicyDocument parameter in CreateRole .
Access/Permissions Policies: the permissions the role will have
This is your second policy document
Principal is not allowed - makes no sense here
There are two ways to attach these permissions to your role (aka Identity-based Policies):
As a standalone Managed Policy with AttachRolePolicy
Or as an Inline Policy embedded in your role with PutRolePolicy
In other words, remove the Principal from your second policy document and call PutRolePolicy to embed it with your role.

You can not use role policy with assume-role-policy.
I think you are trying to rediscover the wheel.
AWS has one role for your need to autoscale AWSServiceRoleForAutoScaling managed role.

Related

Official example on AWS documentation on how to add a service principal on a resource based policy does not work

I several lambda functions on my account to be able to access a secret.
(I cannot use identity policies, don't ask why)
I am following this example from the official documentation so I am creating this resource based policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:sourceArn": "arn:aws:lambda::1234567891911:*"
},
"StringEquals": {
"aws:sourceAccount": "1234567891911"
}
}
}
]
}
My lambda invocation fails as follows:
"An error occurred (AccessDeniedException) when calling the GetSecretValue operation: User: arn:aws:sts::1234567891911:assumed-role/my-secret-name/my-lambda-name is not authorized to perform: secretsmanager:GetSecretValue on resource: ps-shield-token because no identity-based policy allows the secretsmanager:GetSecretValue action",
????
I don't see the problem. Your policy example is valid for services that support service-linked roles1. Lambda functions do not support service-linked roles. Therefore, the policy example is not valid for Lambda.
Service-linked roles, which are AWS-managed, are referenced by service name in resource-based policies, as in the OP. For instance, the principal { “Service”: “elasticloadbalancing.amazonaws.com” } refers to the AWS-managed ELB service-linked-role, which is called AWSServiceRoleForElasticLoadBalancing. Again, there's no equivalent lambda.amazon.aws option here, because Lambda has no service-linked role2.
Functions have user-managed execution roles. Execution roles (EC2 Instances and ECS Tasks have something similar) are referenced by the role ARN in the resource-based policy "Principal": { AWS: <Lambda Role Arn> }, as in #jellycsc's answer.
Although the docs could definitely be clearer, your Example: Service principal does refer to just to service-linked roles. The first link on the page, AWS Service Principal, refers to "service principal" as used "services that support service-linked roles".
Lambda#Edge does support service-linked roles.
It's not the lambda service that's getting the secret value. The lambda service first assumes the execution role which you set in your lambda function, and the execution role is the principle of the secretsmanager:GetSecretValue action. Therefore, the following policy should work.
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Principal":
{
"AWS": "arn:aws:iam::1234567891911:role/<lambda-execution-role-name>"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}

AWS group user not allowed to assume role - access denied

I have a user and I'm trying to impersonate a role for running a service on Kubernetes. However, when I tried using STS to assume the role, I get the following error:
$ aws sts assume-role --role-arn "arn:aws:iam::{ACCOUNT_ID}:role/service-myservice" --role-session-name AWSCLI-Session
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::{ACCOUNT_ID}:user/me is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::{ACCOUNT_ID}:role/service-myservice
I find this odd because this user belongs to a user group with the AdministratorAccess permission attached to it, which should give it access to anything on AWS. This is it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
So, what am I doing wrong here?
What you have here is the IAM policy attached to this User, aka - what is this user is able to do.
You need to set the Trust Relationship as well. This defines which resources or principals is able to use this role/user. Could be Lambda, EC2 or in your case: an IAM User.
See here for example.
The IAM User/Role (in that case, role) you want to assume must have the Trust Relationship as follow:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account_id>:role/<role_name>
},
"Action": "sts:AssumeRole"
}
]
}

Allow any user who has assumed a role in one AWS account to then assume a role in another

I am trying to configure a trust relationship for a AWS IAM role in account 111111111111 so that a user with an assumed role from account 222222222222 can assume it. However, the sts:AssumeRole action is failing because AWS says that I'm not authorised.
Here is the trust relationship that I have set. I've had to define an overly permissive principal because AWS do not allow the use of wildcards in role session principals. I am however attempting to use a condition to restrict the principal.
Note that the AWS principal explicitly matched as arn:aws:iam::222222222222:role/my_lamda_function_role is allowed to assume that role - it seems as though the only issue is with wildcards.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole",
"Condition": {
"ArnLike": {
"aws:PrincipalArn": [
"arn:aws:sts::222222222222:assumed-role/my_admin_role_name/*",
"arn:aws:iam::222222222222:role/my_lamda_function_role"
]
}
}
}
]
}
When I try to assume the role I see the following error.
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::222222222222:assumed-role/my_admin_role_name/my_session_name is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/my_role_that_admins_can_assume
How can I amend my trust relationship to get it working?
I believe that my issue is related to my use of Condition in the policy, because when I explicitly add my STS session to the Principal I can assume the role as expected.
However, I wish for all sessions that assume the role my_admin_role_name to be allowed, so this approach is not viable and that is why I'm trying to use Condition with a wildcard.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:sts::222222222222:assumed-role/my_admin_role_name/my_session_name",
"arn:aws:iam::222222222222:role/my_lamda_function_role"
]
},
"Action": "sts:AssumeRole"
}
]
}

AWS lambda to assume role in the same aws account to access S3

I have created a role to get objects from s3 bucket as below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3GetObjects",
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::cat-pics",
"arn:aws:s3:::cat-pics/"
]
}
]
}
Next, created a lambda function to assume this role. For that added the following statement to the basic lambda execution role which is attached to lambda:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::same-account-id:role/AssumeS3RoleDemo"
}
]
}
However, the following code
import json
import boto3
def lambda_handler(event, context):
print("this test should be printed")
# create an STS client object that represents a live connection to the
# STS service
sts_client = boto3.client('sts')
# Call the assume_role method of the STSConnection object and pass the role
# ARN and a role session name.
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::same-account-id:role/AssumeS3RoleDemo",
RoleSessionName="AssumeRoleSession"
)
# From the response that contains the assumed role, get the temporary
# credentials that can be used to make subsequent API calls
credentials=assumed_role_object['Credentials']
print("credentials are")
print(credentials)
does not work. I keep getting the following error:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::same-account-id:assumed-role/lambda_basic_execution_new/AssumeRoleDemo is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::same-account-id:role/AssumeS3RoleDemo: ClientError
Here AssumeRoleDemo is name of the lambda function and AssumeS3RoleDemo is the role name which has access to S3.
Is it possible to assume role in the same account ? Is so, what step am I missing here ? Please let me know.
thanks
You need amend the role with trust policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
In addition to that make sure your S3 bucket doesnt have a bucket policy. Because resource based policy and IAM based policies both should be allowing.
You don't need to use STS and AssumeRole in your lambda code to access S3 if both are in the same account, if role attached to lambda has policy allowing access on S3 it will work just fine.
But if you really want to do it, you need to make sure your role AssumeS3RoleDemo trust policy allow lambda execution role to assume it.
Below is a link to one exemplo using two different accounts, but the mechanism is the same using just one account:
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/#:~:text=1.,the%20role%20in%20account%20B%3A&text=Update%20your%20Lambda%20function%20code,to%20create%20a%20service%20client.

API Gateway resource policy: specify IAM role as AWS principal

I am trying to setup an API Gateway endpoint with a resource policy, which allows access to a specific IAM role in my account. The IAM role is cross-account, setup with a trust policy which allows AssumeRole to a specific IAM user principal from another account.
In the API Gateway resource policy, when I set AWS principal to the role ARN: arn:aws:iam::********:role/myRole, I get the following 403 error when invoking the API:
User: arn:aws:sts::********:assumed-role/myRole/mySession is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-2:********:********/test/POST/echo
But, if I change the AWS principal to be the temporary STS user ARN: arn:aws:sts::********:assumed-role/myRole/mySession, then I can invoke the API successfully.
Here's the resource policy that doesn't work:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/myRole"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Here's the resource policy that works:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::********:assumed-role/myRole/mySession"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:********:********/*"
}
]
}
Can IAM roles be used as AWS principals for API Gateway resource policy?
Based on the documentation https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-policy-language-overview.html,
Principal – The account or user who is allowed access to the actions
and resources in the statement. In a resource policy, the principal is
the IAM user or account who is the recipient of this permission.
Looks like roles cannot be added as a principal.
P.S: Spent two days trying to restrict access using roles, but couldn't get it to work.