By Ruslan Prytula July 30, 2020 10:42 PM
Authentication types in AWS Amplify

Image we’re building a blog where guest-users can see the posts, authenticated users can read, create and administrators are allowed to do everything they want. Here is a small post of how to configure the auth rules and avoid Access Denied errors.

Auth type

An auth type or auth provider type is the way for your application to interact with the GraphQL API. It could be IAM, OIDC, API_KEY or AMAZON_COGNITO_USER_POOLS. When designing the schema, you can use different auth types to target users and assign them correct permissions.

Public access

With AWS Amplify you can give public access either by using API_KEY or IAM auth type. If you go with API_KEY then when a guest opens your website, AWS will use the generated API key to communicate with the back-end. If you choose IAM, AWS creates an unauthorized identity in Cognito Identity Pool and will use that identity instead.

Private access

Private access is granted with using Amazon Cognito User Pools. There are different ways how one can target users, but I will use groups as an example. Once you create the groups using amplify cli you can use them to assign the permissions.

Let’s define the model in the schema.graphql file.

type Post
@model
@searchable
@auth(
  rules: [
    # guests users use API_KEY to read the posts
    { allow: public, operations: [read] },
    # authenticated users in 'Users' group
    { allow: groups, groups: ["Users"], operations: [create, read] },
    # authenticated users in 'Admins' group
    { allow: groups, groups: ["Admins"], operations: [create, read, update, delete] },
  ]
) {
  id: ID!
  title: String!
  description: String!
  body: String!
}

The front-end

Amplify on the front-end must know what auth type should be used in order to communicate with GraphQL api. You can pass it every time you make graphql request or configure it globally. For example, if user is a guest, we configure Amplify to use API_KEY auth type, otherwise AMAZON_COGNITO_USER_POOLS must be used.

import Amplify, { Auth } from 'aws-amplify'
...
try {
  let session = await Auth.currentAuthenticatedUser()
  let user = await Auth.currentUserInfo()
  ...
  Amplify.configure({
    "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS"
  })
} catch (ex) {
  console.warn(ex)
  Amplify.configure({
    "aws_appsync_authenticationType": "API_KEY"
  })
}

Let me end by saing that AWS Amplify is an incredible technology that allows developers to build great applications relatively fast and let AWS manage the the back-end. I think it definitely has a potential of the way how we build apps.