My situation is this:
I'm trying to control access to an S3 bucket using unix-like home directories via AWS Cognito. These home directories should be accessible by groups of users rather than each individual user. i.e.:
s3-bucket/home/group1
s3-bucket/home/group2
s3-bucket/home/group3
When creating roles separately with group information (group name currently used as part of directory name for wildcarding), similar to this link, it works. However, I'd rather not make a separate IAM role for each group.
Before I used the enhanced flow I could restrict the role with a further policy via the assumeRoleWithWebIdentity call with STS. However when using just cognito, it expects only a role to apply.
Instead of directly applying a policy to the subject of the ID token (like ${cognito-identity.amazonaws.com:sub}), I'd rather have it use the group (like from ${cognito-identity.amazonaws.com:cognito:groups}), such that I don't have to create a role for each new group, and the variable itself would help define the resource scope.
Has anyone had much luck with this? Or using string arrays/sets in IAM resource definitions in general? I was trying to do something like
{"Fn::Select": [0, "${cognito-identity.amazonaws.com:cognito:groups}"]}
but cloudformation complains about
Template error: Fn::Select requires a list argument with two elements: an integer index and a list.
Thanks!
P.S. I see this page which states that there are no service-specific keys for cognito for use in policies, but that doesn't seem right as I've seen people use sub aud amr etc in policies in other examples on the web, although a definitive guide doesn't seem well documented.
Related
I understand the resources and identity iam policies and im trying to restrict access to a group or user to only the resources this group or user will create.
Note the resources are not yet created, so i dont have a resource arn for the ec2/s3/ecs etc. i can use in the policy definition.
I have tried to create a policy with all actions on ec2 and restrict it to a resources set to a specific group but i have an error message stating the resources are not set properly
Thanks a lot for your time and consideration
This isn't really a question anyone can answer properly. So here are a few pointers to get you going in the right direction;
AWS Service Control Policies - https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html and https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html
AWS Control Tower - https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html
AWS Policy Generator - https://awspolicygen.s3.amazonaws.com/policygen.html
All that being said, I'm not aware of a way to do what you are asking. Any AWS account is designed to be a platform for the organisation, not an individual use case. It's top down, not bottom up.
If User X wants their own separate playground, set them up with their own Account under the main Organisation, but you probably won't want to do this per user, more groups/teams of people in most organisations.
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.
We want to have deployment users to use in our pipelines, purely for programmatic access. These users will be created per project, rather than using one deployment user for all stacks.
I'm trying to lock down the resources that these deployment users have permission to change, but I'm struggling due to the fact that the ARN is not yet known until the stack is created, meaning that creating the IAM policy to restrict it to only certain resources is proving difficult.
For example, say I want to create an application load balancer (with listeners, rules etc) - I want the deployment user to have permission to create an ALB (easy enough) but I want the deployment user to only have permission to delete or modify the newly created ALB, not any other ALBs.
Any tips / smart ways to do this? The ARNs are generated and "random" as I dislike naming my resources and having to modify the names if I change a setting that requires replacement.
You can use IAM policy conditions to restrict access to resources based on tags.
For example, you can add two policy statements with a condition element to allow specific actions on a resource:
User1 can create a resource only if the request contains owner=user1 tag.
User1 can update or delete a resource only if owner=${aws:username} tag is attached to the resource.
You can find policy example in this guide:
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html
My intention is simple- to create a role that I can assign to a standard user of my AWS account so that they can read/write to one of my S3 buckets.
I've created a policy to apply to the role and I'm happy with that bit.
The thing I'm a bit confused about is the "Select Role type" screen in the management console (see attached image). I can't work out what I'm supposed to choose at this stage as none of the descriptions seem to apply to the simple thing I'm trying to achieve.
Does anyone have any idea?
I think you are on the wrong path here. Roles are not ACLs for users, but for systems and services.
See: IAM Roles
If you want to grant a user access to some AWS resources you should have a look at the policy section. Either use a pre-build (like AmazonS3ReadOnlyAccess or AmazonS3FullAccess) or define a policy on your own.
You can then assign this policy to a user. If you want to manage multiple users this way, you can also use groups to assign policies to users.
As part of the process for onboarding new customers, I need to create an S3 bucket, create a new user, and grant that user permissions to get, list, and put to that bucket. I'd like to automate this process, which means that I need to create a "Provisioning" policy that grants a service only the permissions needed to do these things.
It seems pretty straightforward to use String Conditions in my Provisioning Policy to require the names of Users and Buckets start with a certain prefix. However, the PutUserPolicy seems to just take a text blob as its argument. I'd prefer to limit my Provisioning Policy to only be able to create Policies that grant the specific permissions that I need here; ideally only being able to grant users who names match a pattern the ability to get, list, and put to buckets who names match a pattern. (If this Policy is somehow hijacked, I'd prefer to limit their ability to create a user and grant it all privileges.)
Is there any way to get this level of fine-grained control?
No. IAM doesn't go into this much detail. You can't say "Only allow a user to create a policy with these permissions".
You would need to design your system in such a way that this policy can't be hijacked. Create a template policy and just make sure a new user can't inject anything into the inputs.
Also, on a separate note, it would be considered much better practice to use one bucket and give each user a folder inside that bucket. You can still control permissions to a key in a bucket. See the blog for more on this.