Modern applications rarely get away with simple, static role-based access control anymore. Whether you’re building a SaaS platform, an internal admin system, or any multi-tenant service, your authorization logic can quickly become very complex to manage, test, and audit. It often gets entangled with your essential business logic, replicated across multiple services, or clouded by unclear permissions within a database.
Cerbos solves this by acting as a stateless Policy Decision Point (PDP) that allows you to keep your authorization logic separate from your actual application code. This renders your access control testable and simple to adapt without touching your core business services.
In this guide, you’ll learn how to run Cerbos as a serverless Lambda function, using AWS API Gateway, with policies hosted in the Amazon S3 service. You’ll also see how to configure, deploy, test, and maintain this setup.
Cerbos is an open-source authorization solution that decouples your access control logic from your application code. The Policy Decision Point serves as one of the key parts of the system, rigorously evaluating incoming requests according to your defined policies to determine whether access should be granted or denied based on roles, attributes, resources, actions, and many other parameters.
The AWS API Gateway is a completely managed service for building, publishing, and securing RESTful and HTTP APIs at scale. It acts as the "front door" to your Lambda functions and other backend services, with request routing, ensuring security, implementing throttling, and providing additional resources. By combining API Gateway with Lambda, you can build robust serverless applications with minimal operational overhead.
Deploying Cerbos as a Lambda function using API Gateway offers several advantages:
If you are looking for flexible authorization with minimal maintenance and easy AWS integration, this is an effective plan.
It is easy to run Cerbos in a container or VM, but if your stack is already serverless, managing EC2 or ECS just for authorization doesn’t make sense. You never have to provision or patch servers, and your Cerbos policies remain version-controlled and simple to modify in S3.
This is a lightweight, low-cost, and seamless fit into an AWS environment. Your other microservices or Lambdas can invoke the PDP via HTTP, and you can scale it up with provisioned concurrency for low-latency validations.
Before you start, you’ll need to set up a few things:
The fundamental components of Cerbos are policies. In this example, we’ll keep it simple and store your policies in S3. Cerbos uses a configuration file, config.yaml
, to know where to find your policies and how to configure startup.
Create a new folder on your local machine for your Cerbos Lambda project:
mkdir cerbos-lambda && cd cerbos-lambda
While utilizing the blob
storage driver for s3
, Cerbos scans the entire S3 bucket prefix to find any existing policy files.
In your new directory, create a new file named config.yaml
:
server:
httpListenAddr: ":3592"
storage:
driver: "blob"
blob:
driver: "s3"
bucket: "my-cerbos-policies-bucket"
region: "us-east-1"
Next, write your first policy. Here’s a minimal resource policy for a document
resource type:
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: "default"
resource: "document"
rules:
- actions: ["view", "edit"]
effect: EFFECT_ALLOW
roles: ["editor"]
Create a policies
directory with your .yaml
policy definitions. Cerbos will discover and compile these files at startup.
Example of directory structure:
cerbos-lambda-project/
├── Dockerfile # Builds the Lambda image with Cerbos binary
├── config.yaml # Cerbos config pointing to S3 bucket
├── policies/
│ └── document.yaml # Example policy
└── template.yaml # AWS SAM template
aws s3 mb s3://my-cerbos-policies-bucket
aws s3 cp config.yaml s3://my-cerbos-policies-bucket/config.yaml
aws s3 cp policies/ s3://my-cerbos-policies-bucket/policies/ --recursive
Your Lambda function will need permission to read from the S3 bucket and write logs to CloudWatch. In the IAM console (or using AWS CLI), create a new role with a trusted entity on Lambda. Attach a policy that allows s3:GetObject
on your policies bucket andlogs:*
for CloudWatch.
A simple inline policy might look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:GetObject"],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-cerbos-policies-bucket/*"
},
{
"Action": ["logs:*"],
"Effect": "Allow",
"Resource": "*"
}
]
}
AWS Lambda can run custom container images. Cerbos provides an example template you can adapt. The key idea is you’ll package the Cerbos binary and a small bootstrap
script that launches the Cerbos server.
To build a container image, create a Dockerfile
in your project folder. In your Dockerfile
, include the config.yaml
in the image. This step is important so that Cerbos knows how to locate the S3 bucket and policies during startup
Place your config.yaml
into /opt/cerbos/
during the build, or read it from S3 at runtime if you prefer. For this example, the config.yaml
references S3 for the policy backend.
So, the final Dockerfile
should look like this:
# Use AWS Lambda custom runtime base image
FROM public.ecr.aws/lambda/provided.al2
# Download the Cerbos binary
RUN curl -L https://github.com/cerbos/cerbos/releases/latest/download/cerbos-linux-amd64.tar.gz \
| tar -xz -C /opt
# Copy the Lambda bootstrap
COPY bootstrap /var/runtime/bootstrap
RUN chmod +x /var/runtime/bootstrap
# Copy the Cerbos config
COPY config.yaml /opt/cerbos/config.yaml
# Command for Lambda runtime
CMD ["cerbos", "server", "--config=/opt/cerbos/config.yaml"]
Your bootstrap file (from the Cerbos AWS Lambda repo) will look something like this:
#!/bin/sh
set -euo pipefail
/opt/cerbos server --config=/opt/cerbos/config.yaml
Build the Docker image locally:
docker build -t cerbos-lambda
Push the image to your own ECR repository:
aws ecr create-repository --repository-name cerbos-lambda
aws ecr get-login-password | docker login --username AWS --password-stdin .dkr.ecr.<region>.amazonaws.com
docker tag cerbos-lambda:latest .dkr.ecr.<region>.amazonaws.com/cerbos-lambda:latest
docker push .dkr.ecr.<region>.amazonaws.com/cerbos-lambda:latest
Now, you will define our Lambda function and API Gateway by creating a template file. You will use AWS SAM CLI to define your tech stack. Create a template.yaml
in your project root directory:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
CerbosFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
ImageUri:
MemorySize: 512
Timeout: 10
Role: arn:aws:iam::<account_id>:role/<role_name>
CerbosApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
DefinitionBody:
swagger: 2.0
info:
title: Cerbos PDP
version: 1.0
paths:
/{proxy+}:
x-amazon-apigateway-any-method:
isDefaultRoute: true
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CerbosFunction.Arn}/invocations
httpMethod: POST
type: aws_proxy
Outputs:
ApiEndpoint:
Description: "URL of the Cerbos API Gateway"
Value: !Sub "https://${CerbosApi}.execute-api.${AWS::Region}.amazonaws.com/prod/"
This configuration will ensure that the API Gateway seamlessly forwards all HTTP methods and paths to the Lambda, while maintaining the complete functionality of the Cerbos REST API. The proxy integration is crucial so that Cerbos receives the request exactly as your client sends it.
To deploy the stack via SAM, you can run the following commands:
sam build
sam deploy --guided
The guided deploy will ask you for stack name, AWS region, and confirmation to create roles. Once deployed, SAM outputs your API Gateway URL. You can monitor the deployment progress in the AWS CloudFormation.
You can also, utilize CloudWatch to monitor your logs in real-time and ensure that Cerbos initiates without any errors.
aws logs tail /aws/lambda/<function-name> --follow
Look for a line like Cerbos PDP server listening on [::]:3592
. That means it’s ready. Now test your PDP with curl or Postman. For example:
curl -X POST \
https://<api-id>.execute-api.<region>.amazonaws.com/prod/api/check \
-H "Content-Type: application/json" \
-d '{
"requestId": "test",
"actions": ["view"],
"resource": {
"kind": "document",
"policyVersion": "default",
"id": "1",
"attributes": {}
},
"principal": {
"id": "alice",
"roles": ["editor"],
"attributes": {}
}
}'
If your policy allows the editor
to view
a document
, you’ll see an allow decision in the response.
Cerbos is equipped with OpenTelemetry (OTel) for both tracing and metrics, including support for Lambda environments. You can export traces to AWS X-Ray or your own tracing backend. All authorization decisions are logged to CloudWatch, so you’ll have an audit trail for compliance.
To change permissions, just update your policy files and push them to the same S3 bucket.
aws s3 cp policies/ s3://my-cerbos-policies-bucket/policies/ --recursive
Your authorization service should never be wide open. API Gateway gives you tools to secure your endpoint:
Think about how your application services will authenticate when calling the PDP, and keep logs for auditing. You can use signed IAM requests or even mutual TLS (mTLS) if you choose to run Cerbos behind VPC-based Lambda to allow only trusted requests.
Deploying Cerbos as a Lambda function provides an excellent solution for integrating fine-grained authorization into your serverless applications while reducing the infrastructure overhead. You get all the benefits of policy-as-code, easy auditing, and the power to update rules without messing up your application containers.
While deploying to production, make sure to tune concurrency, lock down your endpoints, and test your policies carefully. By integrating Cerbos in your tech stack, your developers can focus more on shipping features, while your security and compliance standards stay firm and auditable.
To understand more about Cerbos, explore the official Cerbos documentation, experiment with the Cerbos AWS Lambda template, and start creating additional policies that include derived roles, conditions, and hierarchical rules.
Once you have done the setup, you can easily integrate Cerbos into your CI/CD pipelines. By version-controlling your policies alongside your infrastructure, you enable your teams to benefit from transparent, testable authorization rules that adapt and grow with your product.
Authorization is hard, but it doesn’t have to stay tangled in your application code. Cerbos offers you an escape route, and combined with AWS Lambda and API Gateway, you can deploy it seamlessly across any cloud environment.
If you want to dive deeper into implementing and managing authorization, join one of our engineering demos or check out our in-depth documentation.
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.