Skip to content

Authorization is one of the foundational needs when building your applications and services. Learn how, with the help of Cedar and Amazon Verified Permissions, to to add non-trivial authorization rules to your web application.

License

Notifications You must be signed in to change notification settings

build-on-aws/bookstore-demo-app-with-authz

Bookstore Demo Application with Authorization

Context

This repository is the main asset for the AWS re:Invent 2023 breakout session titled: "Build verifiable and effective application authorization in 40 minutes" (BOA209).

It contains a sample application that demonstrates how you could add authorization layer using Amazon Verified Permissions and Cedar policy language. The backend as a serverless application, written in Python and exposed as a REST API, making use of Amazon API Gateway, AWS Lambda, and Amazon Cognito. The frontend is a Vue.js application using the AWS Amplify SDK for authentication and communication with the provided API.

Goal

As stated above, the goal of this application is to integrate an authorization (AuthZ or authz) layer into a bookstore application, which already uses Amazon Cognito for authentication. The addition of Amazon Verified Permissions (AVP) with policies defined in Cedar language will allow you to enhance, maintain in an easier way, and reason about the authorization rules. The application itself is really a demo, as it is just listing books.

For integration of the Amazon Verified Permissions (AVP) with bookstore application, you need to define a set of test users with varying attributes and roles. These users will help you validate different authorization scenarios based on the policies defined in AVP and the user attributes managed by Amazon Cognito.

Architecture & Design

Architecture Diagram

Overview of attributes inside Amazon Cognito User Pool Schema

In our bookstore application, you will use Amazon Cognito for managing user authentication. The user attributes in our Cognito User Pool are designed to support both the security and functionality of our application. Here's a brief overview of these attributes:

  1. ID: id
    • Description: Every user has a unique ID, automatically generated by Cognito. This ID helps identify users distinctly.
  2. Email: email
    • Description: Users register and sign in using their email addresses.
  3. Role: role
    • Description: Users have assigned roles that define their access within the application. Here is list of available roles:
      • Admin: Has complete access to all books (premium offers, etc.).
      • Publisher: Can manage and view their own published books.
      • Customer: Can browse and purchase books.
  4. Years as Member: yearsAsMember
    • Description: This attribute indicates how long a user has been a member of our service. It's used for offering specific features or content to loyal users.

API Design

Product Service

GET     /product                Returns details for all products (books).
GET     /product/{book_id}      Returns details for a single product (individual book).

Authorization

You can review documentation for the authorization scenarios (including available roles and users), prepared Cedar policies, and Policy Store schema inside docs directory.

Running the Example

Here you can find a list of the recommended prerequisites for this repository.

  • Pre-installed tools:
    • Most recent AWS CLI (2.13.37 or higher).
    • Most recent AWS SAM CLI (1.103.0 or higher).
    • Node.js in version 20.9.x or higher.
    • Python in version 3.10.x or higher.
  • Configured profile in the installed AWS CLI with credentials for your AWS IAM user account of choice.

Setup steps

Fork the GitHub repo, then clone your fork locally:

$ git clone https://github.com/<YOUR-GITHUB-USERNAME>/bookstore-demo-app-with-authz && cd bookstore-demo-app-with-authz

If you wish to use a named profile for your AWS credentials, you can set the environment variable AWS_PROFILE before running the below commands. For a profile named development it looks as follows export AWS_PROFILE=development.

You now have 2 options: you can deploy the backend and run the frontend locally, or you can deploy the whole project using the AWS Amplify console.

Option 1: Deploy backend and run frontend locally

Deploy the Backend

A new S3 bucket will be automatically created for you which will be used for deploying source code to AWS. If you wish to use an existing bucket instead, you can manually set the S3_BUCKET environment variable to the name of your bucket.

Build and deploy the resources:

# After cloning it, inside the the repository root:

# Creates S3 bucket if not existing already, then deploys AWS CloudFormation stacks for authentication and product service.
$ make backend
Run the Frontend Locally

Start the frontend locally:

# After cloning it, inside the the repository root:

# Retrieves backend config from AWS SSM parameter store to a .env file, then starts service.
$ make frontend-serve

Once the service is running, you can access the frontend on http://localhost:8080.

You can create an account by clicking on "Sign In" then "Create Account". Be sure to use a valid email address as you'll need to retrieve the verification code sent by Amazon Cognito. Or, you can automate the whole process by using a script:

$ python manage-app-users.py                                      \
    --command create   # ... or delete, if you want to clean-up   \
    --cognito-user-pool-id "<COGNITO_USER_POOL_ID>"               \
    --email-prefix "your-first-part-of-the-email"                 \
    --email-postfix "domain.com"

Note: [CORS](https://aws.amazon.com/what-is/cross-origin-resource-sharing/#:~:text=Cross-origin%20resource%20sharing%20(CORS,resources%20in%20a%20different%20domain.) headers on the backend service default to allowing http://localhost:8080. You will see CORS errors if you access the frontend using the IP address (like http://127.0.0.1:8080), or using a port other than 8080.

Clean Up

Delete the AWS CloudFormation stacks created by this project:

# After cloning it, inside the the repository root:

$ make backend-delete

Keep in mind that there will be also one additional Amazon S3 bucket created for storing code archives, also starting with a similar name: bookstore-demo-app-with-authz-src-.

Option 2: Automatically deploy backend and frontend using Amplify Console

One-click deployment

  1. Use 1-click deployment button above, and continue by clicking "Connect to GitHub".
  2. If you don't have an IAM Service Role with administrative permissions, select "Create new role".
    • If you already have that, you can jump directly to the 5th step.
  3. Select "Amplify" from the drop-down, and select "Amplify - Backend Deployment", then click "Next".
  4. Click "Next" again, then give the role a name and click "Create role".
  5. In the Amplify console and select the role you created, then click "Save and deploy".
  6. Amplify Console will fork this repository into your GitHub account and deploy it for you.
  7. You should now be able to see your app being deployed in the Amplify Console.
  8. Within your new app in Amplify Console, wait for deployment to complete.
    • This should take approximately ~10-15 minutes for the first deploy.
Clean Up

Delete the AWS Amplify application and AWS CloudFormation stacks created by this project. There are 3 of them, with names starting with bookstore-demo-app-with-authz-.

References

License

This library is licensed under the MIT-0 License. See the LICENSE file.

About

Authorization is one of the foundational needs when building your applications and services. Learn how, with the help of Cedar and Amazon Verified Permissions, to to add non-trivial authorization rules to your web application.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks