Multi level authentication/authorization or approvals for access/delete resource in AWS - amazon-web-services

I want to implement a security measure that enables any authenticated user to delete any AWS resource only on approval from any other member.
The main objective is to make sure that, if the creds are compromised, the user should not be able to delete any resource without approval.
Looking forward to get some expert advise and discussion on this.
I understand, the least access privilege and MFA, but still it is fulfilling our requirements.

Since this is not directly supported by AWS, you will have to set up a custom solution for this.
This is one possible solution:
Create a role with delete permissions.
Create a Lambda to use that role to delete a resource.
Implement the Lambda to only processes the delete request if the input includes at least two approvals. (This part depends on your org authentication mechanism. Could be LDAP, short term access tokens, etc)
This fulfills the two requirements you mentioned:
a security measure that enables any authenticated user to delete any AWS resource only on approval from any other member.
The Lambda will only process the request if there is at least 2 approvals.
if the creds are compromised, the user should not be able to delete any resource without approval.
In this design there are no credentials. The role you created can only be assumed by the Lambda. You can further improve the security by only allowing certain Users, Roles or Groups to be able to execute the Lambda.

Related

How can I allow an AWS user/role access to only the resources that he created?

I want to create a role for a Lambda function that allows it to create/update/delete any resource, as long as that resource was also created by it. For example, it should be able to create an SQS queue and do anything with it, but it should not have access to any other SQS queues from that AWS account.
Can this be achieved using IAM policies?
I've tried to use resourceTag and requestTag conditions for this, allowing the role to create or modify a resource only if is tagged with a specific value. Unfortunately, a lot of AWS services do not support authorization based on tags.
Are there other options for achieving this?
You could create IAM policies that only allow a user to create, update, delete resources that have a particular naming scheme. For example, you could set the policy's resource arn to have "/username*". The user would only be able to create resources that start with their username and effect those resources. They wouldn't be able to effect resources created that started with another users name and vice-versa.
It is very hard to do in practice. You would have to combine the tags that you already mentioned, along with permission boundaries.
I think the best way to achieve this is to give you application its own dedicated AWS account, so that you can scope its permissions to that account, and it doesn't have the ability to impact other applications.

How to restrict AWS Cognito users from taking certain actions?

Help is required in the following problem we're facing 😔
Any tip would be much appreciated!
Details and environment:
A multi-tenant application that aims to provide a dedicated tenant per customer (organization), in order to achieve full separation.
AWS Cognito user pool as my users' datastore and authentication provider.
an "AWS Cognito user pool" per customer (org).
Role management - based on the built-in user pool groups. Group per role and the server-side verifies that a user's access token includes a group name in it's embedded group's list.
So far so good and everything is working as expected, using AWS Amplify's SDK, for the client side's implementation. Amplify performs well and allows me to do whatever I want. The server verifies group belonging etc.
The problem:
I want to restrict non-admin users (that doesn't belong to the "admin" group) from performing certain Cognito actions via Amplify.
2 Examples:
I want to disable non-admin users' ability to modify a specific attribute's value, via Amplify.
I want to disable non-admin users' ability to modify MFA settings for themselves, via Amplify.
The actual problem started when I wanted administrators to be able to set MFA (enable/disable) for other users, but in Cognito (as I understand it) only a user can set his own MFA settings.
What I saw and already tried:
Set read/write permissions for user attributes. So the specific attribute I want to protect is modifiable only via API calls with developer credentials. That way, admins can call my server to ask for attribute modification. The server verifies the role by a group belonging according to the access token and calls Cognito API. The problem with that solution is that it covers only the attribute modification scenario.
Create an AWS Cognito identity pool for each of the user pools. For every group in every user pool, create an AWS IAM role with a policy that would restrict or allow the wanted behavior. The could actually work. The problem with that solution is that it feels like a super-duper overkill, plus it requires me to create an extra identity pool and an IAM role for each user pool. It means that every new customer that joins the service, would require (1) user pool, (2) Cognito client application, (3) identity pool and (4) IAM Role (instead of just a user pool and Cognito client app). Essentially, implementing this solution.
The real question:
Can I restrict users in a certain group from performing actions on themselves, such as disabling the MFA (even that the user-pool's MFA is set to "Optional")?
Thank you all so much! any help would be appreciated!
Well... After long research, we have come to the understanding that there is no proper right way. Every possible solution has its own pros and cons. A consultant meeting with AWS's experts taught us that:
Options Overview:
[Server Side Only] - Solution #1 that I proposed is exactly as described. Drawbacks are the same. It could work, and access to user-attributes will be restricted. Any other action that another client would make will not be blocked.
[Identity Pools] - Solution #2 that I proposed is the most accurate one. Yet I described it with one big mistake: one identity-pool can serve multiple user-pools! So essentially, we could create only one IAM role and one identity-pool per app's role. Then we match every user-pool we want to that same identity-pool and when introducing a new role to the app - just create a new group in the user-pool and match it to the IAM role. This solution is not as complicated as thought, and it would definitely do the trick. As a bonus, you'll get the ability to control and allow access to different AWS services. That being said, it still requires management and effort.
[Post-Auth Lambda] - Solution #3 that was not mentioned here, and I started to work on a day after posting this post. I blocked the write permissions of a new boolean custom attribute called "MFA". It indicates the desired MFA configuration for the user. Only a server could edit its value (and users with the admin role will have access to the server's API endpoint that can modify it). We've deployed a lambda function that would be triggered after successful authentication (post auth trigger in Cognito user-pool). It would verify a match between the desired and current MFA configurations for the authenticated user. If there is a mismatch, throw the user out because he did something that is not allowed.
*To be exact, we created one more custom attribute called "mfa_status" and it is set to true after the user has set it's MFA configurations. The lambda checks if both MFA and mfa_status are true and the real current MFA Configurations are false. if this is the case - the user is thrown out.
The Chosen One:
The solution we picked eventually is #3 (Post-Auth lambda) as it is the most detached solution. It does not require any mix with our server or client's code, any special configurations that are specific to a user pool and it still allows us to keep working with the Cognito's Amplify SDK as a client.
Thank you all for your time, I hope this post would help someone in the future.

Is there a way to add a description for IAM users in AWS?

I have users that have been added by other admins in my AWS account. I am afraid that these users might get deleted by other people.
Is there a way to add a description to an IAM user?
I don't see any way to add description/tag when you create an IAM user. One suggestion is to create a IAM group for each admin and add the user to the admin's group when a user is created/added. You can have group(s) with no policy attached.
There is currently no way to add a description to a user. There are a number of better ways to solve your core issue however. Some of the IAM Best Practices specific to your use case include:
Use AWS Defined Policies to Assign Permissions Whenever Possible - AWS-managed policies are designed to support common tasks, such as deleting and creating users. Assign these policies to the users that need them.
Grant Least Privilege - Granting only the permissions required to perform a task. Determine what users need to do and then craft policies for them that let the users perform only those tasks. This is probably the most important factor in preventing users from being deleted accidentally.
Monitor Activity in Your AWS Account - You can use logging features in AWS to determine the actions users have taken in your account, including deletion of users either accidentally or on purpose. Two very useful tools you should be using in this regard include:
AWS CloudTrail - CloudTrail provides event history of your AWS account activity, including actions taken through the AWS Management Console, including user deletions.
AWS Config – Provides detailed historical information about the configuration of your AWS resources, including your IAM users, groups, roles, and policies.
As you can see, utilising the built-in tools that AWS provides can assist you in preventing administrators from deleting users unnecessarily.
As a workaround, you can add a TAG to your user with its key named "DESCRIPTION" and put in the description as a value. Note that for the value, you are very limited to the characters you can use. For instance, you cannot use the apostrophe ('). But it is better than nothing.

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

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.

Is it possible to create an AWS IAM policy for automatic resource tagging?

I would like to set up different AWS Identity and Access Management (IAM) users so that if an AWS resource is created by that IAM user, the resource is automatically assigned a specific tag.
For example: if IAM user F creates a new EC2 instance, the instance is automatically tagged as User:MrF. Is it possible to build a custom policy that does this?
My company GorillaStack have an open source lambda function that does exactly that.
The function 'listens' for CloudTrail logs to be delivered and tag the created resource with the ARN of the user that created it. It also support cross account tagging, for cases where a central account collects CloudTrail logs for other accounts.
Github: https://github.com/GorillaStack/auto-tag
Blog Post: http://blog.gorillastack.com/gorillastack-presents-auto-tag
It got a shout out at the 2015 re:Invent conference which is pretty cool :)
Hope that helps!
This is not available when using the AWS APIs directly (i.e. there's no way to command all AWS API's to tag new resources automatically on your behalf), however, depending on the specifics of your use case you could work around that limitation by correlating the creating user with the resource via post hoc tagging:
Workaround
You could activate AWS CloudTrail, which records AWS API calls for your account and delivers log files to you and provides exactly the information you are after:
The recorded information includes the identity of the API caller, the
time of the API call, the source IP address of the API caller, the
request parameters, and the response elements returned by the AWS
service.
Based on that information, a dedicated service of yours could analyze the logs and apply post hoc tags to all resources based on the logged user and created resource via the resp. API actions. Please see my answer to Which user launched EC2 instance? for some caveats/constraints to consider when going down this route.
An even better solution (faster plus I believe cheaper than parsing through CloudTrail logs) is to use CloudTrail but in combination with CloudWatch Events.
This is the basic concept described in a diagram
The implementation is detailed in this article:
https://blogs.aws.amazon.com/security/post/Tx150Z810KS4ZEC/How-to-Automatically-Tag-Amazon-EC2-Resources-in-Response-to-API-Events
The article also describes how to setup an IAM policy that only allows the creator of a resource to perform certain actions (like start / stop, describe, edit, terminate) against it.
I would chose AWS Config. Create a rule that automatically tags resources on creation. No cost, works across multiple accounts. Great for enforcing compliance. https://aws.amazon.com/about-aws/whats-new/2019/03/aws-config-now-supports-tagging-of-aws-config-resources/
Currently there is no such feature on IAM. If what you need is allow/deny based on user names, what you could do is use variables on your policy to allow or deny access based on naming conventions, e.g.:
...
"Resource":"arn:aws:dynamodb:us-east-!:123456789:table/ItemsCatalog_${aws:username}"
...