AWS Amplify with GraphQL - Defining authentication rules by different types of users

774 views Asked by At

Using Amplify, GraphQL, AppSync, Cognito, DynamoDB

Having the following model:

type Post
@model
{
  id: ID!
  content: String!
  author: String!
}

I want my rules to enable the following case:

  1. Only Admin users can create, update and delete Post
  2. Some Posts where only premium users allow to read
  3. Some Posts where all logged in users allow to read
  4. Some Posts where all users (also unauthenticated) allow to read

What is the best way to implement it using the mentioned tools?

Thanks

2

There are 2 answers

1
Myz On BEST ANSWER

From your question, it is not clear how you define "Some Posts" and how you would differentiate one from another. If I was designing this, I would have at least one more field in my Post type to manage the access level (For example: 3 (Admin) > 2 (Premium) > 1 (Logged-in) > 0 (Unregistered)), like so;

type Post
@model
{
  id: ID!
  content: String!
  author: String!
  accessLevel: Int!
}

To manage this on user level, I think your best bet is to manage it using Cognito groups (like mentioned in the official documentation) and assign appropriate permission for each group.

Things you would need in Cognito:

  1. A user pool which will contain all of your registered users.

  2. A user group for premium members.

  3. A user group for your admins.

Things you would need in your AppSync:

  1. For Admin users to create, update and delete Post:

    type Mutation {
       createPost(id:ID!, content:String!, author:String!):Post!
       @aws_auth(cognito_groups: ["Admin"])
       updatePost(id:ID!, content:String!, author:String!):Post!
       @aws_auth(cognito_groups: ["Admin"])
       deletePost(id:ID!, content:String!, author:String!):Post!
       @aws_auth(cognito_groups: ["Admin"])
    }
    
  2. For some posts only visible to premium, logged-in or unregistered users to read:

    type Query {
       getPost(id:ID!):Post!
       @aws_api_key @aws_cognito_user_pools
    }
    

    Furthermore, you can use the accessLevel in your resolver to filter out the result based on which post you want to be visible to premium, logged-in or unregistered users.

0
bhizmi On

I used @Myz answers. And https://aws.amazon.com/blogs/mobile/graphql-security-appsync-amplify/ for full solution:

  type Post
  @model
  @auth(
    rules: [
      { allow: owner }
      { allow: groups, groups: ["Admin"], operations: [create, update, delete] }
      { allow: groups, groupsField: "group", operations: [read] }
    ]
  ) {
  id: ID!
  content: String!
  author: String!
  group: [String] # or String for a single group
}