> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuraltrust.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS CloudFront

> TrustGuard from Lambda@Edge on viewer request.

AWS WAF cannot call external services. Use Lambda\@Edge on **viewer request** with
**Include Body**.

## Coverage

| Surface    | Monitor | Block | Redact |
| ---------- | :-----: | :---: | :----: |
| LLM input  |    ✅    |   ✅   |    ❌   |
| LLM output |    ❌    |   ❌   |    ❌   |
| Tool-level |    ➖    |   ➖   |    ➖   |

**Ask** — the function returns 403 on `block` and forwards everything else, so an
`ask` gate is **allowed**. Write the rule as **Block** if you need a hard stop.

**Use it when** you serve AI endpoints through CloudFront and want the control
alongside AWS WAF. **Not when** your prompts exceed the viewer-request body
limit.

**Limits.** CloudFront **truncates the exposed body silently** above that limit —
the request does not fail, part of the prompt is evaluated and the rest goes
through unseen. Measure your prompt sizes before treating this as a control.
Lambda\@Edge has no environment variables, so the key must come from Secrets
Manager or SSM. Input only, no redaction.

Full comparison: [Coverage](/trustguard/integrations/coverage).

1. Node.js Lambda in **us-east-1**, deploy as Lambda\@Edge.
2. Viewer request + **Include Body** (body is not exposed otherwise).
3. No env vars on Lambda\@Edge — load the key from Secrets Manager / SSM at cold start, or
   bake it at deploy.
4. CloudFront truncates bodies over the viewer-request size limit.

```js theme={null}
export const handler = async (event) => {
  const request = event.Records[0].cf.request;

  if (request.method === "POST" && request.body?.data) {
    const text = Buffer.from(request.body.data, "base64").toString();
    const result = await fetch("{TRUSTGUARD_URL}/v1/evaluate", {
      method: "POST",
      headers: {
        Authorization: "Bearer <collector-api-key>",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        protocol: "llm",
        direction: "input",
        payload: { input: text },
        consumer_id: request.headers["x-user-id"]?.[0]?.value ?? "",
        session_id: request.headers["x-session-id"]?.[0]?.value ?? "",
      }),
    }).then((r) => r.json());

    if (result.status === "block") {
      return { status: "403", statusDescription: "Forbidden", body: "Blocked by TrustGuard" };
    }
    if (result.status === "transform" && result.transformed_payload) {
      request.body.data = Buffer.from(JSON.stringify(result.transformed_payload)).toString("base64");
    }
  }

  return request;
};
```
