# AWS CloudFront

> Deploy Centinel Analytica on an existing CloudFront distribution via Lambda@Edge.

Source: https://docs.centinelanalytica.com/platforms/cdn-edge/aws-cloudfront

## Overview

This guide covers the console workflow for installing the Centinel Lambda\@Edge function.
After associating the function, allow 15-20 minutes for CloudFront to propagate the protection globally.

## Prerequisites

* Centinel secret key
* CloudFront distribution you can edit
* AWS Console access with Lambda and CloudFront permissions

## Install

1. **Prepare the package**

   1. Download [`centinel-cloudfront.js`](https://docs.centinelanalytica.com/downloads/centinel-cloudfront.js).
   2. Open the file and replace the empty `CENTINEL_SECRET_KEY` value with your key.
   3. Zip the modified `centinel-cloudfront.js` to create a deployment archive.

2. **Create the Lambda function**

   1. Switch the AWS Console region to &#x2A;*N. Virginia (us-east-1)**.
   2. Go to **Lambda → Create function → Author from scratch**.
   3. Name the function (e.g. `centinel-cloudfront`), choose a currently supported **Lambda\@Edge Node.js runtime**, and create it.
   4. In the **Code** tab, select **Upload from → .zip file** and upload your archive.
   5. Under **Configuration → Runtime settings**, set **Handler** to `centinel-cloudfront.handler`.
   6. Under **Configuration → General configuration**, set **Timeout** to 5 seconds and **Memory** to 128 MB. These are the Lambda\@Edge maxima for a viewer-request function, not preferences. If the validator is slow, lower `CENTINEL_TIMEOUT` rather than raising these.
   7. Under **Configuration → Permissions**, edit the execution role's trust relationship so it trusts both `lambda.amazonaws.com` and `edgelambda.amazonaws.com`. CloudFront refuses the association without the second principal.
   8. Choose **Actions → Publish new version** and note the versioned ARN. CloudFront rejects `$LATEST`, so always associate a published version.

3. **Associate with CloudFront**

   1. Open **CloudFront → Distributions**, select the distribution to protect, and edit the cache behavior you want covered.
   2. In **Function associations**, click **Add function**, choose **Lambda\@Edge**, paste the versioned ARN, and set the event type to **Viewer request**.
   3. Click **Add function** again and add the **same ARN** with the event type **Viewer response**. One function, two associations: the viewer-request pass decides, the viewer-response pass delivers the session cookie. Without it, allowed visitors never receive a cookie and every request is revalidated.
   4. Save the behavior to start global deployment.

## Configure

Edit these constants at the top of `centinel-cloudfront.js` before zipping it.

| Setting                      | Default                           | Purpose                                                        |
| ---------------------------- | --------------------------------- | -------------------------------------------------------------- |
| `CENTINEL_SECRET_KEY`        | empty                             | Required. While empty, every request is forwarded unvalidated. |
| `CENTINEL_PROTECTED_PATHS`   | empty (all paths)                 | Paths to protect. `*` matches a single path segment only.      |
| `CENTINEL_UNPROTECTED_PATHS` | 30 static extensions              | Paths to skip. `*.ext` matches at any depth.                   |
| `CENTINEL_VALIDATOR_URL`     | `validator.centinelanalytica.com` | Alternate validator endpoint.                                  |
| `CENTINEL_TIMEOUT`           | `300`                             | Validator timeout in ms. Unrelated to the Lambda timeout.      |
| `CENTINEL_LOG_ENABLED`       | `true`                            | Gates the `[Centinel]` log lines the Verify step looks for.    |

Two behaviors worth knowing before you deploy:

* **Fails open.** A missing key, a timeout, an unparseable response, or an error all allow the request through. After a validator failure the function also stops calling the validator for a spell, backing off up to five minutes, so a sustained outage leaves traffic unvalidated for that window.
* **Allowed requests go straight to the origin.** A viewer-request function cannot both forward a request and set a cookie on the response, so the session cookie is carried to the viewer-response pass on an `x-centinel-set-cookie` request header and written out there. That header also reaches your origin, where it is inert; strip it in an origin-request function if unknown headers are logged.

Viewer-request functions can only return a small generated response, so a large block or challenge
page cannot be delivered on this platform and CloudFront answers 502 instead. Keep custom pages small.

## Verify

* Watch the distribution status until it says **Deployed** (15-20 minutes).
* Lambda\@Edge logs land in the region nearest the viewer, in the log group `/aws/lambda/us-east-1.<function-name>`, not in us-east-1.
* Browse the distribution domain to confirm traffic flows normally.
* Check CloudWatch logs for entries prefixed with `[Centinel]` if you need to troubleshoot.

## Changelog

* **v1.2.0** — Session cookie via viewer-response
* **v1.1.0** — Honor validator status codes
* **v1.0.2** — Typo fix
* **v1.0.1** — Response header passthrough
* **v1.0.0** — Initial release
