3

I am building a project using AppSync and GraphQL to enable Restaurants to track orders. There are four DynamoDB tables (one for each of the following entities): Restaurants, Staff, Tables and Orders. Each Restaurant can have many members of Staff, who are each allocated to one or more Tables. Each Table can have many orders, but an order can only belong to one table (see the System Design diagram for a visualisation of these relationships).

Problem

My issue is that I need very fine-grained hierarchical access control, with 3 main concerns:

  1. Staff belonging to one Restaurant must not be able to Create, Read, Update or Delete any entities belonging to other Restaurants.

  2. All staff in a Restaurant can view all tables in the Restaurant. However, they can only view orders belonging to a table if they are allocated to that table (e.g. a StaffTableJoin object which connects that particular Staff member to that table exists.) OR they are a Restaurant admin (see part 3)

  3. A member of Staff who is a Restaurant Admin can view all orders belonging to any table in the restaurant.

A cognito user is created for each member of staff, and their permissions should be assigned based on the relationships between entities in my DynamoDB table.

Solutions Considered

I have visited the Authorization and Authentication page in the AWS docs to explore options for restricting permissions. So far, I have considered using COGNITO_USER_POOLS and AWS_LAMDBA authorization.

  1. For the approach using COGNITO_USER_POOLS, I would create a Cognito User Group for each Restaurant. When new members of staff register, they are assigned to their restaurant's user group. I would then add an groupsCanAccess field to each entity in each database. My resolvers would check that the requesting user belongs to a group which is allowed to access each resource. However this would only address concern 1, as all staff in a restaurant would then have the same permissions to access their restaurant's resources.

  2. For the approach using AWS_LAMBDA, I am not too sure how this would work, but I considered creating an Authorization lambda which checks which restaurant the requesting user belongs to. For instance, if the User was requesting an Order, I would need to check which table the order belongs to, then check if a StaffUserJoin exists (connecting the requesting User to the table). This approach seems very difficult (maybe impossible).

Any advice that could be offered is much appreciated, as I have been struggling with this for a long time. It seems like a common use case, where permissions are needed based on an object hierachy. Thanks in advance :)

Moo
  • 39
  • 5
  • 2
    this should be. possible and you'll definitely want to use user pools and cognito, I don't think lambda auth really makes sense for this use case. That being said, you can/should probably do this all with a single user pool and treat this like a multi-tenant app. I haven't done this before so can't give you concrete answer but perhaps reading this may help a bit: https://theburningmonk.com/2021/03/how-to-secure-multi-tenant-applications-with-appsync-and-cognito/ – JD D Aug 01 '21 at 22:47
  • thanks for the reply! the link is super helpful, creating a multi-tenant application will definitely help me solve my first concern and I believe I can use cognito groups to solve my third. Any insights into solving my second concern where only staff assigned to a table can view orders? – Moo Aug 04 '21 at 08:42
  • for the 2nd concern, you may just need to create a group to identify someone as a staff member (but not an admin) and you may need to add your own custom logic in your api layer to check for the role and filter the orders/tables accordingly – JD D Aug 04 '21 at 13:55

0 Answers0