/license.xml via your domain, and enforcing the Crawler Authentication Protocol (CAP) using Lambda@Edge and CloudFront Functions.
Publishing RSL License
Your RSL license needs to be accessible athttps://yourdomain.com/license.xml. CloudFront proxies this path to the Supertab Connect origin using a CloudFront Function for URI rewriting, a new origin, and a dedicated cache behavior.
CloudFront Function
Create a function with runtimecloudfront-js-2.0. This runs on viewer request and rewrites the URI before CloudFront selects the origin.
Origin
Add an origin to your distribution:Cache Behavior
Create a cache behavior for/license.xml:
Use
AllViewerExceptHostHeader, not AllViewer. The SDK needs viewer headers like User-Agent for bot detection, but forwarding the Host header causes origin routing failures./license.xml behavior must sit above the default * behavior in the behaviors list. Deployment takes 10–15 minutes after saving.
Terraform Alternative
Terraform Alternative
If you manage your distribution with Terraform, use this configuration instead of the manual steps above.
CAP Enforcement
CloudFront CAP deployment combines two edge features:- CloudFront Function (viewer request): Identifies
Authorization: Licenseheaders on every request, including cache hits, without adding latency for regular traffic. - Lambda@Edge (origin request): Runs the Supertab Connect SDK to verify the token and record usage. Fires only on cache misses.
CloudFront Functions fire on every request including cache hits. Lambda@Edge origin-request fires only on cache misses. This distinction matters for billing and completeness of usage recording.
Prerequisites
You need Node.js 22+, npm, and the AWS CLI configured (aws configure or aws login).
If you have PowerUserAccess, that covers all IAM requirements. Otherwise, the deploying user needs a scoped policy.
Required IAM policy (replace YOUR_DISTRIBUTION_ID)
Required IAM policy (replace YOUR_DISTRIBUTION_ID)
Step 1: Build the Lambda Package
index.ts:
package.json:
dist/function.zip.
Step 2: Deploy to AWS
Deployment creates three resources: an IAM execution role (assumable by bothlambda.amazonaws.com and edgelambda.amazonaws.com, with AWSLambdaBasicExecutionRole for CloudWatch logging), the Lambda function in us-east-1 (required for Lambda@Edge — CloudFront replicates it globally from there), and a published, numbered version that CloudFront is granted permission to invoke at the edge. Lambda@Edge cannot use $LATEST.
The script below does all three and is idempotent — re-run it after any handler change and it publishes a new version. Save it as deploy.sh in your supertab-verify directory.
deploy.sh
deploy.sh
Prefer the console? Create the role with the Lambda +
edgelambda trust policy (shown in the script above), create the function (nodejs22.x, us-east-1, handler index.handler, timeout 10s, memory 128 MB), upload dist/function.zip, publish a numbered version, then grant lambda:GetFunction and lambda:InvokeFunction to the edgelambda.amazonaws.com principal on that version. If you update your handler later, publish a new version and repoint the behavior to the new ARN.Step 3: Create the Filtering Function
Create a CloudFront Function (cloudfront-js-2.0 runtime) that runs on viewer request. It checks whether the Authorization header contains a license token. If it does, it adds x-license-auth to the request headers — this header is used in the cache key to separate licensed and unlicensed cache entries, and its presence triggers the Lambda@Edge function on cache misses.
Step 4: Configure the Cache Behavior
Edit the behavior for the path you want to protect (the default* behavior for all requests, or a specific path like /articles/*).
Cache policy — Create a custom cache policy with x-license-auth included in the cache key headers. This ensures that requests with and without a license token produce separate cache entries — without it, a cached response from a licensed request could be served to unlicensed requests. Keep defaults for TTL, query strings, cookies, and compression.
Origin request policy — Set to AllViewerExceptHostHeader. This forwards viewer headers (including User-Agent for bot detection) to the origin while letting CloudFront set the correct origin hostname.
Do not use
AllViewer — it forwards the original Host header, which causes routing failures on S3 and API Gateway origins.
Save and wait for the distribution to deploy (10–15 minutes).
Purge Cached License
After you publish a new license version, CloudFront may keep serving the cached copy for up to 24 hours. Invalidate the license path to force a refresh. In the console, open your distribution → Invalidations → Create invalidation, and enter:https://yourdomain.com/license.xml.
Related Docs
Deploy in Your CDN
CDN-agnostic guide covering RSL serving, CAP enforcement, and robots.txt.
Other CDNs
Generic CDN patterns for platforms not listed above.