Why is iam:PassRole required in this project? - amazon-web-services

I cloned this solution azure-devops-on-aws and used dotnet lambda deploy-serverless ... to deploy the MyLizardApp to my personal AWS account.
During the learning curve, I created an S3 bucket my-lizard-test, IAM user group MyLizardGroup with user lizard-user and group policy MyLizardApp-Policy. Included in the policy are these services:
API Gateway (full access, all resources)
CloudFormation (full access, all resources)
Lambda (full access, all resources)
S3 (full access, all resources)
(Eventually) the deployment succeeded and I had a Lambda application serving the simple razor page showing the time.
I then copied the LambdaEntryPoint.cs, aws-lambda-tools-defaults.json and serverless.template files to my own dotnet core webapp (also a razor project) and attempted to deploy it to the same AWS account with the same command. The only changes made were the namespace of the LambdaEntryPoint class (reflected in the serverless.template file) and the .csproj file to include:
<AWSProjectType>Lambda</AWSProjectType>
and:
<PackageReference Include="Amazon.Lambda.AspNetCoreServer" Version="5.0.0" />
The dotnet lambda deploy-serverless ... command failed with the message:
User: arn:aws:iam::123456789120:user/lizard-user is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789120:role/MyLizardAppServiceRole (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: 12345678-1234-1234-1234-123456789012; Proxy: null)
I got the command to succeed by adding the IAM service to the MyLizardApp-Policy with the PassRole (all resources).
Why was this necessary for my personal app and not the demo solution from github? If the answer is not clear, what should I be looking for as differences? My personal app is not significantly different from the demo solution and I don't think the functional differences (in C#) would matter.

Whenever an AWS Service assumes (uses) an IAM Role, the service must have iam:PassRole permission to grant permission to use the Role. This required to prevent users from gaining too much permission.
For example, imagine a normal (non-Admin) user who launches an Amazon EC2 instance. When launching the instance, they can nominate an IAM Role to be assigned to the instance. If this user was permitted to select any IAM Role, they could select an Admin role and assign it to the EC2 instance. They could then login to the instance and use the credentials to make API calls as an Admin. This is an unwanted "privilege escalation".
Similarly, when an AWS Lambda function executes, it uses an IAM Role to obtain permissions. The iam:PassRole permission is used to control which roles a user can assign to the Lambda function.
So, there is something in that project that is trying to use an IAM Role and needs appropriate permissions.

First of all, we need to know what PassRole is:
iam:PassRole is the permission that controls which users can delegate an IAM role to an AWS resource.
As I can see in the repo, there is a file for CodeDeploy which already have credentials so maybe you are using CodeDeploy.
But btw, you are using an instances to deploy a Lambda function, and you need to pass the role to that Lambda so that is what PassRole do

AWS Services cannot directly assume service-linked roles. The role must be passed to the service by a user with the iam::PassRole permission.
The role-passing needs to be done only once, when a resource (e.g. EC2 instance) is created. After that the resource can assume the role repeatedly.
EC2 Instance profile is implemented this way. When a user launches an instance, it passes a role to the instance to act as an instance profile (it in addition needs iam:AddRoleToInstanceProfile for this case).
Other service-linked roles are also passed in this way.
Do not confuse it with the iam::CreateRole permission. A user may freely create service-linked roles, but is unable to pass the role to a service when needed.
In the management console, and to some extent in the CLI commands, role-passing is implicit, so you may encounter it without clear error messages when using non-root accounts.
As for why sometimes you need this permission, ands sometimes you don't, that is because when you use the root user, it will have AdministratorAccess which basically allows all actions on all resources.
If you create a new IAM user or account with blank permissions then you will need to add this permission manually.

Related

EC2 instance using the wrong user when executing PHP code

I have a ec2 instance with a role attached to it. The role is called webserver and has all the relevant policies attached to it.
I am trying to invoke my lambda function from my PHP code, but I get the following error:
Failed attempt at deleting data/ account: exception 'Aws\Lambda\Exception\LambdaException' with message 'Error executing "Invoke" on "https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/blahFunction/invocations"; AWS HTTP error: Client error: `POST https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/blahFunction/invocations` resulted in a `403 Forbidden` response:
{"Message":"User: arn:aws:iam::34234324324342:user/SecretGuy is not authorized to perform: lambda:InvokeFunction on resour (truncated...)
AccessDeniedException (client): User: arn:aws:iam::34234324324342:user/SecretGuy is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:eu-west-2:34234324324342:function:blahFunction because no identity-based policy allows the lambda:InvokeFunction action - {"Message":"User: arn:aws:iam::34234324324342:user/SecretGuy is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:eu-west-2:34234324324342:function:blahFunction because no identity-based policy allows the lambda:InvokeFunction action"}'
Now SecretGuy is a user I created a long time ago, and somehow my ec2 is trying to use that.
I am wondering if anyone can help with this?
Thanks
From my understanding, you are running PHP code on an EC2 instance, and your code invokes the Lambda function.
And this EC2 instance has attached IAM Role with proper permissions to invoke the Lambda function. Then you tried to run your code and faced that the EC2 instance is using an unexpected IAM identity(IAM User named SecretGuy here), not the role you attached.
There's a chance that you might have IAM credentials set by environment variables for that Linux user or static credentials set on your EC2 instance.
AWS SDK client has an order to retrieve credentials on the machine. The official docs of PHP AWS SDK say,
When you initialize a new service client without providing any credential arguments, the SDK uses the default credential provider chain to find AWS credentials. The SDK uses the first provider in the chain that returns credentials without an error.
The default provider chain looks for and uses credentials as follows, in this order:
Use credentials from environment variables.
Setting environment variables is useful if you're doing development work on a machine other than an Amazon EC2 instance.
Use the AWS shared credentials file and profiles.
This credentials file is the same one used by other SDKs and the AWS CLI. If you're already using a shared credentials file, you can use that file for this purpose.
We use this method in most of our PHP code examples.
Assume an IAM role.
IAM roles provide applications on the instance with temporary security credentials to make AWS calls. For example, IAM roles offer an easy way to distribute and manage credentials on multiple Amazon EC2 instances.
To retrieve IAM credentials from the role attached,
You can check which IAM Identity you are using to call AWS API with the below command on the EC2 instance. (as that Linux user, you are running PHP code)
aws sts get-caller-identity
Then it will show result as below,
{
"UserId": "ABCDEFGHIJKLMNOPQRSTU",
"Account": "34234324324342",
"Arn": "arn:aws:iam:: 34234324324342:user/SecretGuy"
}
Then you need to look for environment variables set or static credentials files on that EC2 instance.
My guess is maybe someone used aws CLI on that EC2 before, with SecretGuy credentials, So there would be a file $HOME/.aws/credentials.
If the file exists and is confirmed as a SecretGuy access key, you have to delete that file. (If EC2 runs some critical application, you might want to copy all permissions of SecretGuy to the IAM Role you attached before deleting it to avoid unexpected service outage)
Or, you can look for environment variables.
echo $AWS_ACCESS_KEY_ID
If the above commands return the access key id value, you might have to unset environment variables.
After that, your code will retrieve credentials from IAM Role.

Handle execution role to Setup SageMaker Domain (not root user)

I'm working on an AWS account managed by another team which use it only for S3 storage. We have authorization to use sagemaker, and administartor said “AmazonSageMakerFullAccess” have been given to me.
I'm trying to access sagemaker studio, for that I'm ask to "Setup SageMaker Domain" by aws.
I then need a "Default execution role"
If I try to create one, I got error "User ... is not authorized to perform: iam:CreateRole on resource: ..."
There is an option to use a custom exiting one with the format
"arn:aws:iam::YourAccountID:role/yourRole"
but while I have an account Id, I don't know what role to use.
I don't have permission to create role, and the ones I see in IAM service doesn't seem to be related to sagemaker (also I don't have permission to see the details of those roles).
Should the sagemaker setup be done by the administrator who can create a new role ? Or is there a way for me to do it, and if so where can I find the role I need ?
If you don't attach any role to AWS SageMaker, and when you try to create SageMaker resource the very first time it will create a default execution role for the service. Either get the permission to create a role or ask your administrator to create a execution role for your SageMaker so that next time when you create one you can use the same role.

Difference between policy path "arn:aws:iam::aws:policy/aws-service-role" and ""arn:aws:iam::aws:policy/service-role

What difference between policies under the paths "aws:policy/service-role" and "aws:policy/aws-service-role"?
Is there any the logic behind this design?
The AWS managed policies within the aws-service-role path are policies that be attached to a service-linked role only.
If you go to AWS Console -> IAM -> Policies, filter by AWS Managed Polices and start clicking on them, you'll notice the ones with the aws-servive-role path have a help label at the top that reads "This policy is linked to a service and used only with a service-linked role for that service. You cannot attach, detach, modify, or delete this policy.". There might be a way to filter down to the service-linked policies in the AWS Console or CLI when desribing policies other than inspecting the paths, but it alludes me right now.
You can see their usage described here
https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html.
Here also is the blog post that describes what a service-linked role is https://aws.amazon.com/blogs/security/introducing-an-easier-way-to-delegate-permissions-to-aws-services-service-linked-roles/. Basically these are roles that can only be assumed by a specific service type.
The AWS managed policies in the service-role path are policies that can be attached to any role including "normal/basic" roles. These types of roles can be assumed by users, EC2 instances, or anywhere else roles are assumed.
For example you could give someone permission to attach a linked-service role that has the policy arn:aws:iam::aws:policy/aws-service-role/AWSLambdaReplicator attached which is only attachable to a linked-role linked to the Lambda service. They would be able to use this role in the Lambda execution role, but they would not be able to use this role with another service like EC2 or an IAM user. This supports an admin allowing users to assign out permissions to new resources that users spins up (a new Lambda) that that the admin trusts the linked AWS service to use, but don't want to allow that user to access directly through their user account or give them to other custom applications running in AWS.

Specifying Role in ASK CLI v2

I'm setting a new skill with ASK CLI V2 in Alexa. I would like to specify a specific role when deploying the new skill instead of letting the command create a new one.
Some background: I created a new skill using the new command and used the hello world template. Then, I ran the deploy command. I am using a corporate account and I don't have permissions to create a new role. I have to use an existing one.
AccessDenied: User: [...] is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::845692260290:role/ask-lambda-skill-sample-nodejs-hello-world
I am afraid that you need to ask your organization to give some permissions to your user to create Lambda Execution Roles, as per the documentation here
AWS permissions
When ASK CLI creates a new Lambda function, it associates the AWSLambdaBasicExecutionRole with the function. For more information, see Manage Permissions: Using an IAM Role (Execution Role) in the AWS Lambda documentation. Make sure the AWS credentials that you configured for use with ASK CLI have permission to create IAM roles and associate permissions.
I hope this helps.

What is exactly "Assume" a role in AWS?

Question
What does exactly "Assume" a role mean in AWS and where is the definitive definition provided?
Background
Assuming a role is frequently used and trying to understand the definition and what it actually means.
I suppose when a principal (IAM user, application running in an EC2 instance, etc which invokes an action to access AWS resource(s)) needs to invoke an action to access an AWS resource:
AWS (API? or some Authorisation runtime in AWS?) identifies the roles which the principal can be granted. e.g. if an EC2 user is specified to execute the assume-role API call and run an application which accesses an AWS resources in an EC2 instance to which IAM profile is attached, then:
All the IAM roles from the EC2 IAM profile
IAM roles and policies requested in the assume-role call
IAM roles which the EC2 user is granted
AWS finds a role from the roles which has the policy (action, resource) that allows the principle to do the action on the resource.
AWS switches the role of the principle to the role identified.
When the step 3 has happened, it is said "the principal has assumed the role". Is this correct?
Research
Using IAM Roles
Before an IAM user, application, or service can use a role that you created, you must grant permissions to switch to the role. You can use any policy attached to one of an IAM user's groups or to the user itself to grant the necessary permissions.
Assuming a Role
AssumeRole
Using IAM Roles
Using an IAM Role to Grant Permissions to Applications Running on Amazon EC2 Instances
Assuming a role means asking Security Token Service (STS) to provide you with a set of temporary credentials -- role credentials -- that are specific to the role you want to assume. (Specifically, a new "session" with that role.)
You can optionally include a policy with this request, which will serve to limit the permissions of the temporary credentials to only a subset of what the role's policies would have allowed.
You then use these credentials to make further requests. These credentials look similar to IAM user credentials with an access-key-id and secret, but the access key begins with ASIA instead of AKIA and there's a third element, called the security token, which must be included in requests signed with the temporary credentials.
When you make requests with these temporary credentials, you have the permissions associated with the role, and not your own (if you have one) because you have taken on a new identity. CloudTrail can be used to trace the role credentials back to the user who assumed the role, but otherwise the service is unaware of who is using the credentials.
tl;dr: Assuming a role means obtaining a set of temporary credentials which are associated with the role and not with the entity that assumed the role.
AWS (API? or some Authorisation runtime in AWS?) identifies the roles which the principal can be granted.
No. You specify the role you want to assume.
When "you" are code running on an EC2 instance, and the instance has an instance role, the EC2 infrastructure actually calls assume-role on behalf of the instance, and you can fetch the temporary credentials from the instance metadata service. These credentials are accessible only from within the instance, but they are not stored on the instance.
When running a Lambda function, the Lambda infrastructure contacts STS and places your temporary credentials in environment variables. Again, these credentials are accessible to the function, without being stored inside the function.
In either case, you could call assume role with these credentials and assume a different role, but that should not be necessary in most environments.
e.g. if an EC2 user is specified to execute the assume-role API call and run an application which accesses an AWS resources in an EC2 instance to which IAM profile is attached, then:
AWS has no awareness of EC2 users. Instance roles are accessible to everything running on the instance.
All the IAM roles from the EC2 IAM profile
An instance profile can only include one role.
IAM roles and policies requested in the assume-role call
You request to assume exactly one role. You do not need to request a policy -- you only specify a policy if you want the temporary credentials to have fewer privileges than the role credentials would allow. This might be something you would do if you needed code running in an untrusted place -- such as code in a browser or an app -- to be able to sign requests with credentials.
AWS finds a role from the roles which has the policy (action, resource) that allows the principle to do the action on the resource.
No. As noted above, you ask for a specific role when you call assume-role.
AWS switches the role of the principle to the role identified.
No. You make the switch by using the temporary credentials provided.
I have created the following diagram for myself to understand what is exactly assume a role in AWS. Hopefully, you will also find it helpful.
In the diagram, I put it in 3 steps:
Prepare the roles (ExecutionRole and AssumedRole)
Create a Lambda Function on Account A (in your case it is EC2)
Execute the LambdaFunction.
The diagram uses cross-account as an example, if it is within the same account step 1.3 is not required.
Typically, you use AssumeRole within your account or for cross-account access.
...
Users in the same account as the role do not need explicit permission to assume the role. Source: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
When step 3 has happened, it is said: "the principal has assumed the
role". Is this correct?
The steps you mentioned in assuming a role are correct.
Here the important point is the IAM role's Trust Relationship configuration where you grant each of the IAM user, application, or service to assume the role. That is where you grant the permission to assume the particular role.
This is important in many aspects, where it controls who can assume the role and it is important to provide not only least access to the role but also grant the least amount of entities who can assume the role.