Is there any way of controlling access to DynamoDB data based on data in other tables? By way of comparison, Firebase Realtime Database rules have access to a snapshot of the entire database when being evaluated, so rules like this are possible:
".write": "root.child('allow_writes').val() === true"
But all my reading of the AWS permissions structure hasn't given me any clue how to achieve the same thing. There are variables that can be tested based on the current authenticated user, and some variables based on the current request, but no way I can see of referencing other data within the database.
AWS don't support this case, you're only option would be to put the access control in your application.
You can control table, item or attribute level data access in DynamoDB using a IAM policy variables. Frustratingly AWS don't even seem to publish a list of available policy variables. Typically it boils down to using Cognito sub or AWS userid, which the majority of people don't want to use as a partition keys in their tables.
Related
I am trying to setup a web application using aws Amplify. It is backed by a dynamodb table containing some data, with "user group" as primary key. So whenever a user is logged, it should only display data connected to his group. I read some aws docs about fine-grained access, but it seems that the only way is to use "user_id" as primary key (hopefully i misunderstood that). If any of you could give me some tips i would be very thankful :)
If I understand correctly you are trying to apply some sort of row isolation strategy on your dynamo table.
Your intuition about the primary key is right as stated here with the caveat that your partition key should contain your group_id (not necessarily the user_id) since you want to isolate access by groups.
Using composite partition keys is common practice in a database like Dynamo.
This will structure the DB so that it can be restricted by a IAM policy that allows for the fine grained access control on the groups that you need.
I want to build an AWS architecture for a serverless application which stores files in a DynamoDB.
This database stores data which relates to a given perimeter. On the other hand I have data (M:N links) which link users of my application to some perimeters.
I want to make sure that my users (Authenticated on Amazon Cognito via a federated OIDC provider) only access to the data related to one of their perimeters.
What is the best practice to implement this kind of access control logic with Amazon bricks ?
Is it possible to accomplish such access control logic with IAM policies at the Dynamo DB level ?
You can add a table
UserPerimeter
---
id (hash key)
userId (index - hash key)
perimeterId
And as part of your validation in your Lambda, you do a query on the index with the the user id from JWT/Cognito. This will check if he has access to the requested parameter. So basically protect your DB from your code (which is the only point of access).
You can achieve this from IAM, (check this article) but it adds too much complexity for my taste. This would be useful if the DB is used by multiple products/components/companies (which isn't a good practise anyway).
How do I use athena workgroups to restrict access of a user to a particular database?
For e.g. I have a user "readonly" who should not be able to run select query on default database. Is this possible?
The way to restrict users from querying tables is to use IAM permissions. The permissions model in Athena is unfortunately more complicated than in an isolated data warehouse or RDBMS, since Athena is a part of a larger ecosystem that also includes S3 and Glue.
There is no specific permission for running SELECT. You can restrict users to run queries by controlling whether or not they are allowed to perform the athena:StartQueryExecution action, but you can't control what kind of queries they run.
Instead you need to think in terms of access to data, and access to the catalog.
To restrict reading you restrict the user's access to the data on S3. Even if a user is allowed to run a SELECT query they will get an error if they don't have permission to run s3:ListObject and s3:GetObject on the objects in the table's prefix.
You can also restrict a user's access to the catalog objects, i.e. the databases and tables – but that does not restrict their access to the data itself, think of it more as a restriction on creating, updating, and dropping databases and tables. Even if there is a way to restrict which databases and tables a user can see in the catalog, if they have permission to read the data they can read the data directly from S3 and skipping Athena.
You can find the documentation on how to control access to catalog objects here: https://docs.aws.amazon.com/athena/latest/ug/fine-grained-access-to-glue-resources.html
Workgroups in Athena can't be used to control access to data, nor to the catalog.
I am new to AWS platform. I am trying to build a backend for a mobile app using AWS lambda, API gateway and DynamoDB using Facebook Authentication of AWS Cognito for my app.
A user are able to logged in to app and data should saved in a table with UserID (which I get from Cognito), data1, data2, data3. This only belongs to this. Let's say those are user's activities.
Again when he login to app next time, he should be able to see all his entered data.
I was looking for the example of it, I found this link which is about fine grained access control where the table is Partitioned with a particular user and permission.
https://aws.amazon.com/blogs/mobile/dynamodb-on-mobile-part-5-fine-grained-access-control/
That doesn't sound right. In a regular RDBMS centered app, the application connects to the database using a specific user in a connection string. User specific data is returned to the user using a query that is constructed on the fly with "username = user_id".
Is this above link talking about something different?
I am confused.
Thanks for your time!!
I believe the article you linked is discussing allowing an app to access DynamoDB directly, by calling the AWS API directly instead of going through a backend application layer. It is using variables in the IAM policy to only allow a user to execute queries against the table that contain their ID as the primary key.
In your case the AWS Lambda function is your backend application layer. You could simply assign an IAM role to the Lambda function that allows it to query all records in the DynamoDB table, and build queries in the Lambda function using the UserID as the query key.
I am trying to implement a public file sharing system for my application using AWS Cognito & DynamoDB. Basically users can create and sign into an account using Cognito and use this account to upload their files. Public meta data that needs to be accessed frequently goes to DynamoDB (such as ratings, download count, upload date, etc.) and the files itself to an S3 bucket.
To ensure that only the Cognito user who shared the file is allowed to delete the DynamoDB item and modify certain private attributes, I am using the Cognito identity id as the primary key for my items inside the DynamoDB, coupled with a policy rule as described in the docs. Afaik there is no other solution.
So far so good, but this obviously means that a user cannot upload more than 1 item to the database since the primary key attributes of DynamoDB items need to be unique, which is not possible since I am using the Cognito identity id for them.
I could of course create one item for each user and store the meta data for each file he owns inside maps, but this wouldn't allow me to query the items by date, rating, etc.
I'm honestly stuck and cannot think of a way to structure my database items any other way to make this work. Is this even feasible with DynamoDB?
You can create a range key with a unique id for each file, while maintaining the primary key as Cognito id which allows to keep the DynamoDB fine-grained authorization.