I logged into AWS console as DEV-OPS-ENGINEER and created ROLE-1 with aws managed policy attached. I attached this role to ECS tasks.
Now from my machine I logged into aws cli as DEVELOPER and ran aws ecs update-service command but i am getting below mentioned error:
"An error occurred (AccessDeniedException) when calling the UpdateService operation: User: arn:aws:sts:::assumed-role/DEVELOPER is not authorized to perform: iam:PassRole on resource: arn:aws:iam:::role/ROLE-1"
My idea was all logged in user (with different roles) should be able to use ROLE-1.
Any idea why it is throwing me this error and how can I resolve it ?
To pass a role (and its permissions) to an AWS service, a user must have permissions to pass the role to the service. This helps administrators ensure that only approved users can configure a service with a role that grants permissions. To allow a user to pass a role to an AWS service, you must grant the PassRole permission to the user's IAM user, role, or group.
Find out more, including examples, in the AWS User Guide: Granting a user permissions to pass a role to an AWS service
aws deploy register-on-premises-instance --instance-name XXXXX --iam-user-arn arn:aws:iam::XXXXXXXXXXXX:user/LightSailCodeDeployUser --region ap-south-1
An error occurred (AccessDeniedException) when calling the RegisterOnPremisesInstance operation: User: arn:aws:sts::XXXXXXXXXXX:assumed-role/AmazonLightsailInstanceRole/i-XXXXXXXXXXXXXX is not authorized to perform: codedeploy:RegisterOnPremisesInstance on resource: arn:aws:codedeploy:ap-south-1:XXXXXXXXXX:instance:XXXXXXXXXXXX
I didn't even create the role AmazonLightsailInstanceRole, then how did it come in the picture. My user have all permissions on codedeploy though. I am following this link to set up. https://aws.amazon.com/blogs/compute/using-aws-codedeploy-and-aws-codepipeline-to-deploy-applications-to-amazon-lightsail/
I made the same mistake and then realized that command is meant to be run on your local machine and not the instance!
AmazonLightsailInstanceRole is a service-linked role automatically created by aws:
Service-linked roles are predefined by the service and include all the permissions that the service requires to call other AWS services on your behalf.
The error you are getting is not about you not having the codedeploy:RegisterOnPremisesInstance permission.
The error is about the AmazonLightsailInstanceRole not having it. It does not matter if you (i.e. your IAM user) has all CodeDeploy permissions.
Normally you would add the missing permissions to the role. How to work with the AmazonLightsailInstanceRole is described in the following AWS documentaiton:
Using Service-Linked Roles for Amazon Lightsail
Editing a Service-Linked Role
However, I'm not sure if you can modify the AmazonLightsailInstanceRole and add the missing permissions. Some service-linked roles can be modified, some not.
The documentation is a bit confusing. Create a new user in IAM with admin role (full privileges) and use the credentials of that user to run the command in your local machine.
I need to provide IAM role creation permission to a user but with a condition that if he does it only from some AWS service.
For example, if a user running cloudformation stack and attempting to create an IAM role, he should be allowed. if he manually creating role it should be denied. or if a person creating a codepipeline he should have permission to create the role.
The concept you are looking for sounds like service-linked roles.
https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html
https://aws.amazon.com/blogs/security/introducing-an-easier-way-to-delegate-permissions-to-aws-services-service-linked-roles/
However, I don't think it is supported for CloudFormation or CodePipeline
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
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.
Credentials are automatically supplied to an ec2 instance when an IAM role is attached to it.
I have an ec2 instance running in an opsworks stack. It has an IAM role associated with it: opsworks-ec2-role. This role does not have permission to perform iam:GetUser.
I'm trying to export access keys(for a user having access to iam:GetUser) using ~/.aws/credentials file.
But it is still making request using iam role. I get error arn:aws:sts:::assumed-role/opsworks-ec2-role/ is not authorized to perform: iam:GetUser.
So is there a way to make request using the access key of the user rather than the instance role without removing the iam role from the instance(role is being assigned from opsworks stack & layer)?