The Fine World of AWS Idxxxxty and Access Management
#2: IAM Roles
I started writing about this series early in the week of Apr 5, 2020. The first one in the series dealt with Authentication, Users, and Federation. This piece, for IAM Roles.
Recap: During federated authentication (cool kids say AuthN), IAM Roles do not play any role in authentication. The IAM Role ARN is passed in the request context as one of the elements. That determines what the calling application is allowed or not allowed to perform on AWS resources — which is part of authorization (cool kids say AuthZ)
(Trivia question: what are the other pieces of information passed in the request context?)
Note on Primitives and Identities
Like IAM Users, IAM Roles are part of what is called as the AWS Identity “primitives”. Identity primitives are building blocks that make up the further advanced constructs of IAM. Users, roles, and permissions (policies) are the primitives.
IAM Role is also an identity. Another identity is IAM User. Groups, although normally have users in them (I say “normally” because technically you can create a Group without adding any users to it), it is merely an operational construct — meaning it makes it easy to manage permissions for a large set of users.
When you cannot refer to an entity as a
Principalin IAM, it is not considered to be an Identity.
Did you see what I did there? You got it — 2 primitives (User and Permissions) build a construct called “Groups”.
An IAM Role defines what a Principal (another IAM Role, IAM User, AWS Service, Federated User etc.) can or cannot do. Role has permissions which sets this allow or deny behavior.
Roles can take various “forms”. When a service is associated to a role (i.e. a service is set as the trusted entity for a role), it is called a Service Role. Roles associated with Amazon EC2 has a name: Instance Profile (one of a kind). To be clear, when you create a role which trusts a service, it becomes scoped to the trusted service is question unless you edit the role.
For services which define a factory default role, meaning ones that are defined by the service in question and not associated later, is called a Service-Linked Role. E.g.
AWSServiceRoleForRDS for Amazon Relational Database Service (RDS). In this case also, the services which are associated to the role are called the trusted entities.
The difference between the two is that service roles can be assumed by an AWS entity that the role’s trust policy scopes to, whereas the service-linked role is associated with a specific service. For a service-linked role, the trust policy cannot be edited and that is what stops role from trusting (or associating) another entity.
Outside of AWS Services, these below can also be trusted entities for a role:
- AWS Account (your own or a 3rd party)
- Amazon Cognito
- Another OIDC (OAuth 2.0) identity provider
- Another SAML 2.0 identity provider
- Another customer identity broker
For the common use cases where IAM Roles can be used, please review this.
Assuming a Role
When you assume a role, it provides you with temporary security credentials for your role session. In relation to this, it is important to understand that a Role has a trust policy and a permissions policy. The trust policy is what determines which
Principal can assume the role and the permissions policy determines what the
Principal can or cannot do.
Permissions policy: A simple example is shown below. This is a role named
admin-ec2-role, which allows EC2 instances from the same account (trusted entity) to have administrator privilege on all AWS entities / resources. That means, if an EC2 instance is provisioned with this role, the application(s) on this EC2 instance will have administrator level privilege [of course, this is something you will probably never do in reality].
This shows the role name and permissions associated with the role.
Trust policy: And when you go to the second tab, named “Trust relationships” and click on “Show policy document” below is the trust policy shown.
Note: all “policies” referred to here are identity-based policies. There is something called a resource-based policy. Oh, and service control policy and other related concepts. Maybe for another time :)
Assuming a role is underpinned using these trust policy and permissions policy for all types
AssumeRole call or action. Possible scenarios where you might need to assume role are:
- Giving access to AWS entities (i.e. services) within or across your own accounts. Details can be found here.
- Giving access to AWS entities (i.e. services) from a 3rd party AWS account (principally same approach as giving access to resources within or across your own accounts + add additional parameter called external ID). This is also referred to as role delegation scenario.
- Giving access to AWS services — same as the first scenario, but called out explicitly to highlight the instance profile of EC2 or service-linked roles (both discussed above)
- Giving access to users / apps through identity federation. Discussed in my prior blog in the series.
Another concept, closely related to creating a role is a permissions boundary. Permissions boundary, as the name suggests, creates a ring fence of what is the maximum allowable permission that an IAM identity (user or role) can have. Note that, permissions boundary in itself does not provide permissions. Identity-based policy (and other policies not covered here) provides the permissions, and any permissions not allowed beyond the permissions boundary ring fence is dropped creating a net new permission for the IAM identity.
What is the difference between Roles and Groups considering both have permissions associated with them?
The difference is that no one can “assume” groups (you can add or remove users from Groups). But a
Principal(a user, an AWS resource) can assume a role. Also, Groups are merely an operational construct i.e. makes it easier to manage permissions for a number of users.
None of anything mentioned in this blog represents official AWS guidance and may have quality issues.