aws cognito - allow group-chat participants access to s3 bucket - amazon-s3

I'm implementing an iOS app with group-chat support, where users can add photos, other files.
Decided on AWS S3 as storage back end, using Cognito Federated Identities to authenticate upload/downloads - data pumped to/from S3, not via our servers.
So far
my implementation allows a user/identity to upload & download to their their own folder on an S3 bucket (example policy arn:aws:s3:::mybucket/users/${cognito-identity.amazonaws.com:sub}/* the variable being the identityID/user_id).
However
I've not been able to find a secure way that allows only participants in a group-chat to upload/download from that group-chat's folder on S3.
Any ideas?
some thoughts on a possible flow:
first, user upload photo to own folder, [ I know how ]
then, the system copies over the photo into the group-chat's folder [ I know how ]
associate group-chat folder with the identities of participants [ not sure how - there could be thousands of groups & participants ]
EDIT 1: as #MyStackRunnethOver suggest, could use one IAM role/credential to manage all upload/download request for users (that belong to said group) [ big security concern if credential compromised ].
EDIT 1: could use PreSigned URLs: files uploaded to user's own folder, presigned url stored on group-chat entries [ max url-life 7days though ]
client caching helps until participants join/leave a group frequently
requires server-side scheduled job to renew expired PreSigned URLs
Any commends/ideas appreciated

Your question boils down to:
"Given that users are part of groups, how can I give users access to group-specific subdirectories based on group membership?"
As I see it, you have two options:
Give each user the "key" to all directories they're a member of. This could mean adding a permission to that user for each group, or providing them with access to a new IAM role for each group. This is the "come up with a way to have fine-grained permissions for S3" strategy.
Don't distribute any directory-specific keys. Instead, when a user requests a certain directory, check whether they're in the group that directory belongs to. This is the "build a fine-grained data storage system around S3" strategy.
I recommend the latter approach, because instead of having an IAM role or a credential per user or per group, you give all your users one credential: the credential needed to make requests of your S3 wrapper. If you keep track of which groups your users are in, all your wrapper needs to do is check the user -> groups mapping to see if a request should be fulfilled. The front end can use the same mapping to prettify the UI: a user is only shown the option to upload / download from the groups they are a member of. In this case, I would envision the mapping as a Dynamo table that is updated whenever a user signs up, joins a group, leaves a group, or deletes their account. You can identify your users by their Cognito credentials, which include user-specific fields.

Related

Limit bucket access based on user in minio

I am busy setting up minio for the first time and I would like to limit each user so that they can only see buckets they create, or public buckets.
The idea being that admin can see all buckets, but user1 can only see buckets created by user1, etc.
Is this possible?
I know that using mc policy I can set a buckets access policy to none, download, upload, public. To the best of my knowledge, setting the policy to none will require authenticated access to a bucket - but this will allow any authenticated user which is not what I want.
I have come across this ticket on github - https://github.com/minio/minio/issues/6811
This will create a user policy that limits the users access to a single bucket. The provided example does not allow the user list buckets (private and self created), create new buckets, etc. This user can only access the bucket listed in the policy.
Answering my own question with feedback from the minio team
No it is not possible, we do something similar to what AWS does, user
is not tied to buckets . Buckets exist for all users you just
selectively give them access.

Google Cloud equivalent of Amazon STS

Amazon STS offers the ability to take an IAM token and create a limited subset of the abilities of that token for other use. The subset of abilities can be by time (expiring in N hours) and by allowed operations (e.g. read one S3 bucket but not all the S3 buckets the original token can read).
Because this is done using the S3 ARN format which which supports wildcards in the S3 key name, that means it's possible to create a sub-token that can read part of an S3 bucket.
Looking through Google Cloud Storage's's access control docs I couldn't find the equivalent of this functionality in GCS.
To be more specific, I'd like to create a bucket with these four objects:
/folder1/file1
/folder1/file2
/folder2/file3
/folder2/file4
And given a token with permissions to access all files indefinitely, produced a limited subset of the token with permissions to view just the objects in /folder2/* (so /folder2/file3 and /folder2/file4) for N hours.
Is this possible in GCS like it is in S3/STS?
Currently, in GCP there are no tokens with a limited subset of the abilities of another token.
The most similar thing to what you are asking are Signed URLs, since they allow access time-limited access to Cloud Storage objects.
I don't know why you need them to have abilities that are a subset to the ones of another token, but in your case you could just create Signed URLs with permissions to view the objects in /folder2/*

How to safely extend credentials to other contributors to my S3-hosted OS project

I have an open source project with several contributors. The project's home page is hosted on Amazon S3. At the moment, the S3 bucket is on my personal account. Only I have access to it, and I pay the hosting (~$5 a month). There are other personal buckets on my account that contributors should not have access to.
I'd like to allow other contributors to modify the site. I'd also like to enable e.g. TravisCI to deploy to the site, which requires extending some credentials to third parties.
Is it necessary to set up a separate Amazon account entirely, or is IAM sufficient for my needs?
If IAM is the way to go, should there be a single IAM user shared among all contributors, or should I create a separate one for each contributor?
Do I need MFA? If so, how to safely distribute TOTP keys?
Any provisions I should make for succession (i.e. bus factor)?
Anything else I should know?
Thanks for any ideas or experiences here.
Is it necessary to set up a separate Amazon account entirely, or is IAM sufficient for my needs?
You should probably have an account for this project that is separate from any accounts you use for purposes unrelated to this project, for clean separation and in case you want to hand over control. What isn't in the account doesn't need to be protected from users who shouldn't see it.
Cross-account privileges are possible, so if others already have accounts, it's possible for you to authorize their existing credentials without knowing their secrets, but it's more complex.
If IAM is the way to go, should there be a single IAM user shared among all contributors, or should I create a separate one for each contributor?
You should absolutely create one for each contributor. That's kind of a no-brainer. Accountability.
Do I need MFA? If so, how to safely distribute TOTP keys?
It depends on your need for the added security. MFA is great and it's also a hassle. But you don't have to (and shouldn't) distribute the MFA secrets for virtual MFA. The user can log in with his/her credentials and create and download that themselves if you allow it.
Any provisions I should make for succession (i.e. bus factor)?
Heh, bus factor. Yes, you probably need a trusted adjutant with a high privilege level. In my accounts we don't actually use the root credentials, ever, but typically two people have a physical copy of the root credentials, though we do sometimes ride together in the same elevator, and we really shouldn't do that.
Anything else I should know?
Read the documentation. It takes a bit of time to sink in, but it takes less time if you get your hands dirty and play with it. Be sure when granting privileges that you verify that things which should not work do indeed not work, not just verify that things which should work indeed do work. But that applies to any authentication and authorization implementation.
Use IAM instance roles in EC2. Even if you can't think of a reason why an instance needs a role, give it one with no permissions anyway, because an instance can only be given a role at launch... yet Formerly, you could only add an IAM role to an instance at launch, but AWS announced on 2017-02-09 that you can now attach an IAM role to an instance after launch. As always, you can change the permissions granted to a role at any time.
Read about user groups. Attach users to groups and policies to groups to simplify granting the same privileges to multiple users.
Unrelated: activate billing alerts for your account to notify you when costs exceed thresholds you select.

The Best Solution for an AWS Mobile App, DynamoDB, & S3 Scenario

I am planning a game app for mobile devices. Users will log into the game using their existing social media account to streamline data capture. Company B would like to directly save player data and scoring information from the mobile app to a DynamoDS table named Score Data When a user saves their game the progress data will be stored to the Game state S3 bucket.
What is the best approach for storing data to DynamoDB and S3?
Option 1: Use an EC2 Instance that is launched with an EC2 role providing access to the Score Data DynamoDB table and the GameState S3 bucket that communicates with the mobile app via web services.
Option 2: Use temporary security credentials that assume a role providing access to the Score Data DynamoDB table and the Game State S3 bucket using web identity federation.
Many architects I talked to Option 1 is the right one. But according to AWS doco, it appears Option2 can be valid too. Any inputs would be appreciated!
I would strongly consider Option #2 using Amazon Cognito to provide temporary credentials to your users that enable them to directly and specifically access DynamoDB and S3.
Generally speaking, you need to:
Create a new Cognito Identity Pool and set up 2 IAM roles -- one for authenticated users and one for unauthenticated users (optional). https://docs.aws.amazon.com/cognito/devguide/getting-started/?platform=ios
Authenticate a user via your own authentication provider or via external providers like Facebook, Twitter, etc., and then use Cognito to create temporary credentials for them. https://docs.aws.amazon.com/cognito/devguide/identity/external-providers/
Use the credentials to access DynamoDB and/or S3. Your AWS resources will be protected as long as you set up your IAM roles appropriately. For example, you can give fine grained access to your DynamoDB table so that users cannot access rows that don't belong to them. See the following link for more details: https://docs.aws.amazon.com/cognito/devguide/identity/concepts/iam-roles/
The Cognito developer guide is here: https://docs.aws.amazon.com/cognito/devguide/.

How do I remove a "grantee" user from S3 permissions tab?

This is really a two part question:
I'm seeing some users in the "Grantee" dropdown for editing S3 permissions within the AWS console.
Where are those users coming from?
How can I delete them?
They aren't in IAM so I'm not really sure where they're coming from.
A grantee can either be an AWS account (which you probably added in the past) or a predefined AWS "group", such as "Authenticated Users", "All Users" or "Log Delivery". Please have a look at ACL Overview, on AWS docs, for more information.
For removing grants from a given file (or from a set of files), you can use the PUT Object acl operation.
It is not clear, on the documentation, what you need to do in order to remove an user from the "Grantee" list. I performed some tests and this is how S3 is behaving:
If you select a file using the S3 Management Console and add permission to a new user (not yet in your grantees list), using his email address (make sure the email belongs to a valid Amazon account), that user does NOT go to the bucket ACL, but goes to the object ACL. This user also goes to the Grantees list permanently (even though his friendly name, instead of his email address, is what shows up there).
If you log out from the AWS console and log in again, the user is still on the Grantees list and you can give him permissions for other objects.
If you remove the given user's permissions on every object, log out and log in again, the user will not show on the Grantees list anymore.
If you add a given user to the Bucket ACL (either via API or via the AWS Console), the user will always be in the Grantees list for objects on that bucket.
This makes me think the Grantees list contains the entire list of users in your bucket's ACL plus a cache of users with permissions to objects in your bucket (which is cleared upon logging out, if you remove those permissions).
So, I would try first removing the users you don't want from your bucket's ACL, and then (via API, of course) remove those user's permissions for the objects in your bucket.
If there is a specific grantee name that you can't find in IAM, it's probably the default grantee which corresponds to yourself. Its name is the same as your AWS Forum nickname.