One of the main challenges when building a mobile or web application is authentication of users and authorization of authenticated users to access your backend resources. For example, you may have a blog where you want different users to have different access levels based on a logical grouping: Read permissions for all authenticated users, edit permissions for contributors, and admin permissions for maintainers, who in addition to moderating content, can also manage users. Designing such a system from the ground up can be challenging.

The Amplify Framework is an open source framework that provides a category based approach for building cloud powered mobile and web applications. The categories in Amplify Framework are mapped to common use cases that a developer would want to build in their application such as Auth (Authentication and Authorization), API, Storage, and even newer use cases based on AI/ML using the Predictions category. The Amplify CLI (part of the Amplify Framework) is a toolchain to create, integrate, and manage the AWS cloud services for your application. Developers can use the Auth category in Amplify CLI to easily configure authentication and authorization use cases for their applications. The Amplify CLI uses Amazon Cognito as a default provider for authentication, authorization, and user management capabilities.

Today, we are excited to share new features in the Amplify CLI that enable developers to create Amazon Cognito User Pool Groups and configure fine grained permissions on these groups for accessing underlying backend resources such as Amazon S3, API Gateway REST endpoints, and AWS AppSync GraphQL APIs. You can also set group precedence if a user is part of multiple groups. The CLI creates policies based on your input and attaches the policies to an IAM role. The role is then automatically associated to a selected User Pool Group.

In addition, developers can now easily add user management admin tasks—such as adding/removing users, enabling/disabling users, and listing all users—to their applications by leveraging a REST endpoint setup by the Amplify CLI. The REST endpoint is powered by API Gateway, which securely accesses Lambda to invoke a route and perform the requested admin task.

In this blog, we will walk through how to create and configure user pool groups, assign permissions based on groups to your backend resources, set up endpoint for admin queries, and use the REST endpoint for administrative actions from a web application.

Basics

User Pool: A user directory in Amazon Cognito. It is used to add authentication and user management to web and mobile applications.

User Pool Groups: Groups are used to create collections of users in a user pool to manage their permissions or to represent different types of users. You can assign an AWS Identity and Access Management (IAM) role to a group to define the permissions for members of a group.

Prerequisites

Install Node.js and npm if they are not already installed on your machine.

Note: At the time of writing this blog the minimum version of Node.js required is >= 8.x and for npm >= 5.x

Adding Amazon Cognito User Pool Groups

Install the and configure the Amplify CLI

$ npm install -g @aws-amplify/cli $ amplify configure

The configure step will guide you through steps for creating a new IAM user. Select all default options. If you already have the CLI configured, you do not need to run the configure command again.

Initialize the project

For this blog, let’s say you have a React application. If you do not have one you can create one using the following command:

$ npx create-react-app myapp $ cd myapp

From the root of your project folder run the command and accept defaults where applicable as shown:

$ amplify init ? Enter a name for the project: myapp ? Enter a name for the environment: dev ? Choose your default editor: Visual Studio Code ? Choose the type of app that you're building: javascript ? What javascript framework are you using: react ? Source Directory Path: src ? Distribution Directory Path: build ? Build Command: npm run-script build ? Start Command: npm run-script start ? Do you want to use an AWS profile? Yes ? Please choose the profile you want to use: default

Add Auth

Next, we add auth to our application using the amplify add auth command.

$ amplify add auth ? Do you want to use the default authentication and security configuration? Default configuration ? How do you want users to be able to sign in? Username ? Do you want to configure advanced settings? No, I am done. Successfully added resource myapp17f3aec1 locally

Next, we add user pool groups.

Add User Pool groups and set groups precedence

Run the following command:

$ amplify auth update ? What do you want to do? Apply default configuration with Social Provider (Federation) Walkthrough all the auth configurations ❯ Create or update Cognito user pool groups ? Provide a name for your user pool group: admin ? Do you want to add another User Pool Group Yes ? Provide a name for your user pool group: editors ? Do you want to add another User Pool Group No

Next question is used to set the precedence of groups.

? Sort the user pool groups in order of preference … (Use <shift>+<right/left> to change the order) admin editors

The CLI flow asks for sorting user pool groups in order of preference. Setting precedence is useful if a user is part of multiple groups as a user can only receive one set of credentials at a time. Precedence removes any ambiguity of what credentials will be received.

Configuring backend for administrative actions

As mentioned earlier, we can now use the CLI to set up a REST endpoint which securely invokes a Lambda having limited set of permissions to the User Pool.

To set up this endpoint, run the following command:

$ amplify auth update ? What do you want to do? Apply default configuration with Social Provider (Federation) Walkthrough all the auth configurations Create or update Cognito user pool groups ❯ Create or update Admin queries API ? Do you want to restrict access to the admin queries API to a specific Group Yes ? Select the group to restrict access with: (Use arrow keys) ❯ admin editors Enter a custom group Successfully added AdminQueries7a90f4c2 function locally Successfully added AdminQueries API locally Successfully updated resource myapp17f3aec1 locally

If you run an amplify status command you will see the following:

As seen above, the CLI locally created a Lambda function for admin queries and an API REST endpoint to run the administrative tasks queries against. The API is protected with a Cognito Authorizer which accepts Access Tokens from authenticated users in the User Pool. If you choose to restrict access, then only members of the selected group in the User Pool will have access.

Push your changes to backend

$ amplify push

The push command provisions a REST API endpoint “AdminQueries” which can be called from the client application with an appropriate route. For e.g. if you want to list users in a group you would have to call the route “/listUsersInGroup”. Learn more about the default routes and their functionality in the documentation here.

Note that this is a base implementation which is created by default and you can customize it based on your use case. This is an advanced feature for which we recommend you first understand the underlying architecture and remove any functionality that you do not need in your application.

You can check the groups that are created by running the following commands:

$ amplify auth console ? Which console: User Pool

This will open the Cognito console. You can find the two groups created under General settings –> Users and groups –> Groups as shown below:

Calling administrative actions from your client application

In this section, we will walk through the steps to call two of the default routes in AdminQueries in a react application. The application has 2 simple buttons: 1) To add user to a user pool group 2) To list users in a user pool group

First, we install the dependencies by running the following commands from the root of your application folder “myapp”:

$ npm install aws-amplify $ npm install aws-amplify-react

We want to add two buttons to the application which will invoke the route to the functionality that adds user to a group and list users in a group called “editors”.

Let’s assume that you already have an admin user “someadminuser” that belongs to the admin group and is going to call the administrative task of adding a user “awesomeeditor” to the group called “editors”.

Replace the code in your App.js:

import Amplify, { Auth, API } from 'aws-amplify'; import { withAuthenticator } from 'aws-amplify-react'; import React, { Component } from 'react'; import awsconfig from './aws-exports'; Amplify.configure(awsconfig); async function addToGroup() { let apiName = 'AdminQueries'; let path = '/addUserToGroup'; let myInit = { body: { "username" : "awesomeeditor", "groupname": "editors" }, headers: { 'Content-Type' : 'application/json', Authorization: `${(await Auth.currentSession()).getAccessToken().getJwtToken()}` } } return await API.post(apiName, path, myInit); } let nextToken; async function listEditors(limit){ let apiName = 'AdminQueries'; let path = '/listUsersInGroup'; let myInit = { queryStringParameters: { "groupname": "editors", "limit": limit, "token": nextToken }, headers: { 'Content-Type' : 'application/json', Authorization: `${(await Auth.currentSession()).getAccessToken().getJwtToken()}` } } const { NextToken, ...rest } = await API.get(apiName, path, myInit); nextToken = NextToken; return rest; } function App() { return ( <div align="center" className="App"> <button onClick={addToGroup}>Add to Group</button> <button onClick={() => listEditors(10)}>List Editors</button> </div> ); } export default withAuthenticator(App, true);

Notice how easy it is to add user sign-in/sign-up page to your react application using the Amplify React Authenticator component.

Next, run the application by running the following command from the root of your application folder:

$ npm start

First, you will see the sign-in/sign-up page:

After you sign-in, the app should like below with your username:

Click on “Add to Group” button. This will add the user “awesomeeditor” to the group “editors”. The Cognito console reflects this as shown below:

Clicking the “List Editors” in your app shows the list of users in the group “editors”.

Adding User Pool Groups based authorization

Next, we look at how to configure fine grained role based access control for storage category using groups that we created. The same functionality is available through the CLI for the API category when you set up a REST endpoint.

Add storage to your backend using the following command:

$ amplify add storage ? Please select from one of the below mentioned services: Content (Images, audio, video, etc.) ? Please provide a friendly name for your resource that will be used to label this category in the project: mystorage ? Please provide bucket name: mystoragebucket

The next question asks you about restricting access to user pools groups. You can chose the group(s) you want to restrict access to followed by the permissions for those groups.

? Restrict access by? Auth/Guest Users ❯ Individual Groups Both Learn more ? Select groups: (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◉ admin ◯ readonlyusers ? What kind of access do you want for admin users? ◉ create/update ◉ read ❯◉ delete ? Do you want to add a Lambda Trigger for your S3 Bucket? No Successfully added resource mystorage locally

Next, run amplify push to provisions your backend.

$ amplify push

This provisions the backend with an S3 bucket called “mystoragebucket”. The CLI creates a policy with permissions you selected for this bucket and assigns it to an IAM role associated with the “admin” group. As you can see the CLI made it easy to assign fine grained role based access control based on user pool groups.

Feedback

We hope you like these new features! Let us know how we are doing, and submit any feedback in the Amplify Framework Github Repository. You can read more about AWS Amplify on the AWS Amplify website.