Skip to content

Edge Content Protection tutorial: hard paywall

This tutorial walks you through the simplest useful Edge Content Protection (ECP) configuration: a binary hard paywall. Subscribers receive the full article; everyone else sees a subscribe page with no article content. There are only two outcomes, one rule, and no prepend claim.

Scenario

Every article on your site is subscriber-only. Readers fall into one of two states:

StateJWT cookieEntitlementAccess
SubscriberPresent and validsubscriberFull article
Everyone elseAbsent or invalidHard paywall

“Everyone else” covers anonymous visitors, registered-but-not-subscribed users, and readers whose JWT has expired — all receive the same paywall template.

Step 1: Design the JWT

Your external system issues a signed JWT cookie after a reader completes a subscription purchase or signs in with an active subscription.

For this scenario you only need two claims:

ClaimValue
entitlements"subscriber"
expExpiration timestamp (Unix epoch)

No prepend claim is needed. The variant value is taken directly from the rule’s resolver-query-param.

Sample JWT payload

{
"entitlements": "subscriber",
"exp": 1763035200
}

Readers without an active subscription receive no cookie. ECP skips rules evaluation entirely and forwards the request without a variant parameter.

Step 2: Build the rules document

A single rule is sufficient for this scenario.

{
"matchers": [
{
"priority": 1,
"uri-pattern": ".*",
"entitlements-pattern": "subscriber",
"resolver-query-param": "full"
}
]
}
  • If ECP finds a valid JWT with entitlements matching "subscriber", the rule fires and appends ?variant=full to the request URL.
  • If there is no cookie, or the JWT is invalid or expired, no rule matches and the request is forwarded without a variant parameter.

Step 3: Configure the PageBuilder resolver

A single resolver handles all article URLs. It reads the variant query parameter and selects the appropriate template.

For more information on resolvers, see Configuring resolvers.

variantTemplateNotes
fullfull-articleComplete article body
(absent)hard-paywallSubscribe page; no article content rendered

Because ECP’s default behavior (no variant) produces the paywall, hard-paywall is the resolver’s default template — the one rendered when no variant parameter is present.

Step 4: Build your templates

Two templates are required.

full-article

Renders the complete article body. This template is used only for readers whose JWT contains the subscriber entitlement.

hard-paywall

Renders no article content. The page presents a subscription offer — typically a headline, a brief description of the benefit, and links to available subscription plans. This is the default template, so it is rendered for all non-subscribers regardless of whether they have an account.

End-to-end matrix

Reader statevariantTemplate
Subscriber (valid JWT)fullfull-article
Anonymous or non-subscriber(absent)hard-paywall
Expired or invalid JWT (no redirect URL)(absent)hard-paywall
Expired or invalid JWT (redirect URL configured)Redirect to your auth system

JWT expiry and the redirect flow

When a subscriber’s JWT expires and a redirect URL is configured:

  1. The reader’s request arrives at the edge with an expired cookie.
  2. ECP rejects the JWT and redirects the browser to your configured redirect URL.
  3. Your system authenticates the reader, issues a fresh JWT with entitlements: "subscriber", and sets a new cookie.
  4. Your system redirects the browser back to the original article URL.
  5. ECP validates the new cookie, the rule fires, and ?variant=full is appended.

Without a redirect URL configured, expired JWTs are silently treated as absent — the reader sees the hard-paywall template until they sign in again manually.