CloudFront Integration Workflow
The CloudFront integration lets you deploy Monocle without changing your application code.
This is the no-code setup path for customers who serve traffic through Amazon CloudFront. Once configured, Monocle can analyze traffic on the paths you choose, on every hostname the distribution serves, and surface results in the dashboard.
Blocking is only applied when policy-based enforcement is enabled.
How it works
The CloudFront integration deploys three pieces into your AWS account, all named monocle-*:
- A CloudFront Function on the viewer-request path that runs Monocle's checks
- A KeyValueStore that holds the integration's configuration
- A Lambda@Edge function (in
us-east-1) that verifies challenge responses
Monocle manages these through a cross-account IAM role that you create in your account. Every AssumeRole call requires the External ID shown in the Monocle dashboard (a standard confused-deputy defence), and no long-lived credentials are ever exchanged.
The role grants only the API calls the integration actually makes, each one scoped to monocle-* wherever AWS supports it.
You can use the integration to:
- Assess traffic without adding code to your site
- Choose which paths Monocle should run on
- Configure a block response
- Redeploy when plugin updates are available
- Remove the integration when it is no longer needed
Before you begin
You need access to:
- An AWS account with a CloudFront distribution serving your traffic
- Permission to run a CloudFormation stack that creates an IAM role in that account
Create a Monocle app
To start the CloudFront integration:
- Create a new Monocle app.
- Enter the app name.
- Choose CloudFront as the integration type.
- Continue to the Connect AWS step.
The Connect AWS step shows the two values the role's template needs:
- Spur's AWS account ID, which goes in the role's trust policy
- Your app's External ID, which the trust policy must require on every AssumeRole call
Create the access role with CloudFormation
The fastest path is the Launch CloudFormation stack button in the Connect AWS step. It opens your AWS console with the stack pre-filled (Spur's account ID and your External ID are already set as parameters), so you just click Create stack.
When the stack finishes, copy the RoleArn value from the stack's Outputs tab and paste it into the Monocle dashboard.
Deploying the template with your own tooling
If you deploy CloudFormation from your own pipeline (the AWS CLI, Terraform's aws_cloudformation_stack, or similar), download the template and set its SpurAccountId and ExternalId parameters to the values shown in the Connect AWS step. When the stack finishes, paste its RoleArn output into the Monocle dashboard.
The template is the only supported definition of the role. It requires a permissions boundary on every role the integration creates, limits the managed policies it can attach and the services it can pass a role to, and names each resource Monocle manages. A role written by hand would have to reproduce all of that to be as narrow, so there is no manual path.
Validate the role
Validation actually assumes the role with your External ID and lists your distributions, so a green check means the trust policy, External ID, and permissions all work.
Choose a distribution and its hostnames
- Pick the CloudFront distribution that serves your traffic. A distribution can host one Monocle app.
- Optionally list the hostnames your site answers on, from the distribution's own (its
*.cloudfront.netdomain and aliases). Monocle protects every hostname the distribution serves either way; the ones you list are what the dashboard checks after deploying.
Choose where Monocle runs
- Assessed paths (the Assessment Scope step, and later the app's CloudFront page) choose which pages Monocle assesses. Site-wide is recommended.
- Enforced paths (on the app's Configure Policy page) choose where a Policy block decision is applied.
Assessed paths can be changed later from the CloudFront page, and apply to the running deployment without a redeploy.
Configure the block response and deploy
- Configure what visitors see when your policy returns a Block decision: an HTML response with a body, page title and status code (401, 403 or 404), or a redirect to a path on the protected domain. You can change this at any time from the CloudFront page.
- Deploy. Monocle provisions the function, KeyValueStore, and Lambda, then attaches them to your distribution. The distribution propagates the change over a few minutes.
Add the Monocle script tag
CloudFront cannot add the Monocle script to your pages, so this integration needs one tag added by hand. After deploying, the app's CloudFront page shows it under Manual include: a <script> tag with a path on your own domain, stable for the deployment, so it is added once.
Without the tag, a visitor sees a short verification screen once an hour on the first assessed page they open. With it, assessment and renewal run in the background, and a request refused for a missing decision can be retried automatically.
If your pages send a Content Security Policy, allow https://js.mcl.io and 'self' in both script-src and connect-src.
Check the deployment
The CloudFront page has a Run check button. It reads the deployment's KeyValueStore and compares it with what your saved settings publish. The edge fails open on a store it cannot use, so a missing or stale item means traffic passes through unprotected while the site looks normal from outside, which is what the check is for. A problem names the item that stopped Monocle.
Blocking requires Policy API
The CloudFront integration can assess traffic without code changes.
However, assessment is not the same as blocking.
By default, Monocle will allow all traffic unless your policy configuration returns a block decision.
To actively block traffic, you must:
- Have access to policy enforcement.
- Enable the Policy API.
- Select a blocking strategy.
- In the policy's Scope, add the paths you want it to protect. These are the enforced paths: a Block decision is applied only on them, and everywhere else the integration assesses and lets the visitor through. Connected integrations apply the saved paths at the edge, so a change here needs no redeploy.
- Configure the policy rules you want to apply.
If your policy is set to Allow All, or its Scope has no paths, CloudFront will continue allowing traffic even though the integration is deployed.
Assessment logging
Assessment logging is available on the Pro plan and above. When it is on, the Lambda@Edge function writes one line each time Monocle's policy makes a decision about a visitor on a path it assesses: the decision, and the visitor's decrypted Monocle assessment, including their IP address and network signals. A visitor's decision is reused until it is due for renewal, so browsing several pages produces one line, not one per page. Each line is a JSON object with a monocle field set to assessment, so it can be told apart from anything else the function logs.
The lines are written with console.log, so they land in CloudWatch Logs. Lambda@Edge runs in the AWS Region closest to each visitor and logs there, so the lines for one distribution are spread across Regions: look in each Region's CloudWatch under the log group named after the Monocle function, prefixed /aws/lambda/us-east-1.. The CloudFront console lists the Regions a function has run in, under the distribution's Lambda@Edge errors tab, with a link to each Region's logs. See Test and debug Lambda@Edge functions for how AWS places these logs. Retention is set per log group in CloudWatch; to gather the lines in one place, add a subscription filter or your log tooling's CloudWatch integration in each Region. Monocle does not configure retention or forwarding: where your logs go is yours to choose.
To turn it on, open the app's CloudFront page in Monocle, turn on Log policy decisions under Assessment Logging, and save. The setting needs a deployment on plugin v2.1.0 or later; the page says so, and offers the update, when the deployed plugin is older.
Each line contains the visitor's IP address. Retain and forward the lines in line with your own data protection obligations. Turning the switch off stops the lines with the next request; a plan that no longer includes assessment logging stops them too, without a redeploy.
Updates and removal
- When a new plugin version is available, the admin page shows an update prompt; redeploying updates the edge functions in place. Updating a deployment made with plugin 1.x moves your distribution to a new
monocle-viewer-*function and adds its behaviors in a single change, then deletes the old function. If your access role came from an older template, the update stops before changing anything your site uses and asks you to update the stack. - Removing the integration detaches Monocle from your distribution first, then deletes the
monocle-*function, KeyValueStore and crawler schedule. Your distribution keeps serving traffic throughout. - AWS keeps a Lambda@Edge function's replicas for up to a few hours after it is detached, and refuses to delete the function until they are gone. If removal runs inside that window, the
monocle-*Lambda function and its role stay behind. They receive no traffic and cost nothing, and you can delete them once AWS allows it. - Deleting the CloudFormation stack after removal revokes Spur's access entirely.