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

# Configuración de Amazon CloudFront

> Dirige el tráfico de asistentes de IA a Profound Dynamic Bot Rendering con una sola CloudFront Function y un grupo de orígenes, sin Lambda@Edge.

Esta guía conecta una distribución de CloudFront existente con Dynamic Bot Rendering. Esta configuración agrega una CloudFront Function en la solicitud del espectador (viewer request) para seleccionar un origen para las solicitudes de páginas de asistentes de IA que cumplan los requisitos.

Esta configuración no usa Lambda\@Edge. Dos propiedades hacen posible esta integración:

* Con el reenvío del `Host` del espectador deshabilitado, CloudFront usa el dominio de origen personalizado para su encabezado `Host` y para la Indicación de Nombre de Servidor (SNI) de TLS. Conserva esta configuración en ambas políticas en el paso 3.
* El endpoint de CloudFront de Profound devuelve `cache-control: no-store` por sí mismo, de modo que CloudFront nunca almacena una segunda copia, más desactualizada, del contenido que Profound ya almacena en caché.

<Note>
  Las solicitudes dirigidas a Profound usan el endpoint de CloudFront `GET https://concierge.tryprofound.com/v1/concierge/cloudfront/{path}`. Nunca construyes esa URL a mano. La configuración **Origin path** del origen antepone el prefijo, y el URI de la solicitud pasa sin modificaciones.
</Note>

## Por qué el diseño es así

Dos reglas de CloudFront determinan todo lo que sigue:

1. Una función de viewer request no puede cambiar el comportamiento de caché (cache behavior) con el que coincide una solicitud. CloudFront selecciona el comportamiento antes de que se ejecute la función, y reescribir el URI no hace que vuelva a evaluarse. Por lo tanto, el tráfico de asistentes permanece en el mismo comportamiento que el tráfico humano, en lugar de en un comportamiento dedicado con su propia política de caché.
2. Una función de viewer request puede cambiar el origen, incluida la creación de un grupo de orígenes por solicitud con conmutación por error (`cf.createRequestOriginGroup`, runtime `cloudfront-js-2.0`).

De esto se derivan dos consecuencias:

* El enrutamiento se realiza cambiando el origen, no el comportamiento. Como **Origin path** es una configuración por origen, una conmutación por error a tu origen predeterminado usa automáticamente la ruta original, sin prefijo. No es necesario reescribir rutas.
* Las solicitudes de asistentes y humanas comparten la política de caché del comportamiento, por lo que la clave de caché debe dividirse con un encabezado marcador (paso 3). Sin él, CloudFront puede servir a un asistente una copia almacenada en caché para humanos, o viceversa.

## Requisitos previos

* Una distribución de CloudFront existente

* Permisos de AWS Identity and Access Management (IAM) para distribuciones, funciones y políticas de caché de CloudFront

* Tu clave de API de Dynamic Bot Rendering, un dominio registrado, una política de servicio vigente y una página de prueba publicada conocida. Consulta [Antes de empezar](/es/dynamic-bot-rendering/overview#before-you-start).

* Solo páginas públicas y no personalizadas. El ejemplo permite `/`, `/pricing`, `/docs` y `/docs/getting-started`. Reemplázalas por páginas públicas revisadas; no incluyas rutas de API, autenticación, cuenta, administración ni recursos del framework.

* Registra las asociaciones de funciones, los orígenes y las políticas existentes para poder revertir los cambios. Conserva la lógica existente de seguridad, autenticación y reescritura. Si combinarla requiere un cambio en el diseño del enrutamiento, detente y revísalo por separado.

* Confirma que las reglas de firewall, los desafíos para bots y las listas de orígenes permitidos admiten tanto el tráfico de asistentes como las solicitudes de origen/scraper de Profound. El marcador de bucle no es una forma de eludir la autenticación ni el firewall.

## Configuración

<Steps>
  <Step title="Crea el origen de Profound">
    Abre **CloudFront → Distributions → tu distribución → Origins → Create origin**.

    | Configuración | Valor |
    | - | - |
    | Origin domain | `concierge.tryprofound.com` |
    | Origin path | `/v1/concierge/cloudfront` |
    | Name | `Profound_Origin` |
    | Protocol | HTTPS only |

    Agrega dos encabezados de origen personalizados:

    | Encabezado | Valor |
    | - | - |
    | `x-concierge-api-key` | Tu clave de API de Dynamic Bot Rendering |
    | `x-concierge-host` | El host de tu sitio público, por ejemplo `www.example.com` |

    CloudFront sobrescribe cualquier encabezado con el mismo nombre enviado por el espectador al reenviar a este origen, por lo que un cliente no puede falsificar la clave de API ni el host. La función del paso 2 también los elimina, como defensa en profundidad.

    <Note>
      **¿Sirves más de un nombre de host desde esta distribución?** Un `x-concierge-host` estático solo funciona para un único host público, y los encabezados de origen estáticos prevalecen sobre cualquier valor que establezca la función. Para una distribución con varios dominios, omite aquí ese encabezado personalizado, quita el comentario de la línea marcada en la función de abajo e incluye `x-concierge-host` en la clave de caché en el paso 3 para que también se reenvíe. El reenvío por sí solo no separa las respuestas almacenadas en caché para distintos hosts. Revisa también la identidad del host para las respuestas humanas y de respaldo antes de habilitar varios hosts.
    </Note>
  </Step>

  <Step title="Crea la función de viewer request">
    Abre **CloudFront → Functions → Create function**. Asígnale el nombre `profound-bot-rendering` y elige el runtime `cloudfront-js-2.0`. Los grupos de orígenes requieren el runtime 2.0.

    ```js theme={null}
    import cf from 'cloudfront';

    // Keep this list in sync with the supported assistants in the Profound docs.
    var BOT_RE = /duckassistbot|chatgpt-user|gemini-deep-research|perplexity-user|amzn-user|mistralai-user|claude-user|claude-code|codex/i;

    // Replace with reviewed public, non-personalized page paths.
    var PUBLIC_PATHS = ['/', '/pricing', '/docs', '/docs/getting-started'];
    var PUBLIC_HOSTS = ['www.example.com'];

    function handler(event) {
        var request = event.request;
        var headers = request.headers;

        // Never trust these from a client. The API key and host come from the
        // origin's custom headers; the route marker feeds the cache key, so a
        // spoofed value could pollute the assistant cache entry.
        delete headers['x-concierge-api-key'];
        delete headers['x-concierge-host'];
        delete headers['x-concierge-url'];
        delete headers['x-concierge-route'];

        // Loop protection: Profound stamps x-concierge-request on its own origin
        // fetches. Never route those back to Profound.
        if (request.method !== 'GET' || headers['x-concierge-request']) {
            return request;
        }

        // CloudFront exposes cookies separately from request.headers.
        if (headers.authorization || Object.keys(request.cookies || {}).length > 0) {
            return request;
        }

        var ua = headers['user-agent'] ? headers['user-agent'].value : '';

        var isAssistant = BOT_RE.test(ua);
        var isPublicPage = PUBLIC_PATHS.indexOf(request.uri) !== -1;
        var host = headers.host ? headers.host.value : '';

        if (!isAssistant || !isPublicPage || PUBLIC_HOSTS.indexOf(host) === -1) {
            return request;
        }

        // Split the cache key. This header is in the behavior's cache policy,
        // so assistant responses never collide with human cache entries.
        headers['x-concierge-route'] = { value: 'bot' };

        // Multi-domain distributions only (see Step 1): derive the host from
        // the viewer Host header instead of a static origin custom header.
        // headers['x-concierge-host'] = { value: headers.host.value };

        // Try Profound first; fall back to your own origin if Profound is down
        // or misconfigured. CloudFront accepts 400, 403, 404, 416, 429, 500,
        // 502, 503 and 504 as failover criteria. 401 is not allowed, so a 401
        // from a bad API key surfaces to the assistant instead of failing over.
        // 404 is deliberately omitted: Profound fails open internally and
        // returns your origin's own status, so a 404 is your real 404 and
        // retrying would double-fetch. 429 is also omitted and passes through.
        cf.createRequestOriginGroup({
            originIds: [
                { originId: 'Profound_Origin' },
                { originId: 'YOUR_DEFAULT_ORIGIN' }
            ],
            failoverCriteria: {
                statusCodes: [400, 403, 500, 502, 503, 504]
            }
        });

        return request;
    }
    ```

    Reemplaza `YOUR_DEFAULT_ORIGIN` por el ID del origen predeterminado existente de tu distribución y `PUBLIC_HOSTS` por los hosts registrados para este origen; luego selecciona **Publish**. Para el encabezado de host estático, incluye solo ese único host. Mantén la lista exacta de rutas públicas permitidas alineada con las rutas de tu sitio. Las solicitudes con cookies o autorización conservan su enrutamiento existente; la función no las envía a Profound.

    La función solo enruta `GET`; todos los demás métodos vuelven al enrutamiento existente. Los grupos de orígenes de CloudFront admiten conmutación por error para `GET`, `HEAD` y `OPTIONS`. El criterio `503` configurado habilita la conmutación por error ante fallos de conexión; `504` la habilita ante tiempos de espera de respuesta. Antes de implementar, establece y registra un presupuesto acotado de intentos de conexión, tiempo de espera de conexión y tiempo de espera de respuesta del origen principal que deje tiempo para la solicitud de respaldo. Los valores predeterminados de CloudFront pueden dedicar 30 segundos solo a los intentos de conexión (tres intentos de 10 segundos). Prueba la latencia total resultante; no asumas que la conmutación por error es inmediata. Consulta [CloudFront origin failover](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/high_availability_origin_failover.html).
  </Step>

  <Step title="Actualiza las políticas de caché y de solicitud al origen">
    CloudFront elimina cualquier encabezado o cadena de consulta del espectador que las políticas del comportamiento no incluyan. Esto ocurre antes de la solicitud al origen, independientemente de lo que haya decidido la función. Se requieren tres configuraciones en el comportamiento que sirve tus páginas.

    **1. Agrega `x-concierge-route` a los encabezados de la clave de caché.** Las políticas de caché administradas por AWS no se pueden editar. Si el comportamiento usa una, primero copia todas sus configuraciones en una nueva política personalizada y luego agrega el encabezado. Mantén **Minimum TTL** (tiempo de vida) en `0`. En la variante con varios dominios, incluye el `x-concierge-host` de confianza en la identidad de caché, además de reenviarlo. El marcador de bot por sí solo no distingue entre hosts.

    **2. Incluye en la clave de caché las cadenas de consulta de las que dependen tus páginas** (o "All"). Las cadenas de consulta de la clave de caché también llegan al origen. Una política de solicitud al origen puede reenviar cadenas de consulta adicionales sin incluirlas en la clave, pero entonces las respuestas que varían según esos valores pueden compartir una entrada de caché. Si ninguna política incluye una cadena de consulta, CloudFront la elimina. Verifica tanto el reenvío como la identidad de caché para cada variante admitida.

    **3. Reenvía el `User-Agent` del espectador mediante la política de solicitud al origen.** De forma predeterminada, CloudFront reemplaza `User-Agent` por `Amazon CloudFront` en las solicitudes al origen. Entonces Profound clasificaría cada solicitud enrutada como un agente desconocido y fallaría en modo abierto de forma permanente, sin servir ni programar ningún renderizado. Usa una lista de encabezados personalizados permitidos para `User-Agent` y, cuando sea necesario, `Accept` y `Accept-Language` (además de `x-concierge-host` en el caso de varios dominios). Conserva la configuración de compresión necesaria. No uses **AllViewer**: el reenvío del `Host` del espectador puede sobrescribir el nombre de host del servicio y romper el enrutamiento al origen o TLS. Excluye `Host`, `Cookie` y `Authorization` del espectador tanto de la política de caché como de la de solicitud al origen; los valores de la clave de caché también se reenvían. Estas políticas también se aplican al tráfico humano. Si el comportamiento existente necesita estos encabezados o cookies, detente y revisa la compatibilidad antes de cambiarlo. CloudFront documenta `originOverrides` por origen para `hostHeader` y `sni` en [request origin groups](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/helper-functions-origin-modification.html); un origen del cliente que requiera un host diferente necesita que esa compatibilidad se revise por separado. Este ejemplo no elige ni agrega una sobrescritura. Las solicitudes de origen de Profound no reenvían las credenciales del espectador, y las páginas publicadas no son variantes por sesión ni por idioma.

    <Warning>
      Para esta configuración, agrega `User-Agent` a la política de solicitud al origen en lugar de a la clave de caché. Una política de solicitud al origen se aplica a todo el comportamiento, por lo que CloudFront ahora también reenvía el `User-Agent` del espectador en las solicitudes humanas. Si tu origen varía su HTML según el `User-Agent` (por ejemplo, con marcado distinto para móvil y escritorio) sin la variación correspondiente en la clave de caché, CloudFront puede servir una variante almacenada en caché a otros espectadores. Confirma que la clave de caché existente ya tiene en cuenta las variantes de tu origen. El contenido que depende de la configuración regional, la geografía y otros encabezados también requiere revisión. Si esto requiere un cambio en el diseño de la caché, detente antes de implementar. Usar el `User-Agent` sin procesar en la clave puede reducir considerablemente la reutilización de la caché.
    </Warning>
  </Step>

  <Step title="Asocia la función con el comportamiento">
    Abre **Behaviors → el comportamiento de tus páginas → Edit**. Establece la política de caché del paso 3 y luego, en **Function associations**, establece **Viewer request** en tu CloudFront Function `profound-bot-rendering`. Para un comportamiento sin lógica de borde existente, no se necesita ninguna asociación de origin request ni de origin response. No elimines las asociaciones existentes. Combina y conserva la lógica de viewer request existente antes de asociar esta función; detente si eso requiere una decisión de diseño.

    Guarda y espera a que la distribución termine de implementarse.
  </Step>

  <Step title="Verifica">
    ```bash theme={null}
    curl -sD - -o /dev/null https://www.example.com/pricing -A 'chatgpt-user'
    ```

    Comprueba el estado HTTP, un `x-concierge-request-id` válido y el `x-concierge-bot-kind` esperado. En tu página publicada conocida, exige también `x-concierge-cache: HIT` y el cuerpo renderizado esperado. Prueba el tráfico normal de navegador, los métodos distintos de GET, las rutas excluidas y las solicitudes con credenciales frente a su comportamiento existente.

    Prueba la conmutación por error a nivel de CDN solo en staging o en una distribución aislada. Registra la configuración original del origen, configura un origen de prueba inaccesible y repite una solicitud de asistente no almacenada en caché. Espera la respuesta del origen predeterminado después del tiempo de espera configurado, sin `x-concierge-request-id`. Restaura la configuración original y espera a que se propague. Un `401` no activa la conmutación por error; los estados `400` y `403` configurados sí lo hacen, lo que puede ocultar errores de configuración. Las respuestas de respaldo almacenadas en caché pueden persistir hasta que venza su TTL.

    Las comprobaciones completas y el significado de los encabezados están en [Verificación y solución de problemas](/es/dynamic-bot-rendering/verify-and-troubleshoot).
  </Step>
</Steps>

## Cómo se comporta la división de caché

* Las solicitudes humanas nunca llevan el marcador, porque la función elimina cualquier copia proporcionada por el cliente. El marcador separa sus entradas de las de los asistentes, pero los cambios en las políticas de consultas y encabezados pueden afectar las tasas de aciertos de caché para humanos.
* Las solicitudes de asistentes que cumplen los requisitos llevan `x-concierge-route: bot` y obtienen sus propias entradas.
* Las respuestas de Profound establecen `cache-control: no-store`, por lo que, con Minimum TTL en `0`, las entradas con clave de asistente solo se llenan con respuestas de conmutación por error de tu propio origen: contenido correcto, que vence según el TTL de tu propio origen.

<Accordion title="Limitación conocida: las respuestas de conmutación por error pueden persistir después de la recuperación">
  Durante una interrupción total de Profound, las respuestas del origen tras la conmutación por error pueden permanecer en la caché con clave de asistente hasta que venza su TTL, lo que retrasa el regreso al contenido renderizado después de la recuperación.

  Valida que este retraso en la recuperación sea aceptable para tus TTL existentes. Cambiar cómo se almacenan en caché las respuestas de respaldo requiere una revisión de diseño independiente; esta guía no agrega una función de borde para cambiar ese comportamiento.
</Accordion>

## Revertir los cambios

Restaura la asociación de viewer request registrada y cualquier política modificada para esta configuración. Usa **No association** solo si no había una función anterior. Deja que la configuración se propague y luego verifica el enrutamiento y el comportamiento de caché originales. Las respuestas de respaldo almacenadas previamente en caché pueden permanecer hasta que venza su TTL o se invaliden mediante tu proceso habitual.
