Objective
Clear the confusion of what/who is the principal of an action being executed in AWS with assuming an IAM role.
Background
A IAM role has the tab of Trust relationships that defines who can assume the role.
It is described as in JSON.
statement {
sid = "1"
effect = "Allow"
principals {
identifiers = ["elastictranscoder.amazonaws.com"]
type = "Service"
}
actions = ["sts:AssumeRole"]
}
According to Roles Terms and Concepts, those who can assume the role must be either a user or a role.
Principal
An entity in AWS that can perform actions and access resources. A principal can be an AWS account root user, an IAM user, or a role. You can grant permissions to access a resource in one of two ways:
Trust policy
A document in JSON format in which you define who is allowed to assume the role. This trusted entity is included in the policy as the principal element in the document.
Question
Who/what is the principal if I issue the assume-role command using my AWS account to get a temporary credential, and then run an action e.g. transcode video files? According to the AWS document, it must be either a user or a role.
elastictranscoder.amazonaws.com?
The role that defines the trusted relationship with elastictranscoder.amazonaws.com?
My user account?
If it is elastictranscoder.amazonaws.com, then:
Is it this a user or a role?
From Audit perspective, is elastictranscoder.amazonaws.com recorded as the principal who executed the action? Where can I identify who became elastictranscoder.amazonaws.com when and how?
AWS IAM can be thought as an abstraction over 3 things:
Identity (Role, User, User group)
Policy (Identity based policy, resource based policy)
Resource (AWS resources).
A json is composed of elements and 'Principal' is one of the json element in the 'Policy' json document. Principal elements are only present in resource based policy jsons.
Principal abstraction is at the same abstraction level as Identity abstraction. It extends Identity abstraction and is identified by a granular identity i.e. Amazon Resource Name (ARN).It is used only with resource based policy.
Principal elements are used to specify entities like AWS account, AWS services, IAM role, IAM user, federated user and the actions elements specify what operation principals can perform.
AFAIK,
In your context,
When you issue the assume-role command using my AWS account to get a temporary credential, there is no Prinicipal involved sine there is no resource policy involved it is just identity based policy which gives your IAM role to assume role.
When you issue AssumeRole API via CLI or other means, the principal is the identity whose credentials are being used. For example, if you are assuming a role using IAM user's credentials, the principal is the IAM user.
You receive temporary credentials as a result of successful AssumeRole API and when you perform any action using these temporary credentials, the principal will be the IAM role.
In your example, you are trusting the "elastictranscoder.amazonaws.com" i.e. Elastic Transcoder service itself. You can audit how the service is using the role in CloudTrail logs.
Related
I would like to know if I can check if a policy or role can see, list, or edit a resource.
Can be any type of resource, S3 bucket, Secrets Manager, EC2 instance, etc.
I will try to do this through boto3 as well.
You can Test IAM policies with the IAM policy simulator - AWS Identity and Access Management. This allows you to specify a policy and a resource (including conditions) and test whether the API call would be permitted.
If you wish to do this via boto3, you can use simulate_custom_policy():
Simulate how a set of IAM policies and optionally a resource-based policy works with a list of API operations and AWS resources to determine the policies' effective permissions. The policies are provided as strings.
The simulation does not perform the API operations; it only checks the authorization to determine if the simulated policies allow or deny the operations.
If you want to simulate existing policies that are attached to an IAM user, group, or role, use simulate_principal_policy() instead.
I have created a Lambda function. In the permissions pane there is section for role and another section for resource-based policy.
A role in IAM inherently has a policy. This specifies the resources and actions that the function (via role) has permission to access.
So what is the purpose of having the section for Resource-based policy? If there is access allowed in one and denied in another than which permission is prioritized.
They are two different things.
The role is what the lambda can do (i.e. what the function itself has access to when executing)
The resource-based policy is what other principals can do to the Lambda (i.e. who can execute it, who can update it, who can see it, who can delete it etc)
Lambda is one of a number of services in AWS where this dual set of policies is required as it is both a resource that can be acted upon, and runs as a principal which can act on other things. EC2 Instance Roles are another example.
The IAM role that is attached to the Lambda is used to grant the Lambda the ability to communicate with other AWS resources other the API. If the IAM policy allows access to perform an action, as long as there are no Deny statements the action should be able to be carried out.
The function policy on the other hand is a policy that evaluates invocation of your Lambda function, by default resources within your AWS account can invoke the Lambda should they have the right IAM permissions.
Some services do not have an IAM role that are assigned to them however, so properties such as the Arn of the calling resource or the service that is attempting to invoke the Lambda. In addition you can grant access to another AWS account, or restrict which IAM principals should be able to invoke the function. This is similar to the property of a bucket policy in an S3 bucket.
As per the AWS documentation here.
Identity-based policies are attached to an IAM user, group, or role. These policies let you specify what that identity can do (its permissions). For example, you can attach the policy to the IAM user named John, stating that he is allowed to perform the Amazon EC2 RunInstances action. The policy could further state that John is allowed to get items from an Amazon DynamoDB table named MyCompany. You can also allow John to manage his own IAM security credentials. Identity-based policies can be managed or inline.
Resource-based policies are attached to a resource. For example, you can attach resource-based policies to Amazon S3 buckets, Amazon SQS queues, and AWS Key Management Service encryption keys. For a list of services that support resource-based policies, see AWS services that work with IAM.
With resource-based policies, you can specify who has access to the resource and what actions they can perform on it. To learn whether principals in accounts outside of your zone of trust (trusted organization or account) have access to assume your roles, see What is IAM Access Analyzer?. Resource-based policies are inline only, not managed.
I am trying to understand Policy and bindings in Google Cloud IAM.
I came across this command:
iam service-accounts get-iam-policy <Service Account>
Can you confirm the following statements:
A Service Account can be both an Identity and a Resource, so in regards to Roles a Service Account is a Resource and in a Policy it is an Identity?
This iam service-accounts get-iam-policy <Service Account> returns an eTag, and from my understanding it is a way of concurrency controlling the Policy this Service Account belongs to?
So I guess this command is only used, by the system when checking if a Service Account already belongs to Policy?
A Service Account can belong to only one binding, that belongs to a Policy?
A Policy is just an extra structural organisational layer on-top of Roles, but it also include the option for bindings with constraints?
A Service Account can be both an Identity and a Resource, so in
regards to Roles a Service Account is a Resource and in a Policy it is
an Identity?
A service account can be considered both a resource and an identity.
You can grant roles to other identities to access or manage a service account.
You can grant roles to a service account allowing the service account to access other resources including other service accounts.
This iam service-accounts get-iam-policy returns an
eTag, and from my understanding it is a way of concurrency controlling
the Policy this Service Account belongs to?
The eTag prevents two identities from updating the same policy at the same time for the same resource. First, you read the policy which includes the eTag. Then you modify the policy and reapply. The eTag must match the current eTag. If two identities modify the same policy, the first will succeed and the second will fail. The first update will generate a new eTag which will no longer match the eTag in the second policy.
So I guess this command is only used, by the system when checking if a
Service Account already belongs to Policy?
Service accounts do not belong to a policy. Policies are assigned to service accounts (and resources). The command reads the current policy.
A Service Account can belong to only one binding, that belongs to a
Policy?
A service account can have only one policy assigned to it. Changes are made by modifying the policy. Remember that a service account can be assigned at the Organization, Folder and Project level in addition to individual resources. In this case the resource can have a policy which includes a service account as a member identity. This is different from a policy that is assigned to a service account.
A Policy is just an extra structural organisational layer on-top of
Roles, but it also include the option for bindings with constraints?
I do not understand what you are asking here. A policy consists of roles. A policy is assigned to resources. Constraints are a separate layer that provides restrictions that are applied to resources. If permission is denied by a constraint, then that overrides an allow permission.
A Service Account can be both an Identity and a Resource, so in regards to Roles a Service Account is a Resource and in a Policy it is an Identity?
(this is not true)
This iam service-accounts get-iam-policy returns an eTag, and from my understanding it is a way of concurrency controlling the Policy this Service Account belongs to?
(this is not true)
So I guess this command is only used, by the system when checking if a Service Account already belongs to Policy?
(this is true)
A Service Account can belong to only one binding, that belongs to a Policy?
(this is not true)
A Policy is just an extra structural organisational layer on-top of Roles, but it also include the option for bindings with constraints?
(this is not true)
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.
This page https://www.terraform.io/docs/providers/aws/r/iam_role.html mentions:
NOTE: This assume_role_policy is very similar but slightly different
than just a standard IAM policy and cannot use an aws_iam_policy
resource. It can however, use an aws_iam_policy_document data source,
see example below for how this could work.
Is there any reason why the assume_role_policy is different from the standard IAM policy?
Any why?
An assume role policy is a special policy associated with a role that controls which principals (users, other roles, AWS services, etc) can "assume" the role. Assuming a role means generating temporary credentials to act with the privileges granted by the access policies associated with that role.
An assume role policy differs from a normal policy in the following ways:
It is a property of the role itself, rather than a separate object associated with the role. There is only one assume role policy per role.
The only Action values that have any meaning in an assume role policy are sts:AssumeRole and some other variants on it (at the time of writing, sts:AssumeRoleWithSAML and sts:AssumeRoleWithWebIdentity). Those are the API operations used to obtain the temporary credentials for the role.
It is the first of these differences that creates the difference mentioned in the Terraform documentation: since a role has exactly one IAM policy and it is declared directly as part of the role, its policy document must be provided as an attribute of the aws_iam_role resource. The aws_iam_policy_document data source is just a simple transform of its input into an IAM JSON policy document format, so it can be used to generate the value of the assume_role_policy attribute.
When an AWS service makes calls to another API service on your behalf, it is internally obtaining temporary credentials for the role you designate, which it can then use to make calls to other service APIs. It is for this reason that it is necessary to create roles and assign them to services such as AWS Lambda, EC2 (via instance profiles), Kinesis Firehose, etc.
I wrote a more elaborate description of this as part of an answer to another question, which gives some examples of practical IAM roles, assume role policies and regular policies.