Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Guidance for Moving your Paywall to the Edge on AWS

Summary: This implementation guide provides an overview of the Guidance for Moving your Paywall to the Edge on AWS, its reference architecture and components, considerations for planning the deployment, and configuration steps for deploying the Guidance. This guide is intended for solution architects who want to implement a paywall running at the network edge in their environment.

Guidance overview

Publishers face two conflicting requirements when serving content: deliver content quickly by using a Content Delivery Network (CDN) and protect and monetize content using a paywall. The conflict arises because CDNs operate at the network edge, while paywall logic is usually available only at the originating website.

With Amazon CloudFront, publishers do not need to choose between a good user experience and monetization. Instead, they can combine their CDN and paywall in a single system. CloudFront makes this possible by invoking a compute resource at the network edge using Amazon Web Services (AWS) Lamba@Edge functions.

This implementation guide provides an overview of how to build a paywall with CloudFront and Lambda@Edge and includes a reference architecture, discussion of authentication and authorization considerations, and estimated pricing.

Architecture overview

This section provides a reference implementation architecture diagram for the components described in this Guidance.

Architecture diagram

architecture diagram

Figure 1: Paywall architecture diagram on AWS

Architecture steps

  1. Client authenticates using an Amazon Cognito User Pool (or another identity provider).

  2. During authentication, Cognito’s pre-token generation process invokes an AWS Lambda function.

  3. Lambda function looks up the user’s subscriptions in Amazon DynamoDB (or another data store) and adds them to the JSON Web Token (JWT) as custom claims. This provides a secure mechanism for communicating the subscription information to the paywall. Note that the publisher can add other authorization claims if needed to support paywall logic.

  4. Cognito returns the JWT to the Client, which stores it in a cookie for use in subsequent requests.

  5. Client initiates a request for content, such as a news article, served by Amazon CloudFront. To authorize the request, the client includes the JWT in a cookie.

  6. CloudFront invokes a Lambda@Edge function to update the viewer request headers based on whether or not the user has a subscription. Note that the publisher should follow a URL convention that allows CloudFront to send content requests to the Lambda@Edge function responsible for paywall logic. This will ensure that the function only runs when needed and thus reduce costs. More details can be found in a companion blog post that provides a sample implementation.

  7. The Lambda@Edge function validates the JWT to ensure that it has not expired or been altered. The function compares the subscriptions listed in the JWT claims against the request URL to determine whether the user has access to the content. The function then adds a custom header to the web request to indicate whether or not the user is a subscriber.

  8. CloudFront creates a cache key based on the custom header added in Step 7. If content is not in cache, CloudFront sends an origin request, which in this architecture is represented by an Amazon API Gateway endpoint. If the content is in cache, CloudFront skips to Step 12.

  9. API Gateway invokes a Lambda function to retrieve the requested content.

  10. The Lambda function examines the custom header added in Step 7 to determine if the user has a subscription. If the user has a subscription, it retrieves content from Amazon Simple Storage Service (Amazon S3) or DynamoDB based on an identity provided in the request URL. If the user does not have a subscription, the function can return a message that the user is not authorized to view the content.

  11. API Gateway returns the response generated by the Lambda Function, which will either be the full content or a message saying that the user is not authorized to view the content.

  12. After serving content to the client, CloudFront caches it using a key that includes the customer header added in Step 7, thus enabling different versions of the content to be cached for subscribers and non-subscribers.

Using this architecture, paywall logic can run at the edge cache and the content will be served directly from the CloudFront cache at the network edge. Requests will only go to the origin if content has not previously been cached in CloudFront.

AWS services in this Guidance

AWS serviceDescription
Amazon CloudFront CoreFor all content requests, Amazon CloudFront invokes Lambda@Edge function that handles paywall logic. Specifically, the function determines whether the user has a valid subscription for the content item requested. CloudFront can then retrieve the right version of the content from cache or, if the item has not been cached, send the request to the origin.
AWS Lambda@Edge CoreThe Lambda@Edge applies paywall logic to determine whether a user has access to a content item.
Amazon Cognito CoreCognito authenticates users and generates a JSON Web Token (JWT) that contains claims used by the paywall to determine whether the user can access content.
AWS Lambda CoreLambda functions are used primarily to add claims to the JWT issued by Cognito. Lambda can also be used to retrieve content when requested by the user. However, your implementation may use another mechanism to generate content items.
Amazon DynamoDB SupportingIn this Guidance, DynamoDB provides subscription, content, and content metadata at very low latency.
Amazon Simple Storage Service (Amazon S3) OptionalIn this Guidance, content items can be stored in Amazon S3 as part of the website origin.
Amazon API Gateway OptionalIn this Guidance, origin requests are served by an API Gateway endpoint integrated with an AWS Lambda function. However, publishers can use a range of other technologies, including a traditional web server.


We recommend creating a budget through AWS Cost Explorer to help manage costs. Prices are subject to change. For full details, refer to the pricing webpage for each AWS service used in this Guidance.

Sample cost table

The following table provides a sample cost breakdown for deploying this Guidance with the default parameters in the US East (N. Virginia) Region for one month.

For this estimate, we assume the publisher has 100,000 active monthly subscribers, of which 30,000 login and are active on the site each day. When on the site, each user reads 10 articles on average. The average article size is 100KB and contains 250KB of images. On average, 1,000 unique articles are accessed each day across all the site visits. Articles expire from the CloudFront cache every 24 hours. You can adjust these estimates to better match your own publishing scenario.

AWS serviceDimensionsMonthly Cost (USD)
AWS Cognito100,000 active users per month without the advanced security feature.$275.00
AWS Lambda (JWT generation)JWT expires every hour and users generally on site for slightly more than an hour, invoking 2 JWTs to be generated per visit. 30,000 logins x 2 X 30 JWTs = 1.8M Lambda calls.$0.73
AWS DynamoDBHolds list of user subscriptions.Assume 1GB of storage plus for 100KB items and 1.8M reads per month from Standard table with no provisioned capacity.$5.88
Amazon CloudFrontAssume 80% traffic to US, and 10% to Europe and 10% to Asia Pacific. Total data to US is 2,520MB per month and 215MB to other regions. 21.6M HTTP calls in the US and 2.7M to other regions.$28.34
AWS Lambda@Edge (paywall logic)30,000 users making 10 content requests each day of the month (30,000 x 10 x 30 invocations). The function is expected to run 10 milliseconds with 128MB of allocated memory.$5.96
Amazon API Gateway (content origin)Only the first call for content from subscribers and non-subscribers goes to origin each day. We assume that half of the content requests come from subscribers and half come from non-subscribers. Since 1,000 unique articles are requested each day, that results in 2,000 REST API calls to the content origin each day.$0.21
AWS Lambda (content origin)60,000 invocations each month to serve content. Assume response in 200 milliseconds and minimal memory and storage configuration. Pricing does not include any free tier.$0.04

In the architectural diagram, the origin is represented by an API Gateway endpoint integrated with a Lambda function that retrieves content from DynamoDB and/or Amazon S3. These services have been included for completeness, but publishers may choose from a range of different options, including traditional webservers. We have not included cost estimates for storing content in either DynamoDB or S3, as this will vary depending on the amount of content in the publisher’s back archive.


When you build systems on AWS infrastructure, security responsibilities are shared between you and AWS. This shared responsibility model reduces your operational burden because AWS operates, manages, and controls the components including the host operating system, the virtualization layer, and the physical security of the facilities in which the services operate. For more information about AWS security, visit AWS Cloud Security.

When implementing this Guidance, you must have a mechanism to ensure that requests submitted to your origin come from the Amazon CloudFront distribution you created to handle content requests and that implements your paywall logic. CloudFront and its associated AWS Lambda@Edge function set a request header that indicates whether the user has a subscription to view content. If your origin accepts requests from a source other than CloudFront, callers can spoof the request header and claim to have a subscription.

One way to restrict access is to use the Amazon API Gateway to handle origin requests. With the API Gateway, you can define an API Key that is only known to the AWS Lambda@Edge function that provides paywall logic. The function can then set the API Key in an x-api-key header for every content request to access the origin.

Supported AWS Regions

This Guidance uses the Amazon Cognito service, which is not currently available in all AWS Regions. You must launch this solution in an AWS Region where Amazon Cognito is available. For the most current availability of AWS services by Region, refer to the AWS Regional Services List.

Guidance for Moving your Paywall to the Edge on AWS is supported in the following AWS Regions:

Region name 
US East (Ohio)Canada (Central)
US East (N. Virginia)Europe (Frankfurt)
US West (Northern California)Europe (Ireland)
US West (Oregon)Europe (London)
Asia Pacific (Mumbai)Europe (Milan)
Asia Pacific (Seoul)Europe (Paris)
Asia Pacific (Singapore)Europe (Stockholm)
Asia Pacific (Sydney)Middle East (Bahrain)
Asia Pacific (Tokyo)South America (Sao Paulo)


Service quotas, also referred to as limits, are the maximum number of service resources or operations for your AWS account.

Quotas for AWS services in this Guidance

Make sure you have sufficient quota for each of the services implemented in this solution. For more information, see AWS service quotas.

To view the service quotas for all AWS services in the documentation without switching pages, view the information in the Service endpoints and quotas page in the PDF instead.


Demian Hess


Customers are responsible for making their own independent assessment of the information in this document. This document: (a) is for informational purposes only, (b) represents AWS current product offerings and practices, which are subject to change without notice, and (c) does not create any commitments or assurances from AWS and its affiliates, suppliers or licensors. AWS products or services are provided “as is” without warranties, representations, or conditions of any kind, whether express or implied. AWS responsibilities and liabilities to its customers are controlled by AWS agreements, and this document is not part of, nor does it modify, any agreement between AWS and its customers.