I’m attempting to create a multi-tenant application with DynamoDB and Cognito. The documentation is pretty clear on how to implement fine-grained authorisation so that users can access only their own records, by adding a condition to the IAM access policy like so:
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:sub}"
]
}
}
This is great for allowing users to read & write their own records, when the Cognito user id is the hash key of the row, but I’m struggling with how to allow other users to have read only access to some records.
Take as an example my model for a student who has has multiple courses:
{
“student_id”: “ABC-1234567”,
“course_name”: “Statistics 101”,
“tutors”: [“Cognito-sub-1”, “Cognito-sub-2”],
“seminar_reviews”: [
{
“seminar_id”: “XXXYYY-12345”
“date”: “2018-01-12”,
“score”: “8”,
“comments”: “Nice class!”
},
{
“seminar_id”: “ABCDEF-98765”
“date”: “2018-01-25”,
“score”: “3”,
“comments”: “Boring.”
}
]
}
(Cognito-sub-1
is the Cognito id of a tutor)
With the policy conditions above applied to the user’s IAM role, the user could read & write this document since the hash key (student_id
) is the Cognito id of the user.
I’d also like the tutors listed in the document to have read-only access to certain attributes, but I can’t find any examples of how this can be done. I know that I can’t use the dynamodb:LeadingKeys
condition since tutors is not the hash key of the table. Can this be done if I set up a Global Secondary Index (GSI) that uses the list of tutors as the hash key?
If this can be done with an index, I assume that this would only allow read access to that index (since an index can’t allow write operations). Is there any alternative method to allow write access based on an attribute that is not the hash key?
Alternatively, can I use a longer string as the hash key, concatenating attributes like ”owner”:
and ”read-only”:
that contain lists of Cognito IDs and consume this within my policy to create a more fine-grained permissions model based only on the hash key? This assumes a policy can decode lists from a string, since DynamoDB does not allow a hash key to be a list, JSON object or similar.
I haven’t been able to find any resources that consider fine-grained access control beyond allowing users to read/write only their own records, so if anyone can direct me to some, that would be a great start.
You can restrict access to specific attributes easily (just the attributes).
However, in order to achieve more fine-grained access patterns you'd have to either:
Generally speaking, when designing NoSQL applications, you should always evaluate how you consume your data. They are usually tailored for specific use-case - unlike RDBMS, which allow very general queries regardless.
There's a nice example regarding modeling relational data in terms of DynamoDB available here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With