[{"data":1,"prerenderedAt":111},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fproxies\u002Faws-cloudfront":3},{"page":4,"toc":94,"updated":110},{"path":5,"title":6,"seoTitle":7,"description":8,"blocks":9},"\u002Fdocs\u002Fproxies\u002Faws-cloudfront","AWS CloudFront proxy","AWS CloudFront First-Party Proxy for the Browser SDK","A CloudFront Function and one cache behavior on the distribution that serves your site, sending the browser SDK's calls on the issued path to Fingerly.",[10,13,18,66,69,71,75,78,80,83,85,88,90,92],{"type":11,"text":12},"p","A CloudFront Function and a cache behavior for the distribution that already serves your site. The behavior answers one path the dashboard issued, on your own domain, and sends only the browser SDK's submissions to Fingerly as its origin. It is not an open proxy: the origin is `api.fingerly.io`, the function rewrites every request to one URL on it, and every other method is refused. Version 1.0.0.",{"type":14,"level":15,"text":16,"id":17},"heading",2,"Set up","set-up",{"type":19,"steps":20},"steps",[21,28,33,45,55],{"title":22,"blocks":23},"Create the proxy",[24,26],{"type":11,"text":25},"In the dashboard, open **Integration > Proxy keys** and choose **New proxy**. Pick the environment of the public key it will forward, and **AWS CloudFront** under **How it runs**. Copy the [proxy key](\u002Fdocs\u002Fproxy-integrations#proxy-keys) it shows once, and note the path it issued, such as `\u002Fk7x2qm4a`.",{"type":11,"text":27},"The dashboard then prints the steps below, filled in with your proxy's own path and key. They stay under **Show setup** in the proxy's menu, without the key, which is never shown again.",{"title":29,"blocks":30},"Create the function",[31],{"type":11,"text":32},"**CloudFront > Functions > Create function**, runtime `cloudfront-js-2.0`. Paste the function the dashboard prints, `function.js`, whose `PATH` holds your path, then save and publish. The same function runs on both the viewer request and the viewer response.",{"title":34,"blocks":35},"Add the origin",[36,38],{"type":11,"text":37},"In the distribution that serves your site. The custom header carries the proxy key, and CloudFront always overwrites a viewer-sent header of the same name, so a visitor cannot supply their own.",{"type":39,"samples":40},"code",[41],{"label":42,"lang":43,"code":44},"Origin","text","Origin domain:  api.fingerly.io\nProtocol:       HTTPS only\nCustom header:  x-fingerly-proxy-key = fly_px_production_…",{"title":46,"blocks":47},"Add the cache behavior",[48,50],{"type":11,"text":49},"Your path exactly, with no wildcard, and the function on both events.",{"type":39,"samples":51},[52],{"label":53,"lang":43,"code":54},"Cache behavior","Path pattern:            \u002Fk7x2qm4a\nOrigin:                  api.fingerly.io\nViewer protocol policy:  HTTPS only\nAllowed HTTP methods:    GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE\nCache policy:            CachingDisabled\nOrigin request policy:   AllViewerExceptHostHeader\nViewer request:          CloudFront Functions, the function above\nViewer response:         CloudFront Functions, the function above",{"title":56,"blocks":57},"Point the browser SDK at the path",[58,64],{"type":39,"samples":59},[60],{"label":61,"lang":62,"code":63},"fingerly.ts","ts","import { load } from '@fingerly\u002Fweb-js'\n\nconst fingerly = await load({\n  apiKey: 'fly_pk_production_…',\n  endpoints: '\u002Fk7x2qm4a',\n})",{"type":11,"text":65},"The SDK posts both of its calls to the path exactly as given. Once pages use it, the proxy's row in **Proxy keys** shows it last seen, running `aws-cloudfront\u002F1.0.0`, with its requests over the last 30 days.",{"type":14,"level":15,"text":67,"id":68},"With CloudFormation","with-cloudformation",{"type":11,"text":70},"The dashboard also prints `cloudformation.yaml`: the same function, plus the parameter, origin and cache behavior to merge into your distribution's template. Pass the key as the `FingerlyProxyKey` parameter. It is `NoEcho`, so the key stays out of the template and out of version control.",{"type":72,"tone":73,"text":74},"callout","note","Anyone allowed to read the distribution's configuration can read the origin header, so limit `cloudfront:GetDistributionConfig` accordingly.",{"type":14,"level":15,"text":76,"id":77},"How the visitor's address is trusted","how-the-visitor-s-address-is-trusted",{"type":11,"text":79},"The function sends `event.viewer.ip`, the address CloudFront accepted the connection from, as `x-fingerly-client-ip`. It is not read from any header, so the visitor cannot change it.",{"type":72,"tone":81,"text":82},"warning","Put nothing in front of CloudFront for this path. Behind another proxy, the viewer address would be that proxy's.",{"type":11,"text":84},"The proxy key lives in the origin configuration, not the function, so unlike the other templates there is no key check in the code. Without the origin header, the API refuses every call with `401` and `proxy_key_missing`, because the function still sends the visitor's details. Add the header before routing traffic.",{"type":14,"level":15,"text":86,"id":87},"What it sends and relays","what-it-sends-and-relays",{"type":11,"text":89},"Upstream, to `https:\u002F\u002Fapi.fingerly.io\u002Fapi\u002Fv1\u002Fingest` only: the viewer's request with every cookie, `Authorization` and any visitor-sent `x-fingerly-*` header removed, plus the `x-fingerly-*` headers the function sets (the visitor's address, the page origin, the user agent and `x-fingerly-proxy-version: aws-cloudfront\u002F1.0.0`) and the proxy key from the origin's custom header. Other methods answer `405` with `Allow: POST`.",{"type":11,"text":91},"CloudFront Functions cannot read request bodies, so the body passes through unchanged and CloudFront's own request limits apply rather than a 1 MiB cap. The API enforces its own limit.",{"type":11,"text":93},"Back to the page: the viewer response keeps only `content-type`, `x-request-id`, `ratelimit-limit`, `ratelimit-remaining` and `retry-after` (and the framing headers CloudFront manages), drops every cookie and sets `cache-control: no-store`. CloudFront adds its own `Via` and `X-Cache` style headers after the function runs; none of them names Fingerly.",[95,96,99,101,103,105,107,108,109],{"id":17,"text":16,"level":15},{"id":97,"text":22,"level":98},"step-create-the-proxy",3,{"id":100,"text":29,"level":98},"step-create-the-function",{"id":102,"text":34,"level":98},"step-add-the-origin",{"id":104,"text":46,"level":98},"step-add-the-cache-behavior",{"id":106,"text":56,"level":98},"step-point-the-browser-sdk-at-the-path",{"id":68,"text":67,"level":15},{"id":77,"text":76,"level":15},{"id":87,"text":86,"level":15},"2026-09-25T18:31:31.000Z",1793630453192]