One of the most common questions that arises when learning about AWS IAM is what the difference between roles and groups is and when to use which.
A group is a collection of users with common permissions linked at the group level.
A user is an AWS representation of an entity (real person or service) which typically has privileges linked to it.
A role is assumed by an entity to grant the entity some privileges.
By the end of this blog, you’ll be able to answer these questions:
When will we decide to grant permissions via user vs. group?
And then, when will we decide to grant permissions via group vs. role?
The answer to the first question is straightforward:
If the user is like other users in your AWS ecosystem, in the sense that they all need similar permissions, then add the user to a group and associate the permissions to the group.
In most real-world scenarios, for scalability and reusability, it would be a best practice to attach the permissions to a group and adding the user to it, rather than attaching permissions to the individual user directly.
Now the other question is more imperative: when will we decide to grant permissions via group vs. role?
When we first start to learn about IAM, the natural (read naïve) answer to this question is:
Is the entity a real person? Create a user for it, add them to a group and give it access via group permissions.
Is the entity a service (like an EC2 instance trying to access an S3 bucket)? Let it assume a role.
But surprisingly, this is not the differentiator.
Users (as I mentioned before), can represent both real people, and AWS services.
Roles can also be assumed by people as well as services.
Then why does AWS offer multiple mechanisms to achieve the same thing — granting permissions?
Let’s dive in.
Difference between users and roles
The most important differentiator is that creating a user for an entity means associating long term credentials with them. Letting an entity assume a role means associating temporary credentials with that entity.
The entity that assumes any role gets the privileges associated with that role only for the duration of their role session. Once they relinquish the role, the privileges are automatically revoked.
Let’s have a look at a few use cases to illustrate this further.
- Audits: Say we have a third-party auditor who wants to access our AWS resources for an audit that happens say yearly. So, they would need temporary access. Once the audit is complete, most likely they will not need access again soon. So, we would create a user for them, but instead of adding them to a group, we would rather give them the necessary access through a role. When the audit is complete, they may relinquish the role and the associated access will get revoked.
- Permission to do critical tasks: Say in an organization, there are critical EC2 instances. Taking a specific example scenario, say members of the team are to be given permission to terminate those EC2 instances. There could be two ways to do it: either grant that permission to the group of those users or create a role with that permission associated and let the users assume that role. If the former was chosen, that would mean giving them a long-term permission to do the task. I agree that the permission could be revoked from the user when they are done with the task, but again, revoking the access would be a manual task and not be a scalable way to solve this problem.
- If the latter route is chosen, the users could “switch to” that role when they need to, and when they are done terminating the instances they could switch back out of this role and the privilege to terminate those EC2 instances would be automatically removed for those users. This process could be repeated for any number of times the existing or new users want to terminate those instances, without having to delete or update those permissions manually.
- Cross account access: Say an organization has two AWS accounts for their application, one for the development environment and the other for production. Now say the users for the developers created in the development account need access to resources in the production account, to be able to do specific tasks sporadically. One option could be to create corresponding users in the production environment for those developers. This could get cumbersome with time, as they would have to delete the users or modify their permissions after the specific task is done.
- The second and more scalable option would be to create a role in the production environment allowing anyone who assumes it, to do the specific task and allow the developer users in the development environment to assume that role. Now the developers could assume the role, do the task, and then switch out of this role. It would simply remove their access to the specified task. Too easy.
You get the idea — want an entity to have permanent access? Give them permission at the user/group level.
Want them to have temporary access? Let them assume a role.
I hope you enjoyed this blog and will be able to make better decisions with this knowledge.