AWS Cloudfront
This guide explains how to set up a reverse proxy for Didomi's Privacy Center using AWS CloudFront. Two implementation options are available based on your requirements.
Choose your implementation
Option A: Use a subdomain
To implement a reverse proxy on a subdomain, you will first create an SSL certificate in AWS Certificate Manager, then configure a CloudFront distribution with two origins pointing to Didomi's servers. This approach uses pure CloudFront functionality without requiring any serverless functions.

Customer usage:
/api/*
and/*
paths directlyCloudFront Distribution - Routes
/api/*
→api.privacy-center.org
and/*
→sdk.privacy-center.org
Route 53 - DNS management for your domain
Custom Origins - Direct routing to Didomi servers
Option B: Use the main domain
To implement a reverse proxy on the main domain, you will first create a Lambda@Edge function to handle URL transformation, then configure a CloudFront distribution that routes /consent/*
requests through the Lambda function. The Lambda function removes the /consent/
prefix before forwarding requests to Didomi's servers.

Customer usage:
/consent/*
prefix for all CMP requestsCloudFront Distribution - Routes requests to appropriate origins. Matches
/consent/*
→ routes to SDK originLambda@Edge Function - Removes
/consent/
prefix before forwardingRoute 53 - DNS management for your domain
S3 Bucket - Hosts your static UI files (not required)
Custom Origins - Routes to Didomi servers:
sdk.privacy-center.org
- For SDK filesapi.privacy-center.org
- For API requests
Domain vs Subdomain Trade-offs
When implementing a reverse proxy for the Didomi SDK and its API events, you need to choose between using your main domain or a dedicated subdomain. This choice has important implications for Safari's cookie restrictions.
For more information, see this trade-off matrix to select the implementation that suits your requirements.
Implementation guide
Option A: Use a subdomain
This setup creates a pure CloudFront configuration. The Didomi SDK will use /api/*
and /*
paths through your reverse proxy.
Step 1: Create SSL Certificate
Go to AWS Certificate Manager (ACM)
Navigate to the us-east-1 region (N. Virginia)
Click "Request certificate"
Request a public certificate
Domain name: Your domain (e.g.,
cmp.example.com
)Subject alternative names (SANs): Add
.your-domain.com
if you want to support subdomainsValidation method: DNS validation (recommended) or Email validation
Validate the certificate
If using DNS validation: Add the CNAME records to your DNS provider
If using email validation: Check your email and click the validation link
Wait for the certificate status to change to "Issued"
Copy the certificate ARN
Once issued, click on the certificate
Copy the ARN (format:
arn:aws:acm:us-east-1:ACCOUNT-ID:certificate/CERTIFICATE-ID
)
Step 2: Create CloudFront Distribution
Go to CloudFront Console
Navigate to AWS CloudFront
Click "Create distribution"
Configure Origins
Origin 1: Didomi SDK
Origin domain:
sdk.privacy-center.org
Origin name:
Didomi-SDK-Origin
Protocol: HTTPS only
HTTPS port: 443
Minimum origin SSL protocol: TLSv1.2
Origin 2: Didomi API
Origin domain:
api.privacy-center.org
Origin name:
Didomi-API-Origin
Protocol: HTTPS only
HTTPS port: 443
Minimum origin SSL protocol: TLSv1.2
Configure Cache Behaviors
Default Behavior (catch-all)
Path pattern:
Default (*)
Origin: Any (will be overridden by specific behaviors)
Viewer protocol policy: Redirect HTTP to HTTPS
Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Cache policy: CachingDisabled
Origin request policy: CORS-S3Origin
API Behavior
Path pattern:
/api/*
Origin:
Didomi-API-Origin
Viewer protocol policy: Redirect HTTP to HTTPS
Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Cache policy: CachingDisabled (no caching for API requests)
Origin request policy: CORS-S3Origin (forwards all headers)
SDK Behavior
Path pattern:
/sdk/*
Origin:
Didomi-SDK-Origin
Viewer protocol policy: Redirect HTTP to HTTPS
Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Cache policy: CachingOptimized (for static SDK files)
Origin request policy: CORS-S3Origin
Configure SSL Certificate
Alternate domain names (CNAMEs): Add your domain
SSL certificate: Custom SSL certificate (select your ACM certificate)
Security policy: TLSv1.2_2021
Create Distribution
Click "Create distribution"
Wait for deployment (5-10 minutes)
Step 3: Configure DNS
Get CloudFront domain name
Copy the distribution domain name (e.g.,
d1abc123def.cloudfront.net
)
Update DNS records
For subdomain: Create CNAME record:
cmp.example.com
→d1abc123def.cloudfront.net
For root domain: Create A record pointing to CloudFront IP addresses
Option B: Use the main domain
This setup includes Lambda@Edge for URL transformation. The Didomi SDK will use /consent/*
prefix for all CMP requests.
Prerequisites: Complete Step 1 (SSL Certificate) from Option A above - the process is identical.
Step 1: Create S3 Bucket for UI (Optional)
Step2: Create IAM execution role
Navigate to IAM Console
Go to AWS IAM Console
Click "Roles" in the left navigation
Create new role
Click "Create role"
Select "AWS service" as the trusted entity type
Select "Lambda" use case from the service list
Click "Next"
Skip permissions for now
At step 2 (Add permissions), don't add any policies yet
Click "Next" to proceed
Configure role details
Enter role name:
lambda-edge-execution-role
(or your preferred name)Optionally add a description: "Execution role for Lambda@Edge functions"
Click "Create role"
Create custom permission policy
On the newly created role page, click "Add permissions" → "Create inline policy"
Switch to JSON view and paste the following policy:
{ "Version": "1", "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] }
Step 3: Create Lambda Function
Create Lambda function
Go to Lambda Console (us-east-1 region required for Lambda@Edge)
Function name:
didomi-cmp-proxy
Runtime: Use latest LTS version
Architecture: x86_64 (Lambda@Edge does not support functions with an architecture of arm64)
Add the
index.js
file to the lambda:Create a zip file (
lambda.zip
) withindex.js
at the root
Upload code
Upload the
lambda.zip
fileSet handler:
index.handler
Memory: 128 MB
Timeout: 30 seconds
Set permissions
Execution role: Select "Use an existing role" and choose the role created in step 2 (
lambda-edge-execution-role
)
Lambda Function Code Explanation
The index.js file contains the core logic for the reverse proxy.
Main Handler Function
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
const uri = request.uri;
const method = request.method;
What it does: Extracts the request details from the CloudFront event.
// Extract path after /consent/
const pathAfterConsent = uri.substring(8); // Remove '/consent/'
// Check if this is a valid Didomi request
if (!isDidomiRequest(pathAfterConsent)) {
return { status: '404', ... };
}
What it does:
Removes the
/consent/
prefix from the URIValidates the path matches Didomi patterns
Returns 404 for invalid requests
URI Modification
// For both API and SDK requests, keep the full path after /consent/
request.uri = `/${pathAfterConsent}`;
What it does:
For API requests (
/consent/api/events
): Preserves theapi/
prefix →/api/events
For SDK requests (
/consent/[API_KEY]/loader.js
): Keeps full path →/[API_KEY]/loader.js
Request Validation
const DIDOMI_PATTERNS = [
/^\\/.*$/, // Accept all paths (recommended by Didomi)
/^\\/api\\/.*$/ // API patterns
];
What it does: Validates that the request path matches expected Didomi patterns.
Step 4: Create CloudFront Distribution
Follow the same process as Option A for creating the distribution and configuring the Didomi origins (steps 1-2 from Option A)
Configure cache behaviors (KEY DIFFERENCES from Option A)
API Behavior - DIFFERENT path pattern
Path Pattern:
/consent/api/*
(vs/api/*
in Option A)Target Origin:
Didomi-API-Origin
Lambda@Edge Association:
Event:
origin-request
Function: Your Lambda function ARN
Include body:
true
Other settings: Same as Option A API behavior
SDK Behavior - DIFFERENT path pattern
Path Pattern:
/consent/*
(vs/sdk/*
in Option A)Target Origin:
Didomi-SDK-Origin
Lambda@Edge Association:
Event:
origin-request
Function: Your Lambda function ARN
Include body:
true
Other settings: Same as Option A SDK behavior
Important: Behavior order matters - API behavior (/consent/api/) must come before SDK behavior (/consent/)
Configure SSL certificate and DNS
Follow the same SSL certificate and DNS configuration as Option A (Steps 4-5 from Option A)
Step 5: Publish Lambda Version
Publish new version
Go to Lambda function
Click "Actions" → "Publish new version"
Note the version number (e.g., 1)
Update CloudFront
Go back to CloudFront distribution
Update Lambda function associations to use the published version
General information
Challenges and solutions
403 Forbidden for POST Requests
Legacy forwarded_values
config doesn't support non-cacheable methods
Use modern cache_policy
and origin_request_policy
instead
Double Slash in URLs
Extra slash added during URI construction
Remove extra slash in Lambda function URI modification
Origin Switching in Lambda@Edge
Lambda@Edge doesn't support dynamic origin switching
Use separate CloudFront cache behaviors with different origins
Lambda Function Not Updating
Lambda@Edge requires published versions, not $LATEST
Always publish new versions and update CloudFront associations
CloudWatch Logs Location
Lambda@Edge logs are in us-east-1 region with different log group name
Use correct log group: /aws/lambda/us-east-1.[function-name]
Important Considerations
Regional Requirements
Lambda@Edge: Must be created in us-east-1 region
ACM Certificate: Must be in us-east-1 for CloudFront
CloudWatch Logs: Lambda@Edge logs are always in us-east-1
Deployment Timing
Lambda@Edge: Takes 5-10 minutes to propagate globally
CloudFront: Distribution updates take 1-2 minutes
DNS: Can take up to 48 hours to propagate
Security
HTTPS Only: Configure redirect-to-https policy
CORS: Lambda function adds CORS headers automatically
Origin Validation: Only allow Didomi domains as origins
Monitor Logs
aws logs tail /aws/lambda/us-east-1.didomi-cmp-proxy --region us-east-1 --follow
Troubleshooting
Common Issues
For Both Options:
403 Forbidden
Verify cache behavior allows POST requests
Check origin request policy includes required headers
Ensure origins are accessible from CloudFront
404 Not Found
Check if request path matches expected patterns (/api/* or /sdk/* for Option A, /consent/* for Option B)
Verify origins are configured correctly
Ensure DNS is pointing to CloudFront distribution
SSL/TLS Errors
Verify ACM certificate is valid and in us-east-1 region
Check that certificate covers your domain
Ensure origins use HTTPS
Option B Only (Lambda@Edge):
502 Bad Gateway
Check Lambda function logs in CloudWatch
Verify Lambda function is published (not using $LATEST)
Ensure CloudFront is using correct Lambda version
Lambda Execution Errors
Check CloudWatch logs for Lambda@Edge function
Verify Lambda function has proper permissions
Ensure Lambda code handles all request types
Debug Steps
Check CloudWatch Logs
Look for Lambda function execution logs
Check for errors in request processing
Verify CloudFront Configuration
Check cache behaviors are in correct order
Verify Lambda associations are correct
Test Direct Origin Access
Test if Didomi origins are accessible directly
Verify SSL certificates are valid
After setting up your reverse proxy, update your Didomi SDK snippet to use your own domain instead of privacy-center.org
. This ensures that the Didomi assets are served from your configured domain.
For more information, see the guide to serving Didomi assets from your domain.
Last updated