Authorization and Amazon Verified Permissions: A New Way to Manage Permissions - Part III
Tags: aws, avp, authorization, awscommunitybuilders
Published: 2023-06-29 21:44:04

Welcome back to our series on authorization, Cedar, and AVP! In the previous [article](https://dev.to/aws-builders/authorization-and-cedar-a-new-way-to-manage-permissions-part-ii-2bgb), we explored Cedar, an open-source policy language developed by AWS. We learned about the basics of Cedar, how to write policies, and we played around with a simple Cedar Authorization Server in Rust to see Cedar in action.

In this article, we're shifting our focus to [Amazon Verified Permissions](https://aws.amazon.com/verified-permissions/) (AVP), a service that brings the power of Cedar to AWS in a serverless, fully managed manner. We'll explore what AVP is, why it's needed, and how it can simplify our authorization process. We'll also map our e-commerce scenario to AVP, showing how we can achieve the same results without needing to manage our own Rust server.

Let's dive into AVP!

## What is Amazon Verified Permissions (AVP)?


Amazon Verified Permissions (AVP) is a fully managed, serverless service that simplifies managing, enforcing, and auditing application permissions. It uses Cedar, the policy language we've been learning about, to define fine-grained, attribute-based access control policies.

AVP is designed to be highly scalable, reliable, and secure. It takes care of all the heavy lifting of policy evaluation and management, freeing us from the need to maintain our own authorization servers. This allows us to focus on our application logic, while AVP handles the complexities of authorization for us.

## Why Do We Need AVP?

Managing permissions can be a real headache, especially when we're dealing with a big application with tons of users, roles, resources, and all sorts of context to consider. Traditional methods like Role-Based Access Control (RBAC) can get out of hand as the number of roles and permissions pile up. And while Attribute-Based Access Control (ABAC) gives us more flexibility, it can be a tough nut to crack to get it right and efficient, especially when we need to make decisions based on context.

That's where AVP comes in. It's like our handy toolbox for managing permissions. It uses the power of Cedar to let us define super detailed, attribute-based access control policies. This means we can get really specific about who can do what in our application, including decisions based on context.

But the real kicker? AVP is serverless. That's right, no servers to manage, no scaling issues to worry about, and no patching nightmares. It's always there when we need it, scales automatically with our application's needs, and we only pay for what we use. Plus, it comes with some pretty cool features like a test bench functionality, audit with CloudTrail, policy stores, and schema.

## AVP and Our E-commerce Scenario

Let's revisit our e-commerce scenario and see how we can use AVP to manage our permissions. Remember, in our scenario, we have different types of users (principals) such as customers, sellers, and administrators. These users perform various actions like viewing products, placing orders, managing inventory, and handling customer service issues. They interact with different resources, including product listings, orders, and customer profiles.

Now, let's walk through how to define these principals, actions, and resources in AVP, and how to write and enforce policies using the AVP console.

## Creating a Policy Store

Before we can start defining our policies, we first need to create a policy store in AVP. A policy store is essentially a container for our policies. It allows us to group related policies together and manage them as a unit. This is particularly useful in large applications where we might have hundreds or even thousands of policies. Our application will authorize requests against a specific policy store.

There are three methods to create a policy store:

<img width="100%" style="width:100%" src="https://media.giphy.com/media/LMIlYaB8gETfpjNNvL/giphy.gif">

- Guided setup – This method guides us through the process of defining a resource type with valid actions and a principal type before creating our first policy.
- Sample policy store – This method allows us to choose a pre-defined sample project policy store. This is a great option if we're just getting started with AVP and want to view and test example policies.
- Empty policy store – With this method, we define the schema and all access policies ourselves. This is recommended if we're already familiar with configuring a policy store.

For the purpose of this article, we'll use the Guided setup method to create our policy store to make it easier for the beginning our journey with AVP.

## Guided Setup

To begin the guided setup, click on the "Guided setup" button. This will start the process of creating our policy store. It's important to note that currently, we can't set a custom name for our policy store. The ID is generated randomly. However, the AVP team has indicated that the ability to name our policy stores is a feature that will be available in the near future.

The first step in the guided setup is defining the schema.

## What is a Schema and Why Do We Need It?

In AVP, a schema is a blueprint that defines the structure of our authorization system. It specifies the types of principals (users), resources, and actions that exist in our system, and the attributes associated with each of these types.

A schema is crucial because it forms the basis for writing policies in AVP. When we write a policy, we're defining rules about what actions a principal can perform on a resource. The schema provides the "vocabulary" we use to write these rules.

For example, in our e-commerce scenario, our schema would define principals like "Customer", "Seller", and "Administrator", resources like "Product", "Order", and "Profile", and actions like "View", "Create", and "Edit".

## Step 1: Schema

Let's come back to AVP console. In the guided setup, we'll be prompted to define our schema. For our e-commerce scenario, we can use a namespace like "EcommercePlatform". This namespace will then be used to nest our entity types and actions.

<img width="150%" style="width:150%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZWNrczNkNGo3cnZsYWVzc2pidGlyZmYyd3hwNWh6dHBlcWZyZnVjNCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/pe1gGFC2c8d4spzAjc/giphy.gif">


## Step 2: Resource Types

After setting up the namespace, the next step is to define our resource types. In AVP, a resource type represents a type of object in our system that we want to control access to. Each resource type can have its own set of attributes, but for now, we'll keep things simple and not add any additional attributes.

In our e-commerce scenario, we have several types of resources that users might interact with, such as product listings, orders, and customer profiles. For simplicity, let's start by defining a single resource type: "Product".

- After defining the schema and clicking "Next", we'll be redirected to the "Resource type" step.
- In the "Name of the resource type" field, enter "Product".
- Since we're not adding any additional attributes at this moment, we can leave the "Resource attributes – optional" section empty.
- In the "Actions" section, specify the actions that will need to be authorized on resources of this type. For example, we might add actions like "View", "Create", "Edit" and "Delete". We can add an action by clicking on "Add an action", typing the action name, and then clicking "Add".
- In the "Name of the principal type" field, type the name for a type of principal that will be using the specified actions for our resource type. For example, we might enter "Customer".

<img width="150%" style="width:150%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdGN3eDVyNGJ2MmYxZnRxNHpvb3lmaW12ejN3ZWZtMWp1cjdkaXIzNyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/FiiBSvEEb66rBSrCbw/giphy.gif">

- Click on "Next" to proceed to the next step.


## Step 3: Principal Type

After defining the resource type and actions, we'll be redirected to the "Principal type" step.

- For the "Identity source", we have two options: "Custom" and "Cognito User Pool".
- If we choose "Custom", this means the principal's ID and attributes will be provided directly by our application. This is the default option and is suitable for most scenarios.
- If we choose "Cognito User Pool", this means the principal's ID and attributes will be extracted from an ID or Access token generated by Amazon Cognito. We'll need to connect to a user pool by selecting the AWS Region and typing the User Pool ID of the Amazon Cognito user pool we want to connect to.
- (Optional) We can also add attributes to the principal type by clicking on "Add an attribute". We can specify the attribute name and type for each attribute. These attributes can be referenced in our Cedar policies for attribute-based access control (ABAC).

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdnA0em53eHF6ZXRvaGs1NHYyM3I3cGFwOXI3NTNsNWdmcXhveXB2MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/cBbxLTNkxqWWgQpq2j/giphy.gif">

- Click on "Next" to proceed to the next step.


## Step 4: Policy

In the final step of the guided setup, we will define our first policy. For our e-commerce use case, we want to allow any Customer to view any Product.

In the Policy details section, we can optionally provide a description for our policy. This can be useful for documenting the purpose of the policy and the permissions it grants. We can name it "Allowing Customers to View Products".

In the Principals scope field, select "All principals". This means that the policy will apply to all principals in our policy store.

In the Resources scope field, select "All resources". This means that the policy will apply to all resources in our policy store.

In the Actions scope field, select Specific set of actions. Then, in the Action(s) this policy should apply to field, select the "View" action. This means that the policy will allow the specified action (View) on the specified resources for the specified principals.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNzk1cmZ5dnV4amVuNjY2cG1paDQ1bGV3b3dpY3BiMWZlNHkwbHp4dSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/CuABjpByWw5gbLBkXb/giphy.gif">



Review the policy in the Policy preview section. The policy should look something like this:

```bash
permit(
  principal,
  action in [EcommercePlatform::Action::"View"],
  resource
) when {
  true
};
```
This policy allows any principal to perform the "View" action on any resource. 


One might think that since any principal can see any resource with a view action, so a principal of the "Accountant" type too? In our case, the answer is no. The resources, actions, and principals are still defined by the schema we've set up in AVP, and we did not have an "Accountant" type over there.


Click "Create policy store". This will create our policy store with the defined schema and policy.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExdG4zZmNpb3E4ZXh4MTl4aXIycThqNGRtbHV2dXhpNTk1bmp5OGp2eSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/fNBRzEtgfyZRc1PhgR/giphy.gif">

And that's it! We've now created our first policy store in AVP, complete with a schema and a policy. This policy store can now be used to manage, enforce, and audit permissions.

![Policies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5g7ygkyl2mtfan44oh5.png)


## Next Steps
Take some time to explore the AVP dashboard in the AWS console. We'll see our newly created policy store there, along with options to manage our policies, schema, and test them using the test bench.

But we're just getting started. In the upcoming [article](https://dev.to/aws-builders/authorization-and-amazon-verified-permissions-a-new-way-to-manage-permissions-part-iv-schema-3hlg), we'll dive deeper into AVP. We'll explore more complex schemas, play around with the test bench, experiment with groups of resources, and add more policies to our policy store. Stay tuned.