AWS Logo
Menu
PEP and PDP for Secure Authorization with AVP

PEP and PDP for Secure Authorization with AVP

As authorization needs evolve, managing access efficiently becomes even more crucial. In this follow-up post, we extend our Policy Decision Point (PDP) and Policy Enforcement Point (PEP) solution by introducing Amazon Verified Permissions (AVP) for fine-grained authorization. Instead of storing permissions in DynamoDB, we leverage AVP’s centralized policy engine and Cedar policy language to define and enforce access control dynamically.

Published Feb 21, 2025
In the first part, PEP and PDP for Secure Authorization with Cognito, I introduced the concept of Policy Enforcement Points (PEPs) and Policy Decision Points (PDPs) using Lambda Authorizer in API Gateway as PEP and a Lambda based service as PDP. The authorization decision was based on the roles users held, represented by Cognito groups, with the permissions mapped in a DynamoDB table.
When running a PEP and PDP setup in a multi-tenant SaaS solution we for sure need something more powerful than a DynamoDB table with permissions. Therefor in this part we will look at using Amazon Verified Permissions (AVP) as the foundation in our PDP. Which would serve as an great choice to do Authorization in SaaS.

What is Amazon Verified Permissions?

Amazon Verified Permissions (AVP) is a fully managed service that simplifies the implementation of fine-grained access control in our applications. AVP acts as a central Policy Decision Point (PDP), where it evaluates policies and makes authorization decisions based on the attributes of the request, user roles, and similar. It doesn't only support role-based access control (RBAC), but AVP also supports attribute-based access control (ABAC) and other dynamic policies, allowing for more flexible and granular authorization decisions.
With AVP, our Lambda function (acting as the PDP) no longer has to manually parse and evaluate policies, and we don’t need to store permission mapping in a DynamoDB table. Instead, we define and manage our policies directly in AVP, which then makes the authorization decision for us.

Alternatives Open Source solution to AVP

While AVP is an excellent choice for applications specially if they run in AWS, it’s not the only solution for implementing fine-grained authorization. One alternative is Oso, an open-source authorization framework designed to provide flexible, policy-based access control. Oso allows us to define authorization logic in a declarative language and integrates with our applications across various environments. Choosing between AVP and Oso depends on our specific use case, infrastructure etc.

Caching authorization decisions

Now that we have looked at using AVP as a central part of our PDP, we should think about caching. There are pros and cons against caching, for example AWS IAM never cache any decision which ensure that updates to policies are reflected immediately. With a cache we can reduce the number of calls to AVP and by that reduce cost. We can also either cache decisions in the client or in our backend systems. I will not go in to deep in this topic more than that in this solution we will use an external cache in our backend system. The cache will be placed in DynamoDB. The reason to cache in an external source, like DynamoDB, instead of in Lambda function memory, is for all invocations of the Lambda function to benefit from the cache. With a cache like this we would need a way to clear the cache if a permission set for a user is changed. I will not implement any cache invalidation mechanism in this post.

Understanding AVP and the Cedar Policy Language

Amazon Verified Permissions (AVP) uses Cedar, a purpose-built, policy-as-code language designed for fine-grained authorization. Cedar enables us to define and enforce access control policies that dictate who can perform what actions on which resources.
Cedar policies are declarative, meaning they explicitly state the permissions without requiring procedural logic. They are designed to be easy to read while supporting powerful conditions and attribute-based access control (ABAC).

Basic Cedar Policy Example

Let's start with a simple RBAC (Role-Based Access Control) policy that allows users in the "Admin" group to perform certain actions on all resources
This policy means that any principal (user) who belongs to the UserGroup Admin is permitted to perform the listed actions on all resources, since resource is not restricted.
A second example, where we lean towards a ABAC method would be.
This means that users in JimmysFriends can view photos when the photo has the Shared tag.
In a multi-tenant SaaS system, we might want to restrict access to data belonging to a specific tenant. Cedar allows attribute-based conditions for this.
This ensures that the user can only view resources that belong to the same tenant.
In the implementation for our AVP based PDP we will use RBAC and policy similar to the first example.

Using AVP for scalable and flexible access control

By integrating (AVP) as part of our central PDP, we have simplified our policy management and enhanced the scalability and flexibility of the authorization system. AVP’s support for dynamic policies, and fine-grained access control are powerful tools for any SaaS application.

Implementation

With the introduction to AVP let's convert our PDP to use AVP for Role Based Access (RBAC) instead of a DynamoDB permission mapping. We will just deploy a second PDP into our solution and the swap so our PEP use the new PDP based on AVP instead. This entire setup is based on the solution introduced in part one, PEP and PDP for Secure Authorization with Cognito,, and as prerequisite that solution should be deployed. You find the entire solution on Serverless Handbook PEP and PDP.

Architecture Overview

Just as a reminder, the entire code and all of the architecture can be found on Serverless Handbook PEP and PDP
Looking at the overview of the architecture and call flow we can see that there is not any major changes, but instead of fetching a permission mapping from DynamoDB we will call AVP and let the service use it's policy engine to allow/deny decision.
To better understand the flow during an API access.

Setup and deploy AVP based PDP

First we need to deploy all the resources needed by AVP, what we need to do is to create a Policy Store with our policy schema. The Policies for our three different Roles with a Cedar based policy to determine what the Role has permission to do, and we need to setup our Identity Source.
This template can be fairly long as the Cedar polices and schema tend to be rather huge. So parts of this template has been left out, therefor visit Serverless Handbook PEP and PDP for the full template.

Authorization logic

The PDP Lambda will get the jwt-token, action, and resource from the PEP, our Lambda Authorizer in the API Gateway. The function will get the principal, the subject, from the JWT-Token and see if there is a cached decision. If there is not it will call AVP with all information to get an authorization decision.

Update PEP to use AVP Based PDP

To update our PEP to use the new AVP based PDP instead of the DynamoDB based, navigate to the API folder and modify the samconfig.yaml file, update the value of PDP to PDPStackName=pep-pdp-cognito-pdp-auth-service-avp then redeploy the API part of the solution. This will now swap the PDP that is used.

Testing

To test the setup of AVP we can navigate to the AVP part of the console.
Under Policy Stores you should see the policy store that was created for our PDP.
By clicking on the ID of the policy store and selecting Policies in the menu we see the list of the three created policies.
By selecting the Riders policy we can now inspect the create policy.
By selecting Schema in the menu we can inspect the created schema in a visual form.
Now, we can navigate to the Test Bench to test out our policies, fill in the information as shown in the image below. The group must be prefixed with the Cognito User Pool Id and follow pattern <COGNITO_USER_POOL_ID>|<GROUP_NAME>
If we select the action /get trainers and click Run Authorization request we should get a deny back, as the Trainer role don't have access to that Action
Swapping to the /get trainer action should instead give us an allow back.

Summary and conclusion

Implementing PEP and PDP in our authorization flow offers a highly scalable, flexible, and secure way to control access to resources. By leveraging AWS Lambda and API Gateway, we can build a serverless authorization system that separates authentication and authorization concerns, scales with demand, and simplifies policy management.
With the addition of Role-Based Access Control and Amazon Verified Permissions (AVP), combined with caching for enhanced performance, we can create an authorization solution that fits both current and future needs. Using AVP in our SaaS solutions give us a very powerful way to handle multi tenancy.
Happy coding, and stay secure!

Source Code

The entire setup, with detailed deployment instructions, and all the code can be found on Serverless Handbook PEP and PDP

Final Words

Don't forget to follow me on LinkedIn and X for more content, and read rest of my Blogs
As Werner says! Now Go Build!
 

Comments