
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.
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.
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.
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.
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).
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 resourcesThis 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.
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.
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.
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.

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.
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.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.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.
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!
The entire setup, with detailed deployment instructions, and all the code can be found on Serverless Handbook PEP and PDP
As Werner says! Now Go Build!