AWS IAM: Finding it hard to design a authorization model for SAML-based users - amazon-web-services

Background: On Azure (we're in the process of moving from azure to aws), we have everything organized into resources groups. By default no one can do much in the prod subscription(account), but based on the team asking for a provisioned resource, a team member gets stamped as the "owner" of the resource group, which just gives him/her full access to that resource group, and can add/remove other members as they see fit. This allows us to set up a very fine-grained set of access controls where each team ultimately decides whats allowed and not - not based on groups but based on users getting access to resource groups (in which instances and other resources exist).
Now that we're moving to AWS I had hoped to use the SAML integration to provide access (we're running Auth0 in front of AzureAD, but this should be the same for any saml/federated aws setup I think).
My problem is that with SAML AWS doesn't really "see" each individual user - they're not auto-created in IAM at first logon or anything, so the only "security boundary" I have to work with are the groups I send into AWS, which I can assign to IAM roles.
This is a problem, because 1)the user has to select the desired role at login (if member of more than one), and 2)each role setup is a manual task which requires me to configre AzureAD, saml claims in auth0 and finally IAM roles in AWS. The latter is obviously something I can automate, but still.
Here's the core of my problem:
Say that I have 2 EC2 instances in AWS: DB and Web. I have 3 users, AdminPete, DBDave and WebWilson. I'd like to be able to give Pete full access to both instances, while Dave and Wilson gets access to "their own" ec2 instance. As far as I can see, I would have to configure two IAM roles (DB and Web), and require Pete (who has access to both) to choose his role at login. This is a super-simple example, but it doesn't really scale well at all.
I'm curious to hear how you guys are doing access control in aws - my goal is to be able to create a very fine-tuned setup using tags or some other mechanism. The official aws documentation only deals with getting saml configured (which is easy enough), but very little about real-life permissions management.
The core of the problem (imho) is that unlike "regular" iam users, I can't attach an iam policy or a group to a single user when that user is federated - I can only attach the policy to the federated role as a whole.
Any pointers appreciated! At this point I'm considering just not using saml at all for our aws stuff so that we can use fine-grained iam policies to manage permissions in a more flexible manner.

Related

Recommended IAM structure to link a machine user to a policy? Running on-prem

I would like to run a batch job on-prem and access AWS resources in our account.
I think the recommendation is to create an IAM user, which will be a machine user. Since I don't have a way to assign a role to the on-prem machine, or federate with AWS identity, I'll create an access key and install it on the on-prem machine. What's the best way to link my machine user to a policy?
I can create an IAM policy which allows the required actions (reading AWS SSM Parameters).
But, how should I link the machine user to the policy? I'm setting up these users/policies with Pulumi. Some options I'm aware of:
I can create a role, but then I think the machine user would have to assume the role. (My understanding is that roles do not have immediate "membership", it's just that users have the ability to assume roles. Or, AWS infrastructure can be set up with a role, like an EC2 or an EKS cluster can act as a role. In the future I do plan to move this job's execution to AWS infrastructure, but for now that's not an option.) Is assuming a role easy, for example a aws sts CLI call that I could put in my batch job's startup script before calling the main binary?
Or I could just attach the policy directly to the machine user. Generally that's not recommended from what I've read: you should have a layer between users and policies so when users change what they're doing you have indirection. But in this case maybe that's fine.
Or finally I could create a user group, attach the policy to the group, and add the machine user as a member of the group. Is that layer of indirection useful / an appropriate use of groups, especially if I'm already managing these policies with IaC? Most documentation recommends roles for the user-to-policy indirection, so I'm hesitant to use groups that way. However, that seems to be the expected approach for human users (glad for feedback on that too).
"Is it better to use AWS IAM User Group, or IAM Role for users to assume?" says a group would help manage permissions for multiple users (but so does Pulumi and I only have 1 or 2 machine users); and a role would help separate access rights from long-lived credentials but it seems like rotating the machine user's access key would have that benefit too without the extra assume-role step.

AWS: How to enforce multi-factor-authentication for IAM users (without custom polices)

Let's assume we have a nice, little cloud account running simple workloads. We have two user types accessing this account:
System accounts to access specific resources (CI/CD, DB access, etc.) with very fine-grained permissions
Two or three user accounts to manage the cloud account and everything on it (a.k.a. admins) - with pretty much full access
To secure the user accounts I want to enforce multi-factor-authentication on a global level. On MS Azure the AAD admin can enforce MFA on a per-user-level (on https://admin.microsoft.com). That feels straight-forward to me.
On AWS this seems much more cumbersome:
The IAM user management view only provides MFA configuration options for the current user.
AWS suggests to enforce MFA on a per-policy basis (see AWS docs).
This Stackoverflow thread extends AWS' approach to create a BlockMostAccessUnlessSignedInWithMFA policy. But still: per-user MFA is managed in policies and the custom BlockMostAccessUnlessSignedInWithMFA policy feels like a workaround.
Is there a more straight-forward way to do this on AWS IAM User management?
If not, am I missing something why the Azure AD's approach cannot work on AWS?
Any idea is welcome

why do you need roles (as opposed to IAM groups) to access resources in another AWS account?

I am trying to understand why you need IAM "roles" to access a resource in a different IAM account, and why AWS can't just do the same thing with IAM groups.
Whenever I ask people this question the conversation just seems to go in circles:
Them: "To grant access to a resource to users in another IAM account, you have to give them permission to assume an IAM role, and then grant that IAM role access to your resource."
Me: "I understand that, but why can't you just create an IAM group that can access that resource, and then add those users from the other account to your IAM group?"
Them: "You can't add users from another AWS account to an IAM group in your account."
Me: "I understand that too, but why does AWS only let you do cross-account permissions like that by using roles? Why wouldn't it make just as much sense for AWS to let you create an IAM group and then let you add IAM users from other accounts into that group?"
There's probably some simple one-sentence piece of information that explains why it has to be this way, and once someone tells you, it all makes sense, but it's not in the documentation and I don't know what it is. What is it?
I would say security is main reason. IAM roles provide only temporary credentials. Using such credentials whenever possible is good practice for security reasons.
Off course you can also create IAM user in your account, and give the associated access keys to people form the other account. And sometimes this is preferred, e.g. to enable read access only to some resources. But the issue is that IAM user credentials are permanent, unless manually disabled or deleted. For security reasons giving away permanent credentials to your account is not a recommended practice.
From docs:
We recommend using this approach to enforce the principle of least privilege. That means restricting the use of elevated permissions to only those times when they are needed for specific tasks. With roles you can help prevent accidental changes to sensitive environments, especially if you combine them with auditing to help ensure that roles are only used when needed.
The one-sentence answer is that Amazon chose to do it that way.
From an operational perspective, it simplifies life considerably if you associate an access key with an account. The alternative is to specify an account separately with every request.
From an organization management perspective, trees are easier to understand than forests. What I mean by that is that everything branches off the account's IAM root. If you allow arbitrary users across the AWS universe to have access to arbitrary resources within arbitrary accounts, you end up with a management nightmare.
As a sidebar to that last comment, the early AWS services had resource-based policies. These are now discouraged in favor of identity-based policies, and newer services don't have resource policies.
Lastly, from a security perspective, a multi-tenant environment is a lot easier to control if you establish a hard wall around each tenant.

Hide EC2 Instances from other IAM users

We have large number of IAM users ( in hundreds, can increase more then 1000 in future ).
All the IAM users have access to create EC2 instances. Simultaneously around 30-40 users will be working and creating EC2 instances.
In AWS Management Console, an IAM user can see all the instances created by other IAM users as well.Is it possible to visibly make him see only those EC2 instances which he created and hide all the other instances created by other IAM users?
I do agree that IAM users can give names and tags to recognise their instances. However i am looking for visibly hiding those resources which he has not created.
If IAM policies allowed specifying a required filter, this would be possible. But you can't specify it, so it's not possible.
What you want is called Organizations - You can give each group their own AWS account, so they can see their own billing, etc.
Reserved Instances can flow from the master account to sub account
Bills flow from the sub accounts to the master account
All your users can remain in the master account, you just give them AssumeRole capabilities to view their account.
You can apply Service Control Policies that prevent sub-accounts from doing things.
You may think management is "easier" with one account - but the opposite is true. Just like you should treat servers as "Cattle not Pets" (i.e. they are disposable), you should think of AWS accounts as disposable. Some organizations give each developer their own AWS account, and only a build server can modify the Staging/Prod accounts via TerraForm or CloudFormation.
What you would typically use for this is resource level permissions. What resources / what you can control varies from API call to API call in AWS. In particular, what you would want is a resource-level permission on the DescribeInstances API call. Unfortunately, AWS does not currently support resource-level permissions on this API Call.

AWS IAM Role vs Group

The AWS official site reads role as a collection of permissions and group as a collection of users. But still they look the same to me. You attach policies to groups or roles, and then assign groups or roles to a user. What exactly are the differences between role and group?
Short answer for googlers: you can't assign role to user.
group is a bunch of users with the same policies
role is a preset of policies for service(s)
Users can asume roles according to AWS docs:
Assuming a Role
AWS Groups are the standard groups which you can consider as collection of several users and a user can belong to multiple groups.
AWS IAM Roles are all together different species; they operate like individual users except that they work mostly towards the impersonation style and perform communication with AWS API calls without specifying the credentials.
Given that IAM Roles are little different, I am emphasizing only that. There are several types of IAM Roles like EC2 IAM Roles, Lambda etc. If you consider, you can launch an EC2 instance with an EC2 IAM Role; hence forth any AWS API related communication wouldn't require any AWS Access Key or Secret key for authentication rather can call the APIs directly (however the long answer is - it uses STS and continuously recycles the credentials behind the scenes); the privileges or permissions of what it can do is determined by the IAM Policies attached to the IAM Role.
Lambda IAM Role works exactly the same, except that only Lambda function can use the Lambda IAM Role etc.
Users: End User (Think People).
Groups: A collection of users under one set of permissions (permission as policy). As per IAM standards we create groups with permissions and then assign user to that group.
Role: you create roles and assign them to AWS resource (AWS resource example can be a customer, supplier, contractor, employee, an EC2 instance, some external application outside AWS) but remember you can't assign role to user.
It’s not only users who will login, sometimes applications need access to AWS resources. For example, an EC2 instance might need to access one or more S3 buckets. Then, an IAM role needs to be created and attached to the EC2 instance. That role can be re-used by different EC2 instances.
Remember : Groups are for living. Roles are for non-living.
I think of an AWS Role as a kind of 'sudo', where each AWS Role can temporarily provide a very specific set of elevated privileges, but without needing the elevated credentials. I get the impression that like sudo, AWS Roles try to prevent privileged actions being used accidentally.
I'd be interested to hear if others agree with this analogy.
Please note that Groups are specific to local IAM users, which are not federated, and local IAM user logs do not show who has done the actions (i.e.., multiple people or applications could use the same long-term secret/access keys, and there is no record of which entity used them). If you must use local IAM users, you can place them into IAM Groups. Where this can be especially useful is to serve as a boundary -- you could place a deny policy on the group, restricting access to specific services or actions, and that deny policy will be applied to all users in the Group.
Conversely, roles can be federated, whereas local IAM users are not. You might create an on-premises AD group that serves as a member container, for example, and then the members of that AD group (and only they) can use the role that the AD group correlates to, with whatever allow or deny policies and/or permissions boundaries you've applied to the role. (Here is a link explaining the AWS ADFS federation.)
Importantly, roles allow for temporary session credentials (which is a best security practice), as their session tokens expire after a maximum of 12 hours. Equally importantly, roles do show in the logs which of the AD members with access to use the role actually did the action. You'll find this tacked to the end of the role ARN in the logs (e.g., a user ID). CloudTrail would be one of several services that indicate user activity. This is important from a logging standpoint.
Understanding IAM roles vs IAM groups (IAM indentities) is very important foundational concept . Its important to look at difference between IAM role and IAM user as essentially group is just a bunch of users performing similar functions (eg. group of developers, QA's etc.) Roles are not uniquely associated with one person (user), they can be assumed by user,resource or service who needs it to perform task at that point of time (session). Roles do not provide long-term credentials like password or access keys.
Best practice recommendation is to require workloads to use temporary credentials with IAM roles to access AWS
Please refer to link below for more clarity:
https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html
I was confused all the time about the difference between these two functions.
In short,
Role is like a tag with all the preset policies that can attach on IAM users/groups or AWS services. IAM users share the same account with the account root user (Admin) but with assigned permissions by the root user to use AWS resources within that account.
Therefore, IAM users can directly interact with AWS services; whereas IAM roles cannot make direct requests to AWS services, they are meant to be assumed by authorised entities like an IAM user or an instance. https://aws.amazon.com/iam/faqs/
I had a hard time deciphering the spirit of the given answers..
Here's what I've found:
Groups:
Intended to represent human users created within IAM who need identical policies.
Ex. Dev 1 - Dev 8 are all developers, and all need access to create dev servers.
This is similar to traditional desktop users/groups, but for HUMAN users only.
Roles:
Roles rotate automatic credentials, meaning password input isn't needed for accessing policies.
This makes it good for two things:
Giving permissions to non-humans, such as services / applications.
Ex. EC2 of type A needs access to S3 of type B.
Giving permissions to federated / outside users & groups.
Ex. Contractor A # Outside Company A needs access to your Server A.
Authentication of users & groups are handled by some service, like Azure AD.
Authorizations are then mapped to your IAM role(s), NOT users or groups.
Note: I've used Jumpcloud's Article & AWS's Documentation to gather this information. The terms "Group", "Role", and "User" become overloaded in context to SSO+IdP, and IAM.
Here's an image showing how they map roles. !Need 10 Reputation :(
Aside: There is a way of assigning Roles to normal IAM Users & Groups, but it appears to be bad practice.
Hopefully this provides clarity to the answers above.
Only one IAM Role can be assumed at a time! And there are several
situations which fits exactly this kind of permission.
Read the faq about: How many IAM roles can I assume?
The underlaying tool in use is "Permission" in both of the use cases namely: Group and IAM Role.
Group or IAM Role --> Has Policy --> Policy defines permisions --> Permissions are assigned to a Group or IAM Role.