Introducción
En el curso de Workers AI, una aplicación enviaba un prompt directamente a un modelo alojado en Cloudflare. Esto funciona, pero una aplicación que crece también necesita un lugar único y coherente para observar y controlar el tráfico de los modelos. Cloudflare AI Gateway es ese punto de control: el llamador envía una solicitud a una puerta de enlace con nombre y la puerta de enlace reenvía la solicitud a un proveedor de modelos ascendente, como Workers AI.
En este laboratorio se mantienen visibles los tres roles:
- el llamador es
curlen su máquina virtual de LabEx; - la puerta de enlace comprueba si el llamador puede acceder y registra la solicitud;
- el proveedor ascendente es Workers AI, que comprueba si la solicitud puede ejecutar el modelo.
Las dos últimas comprobaciones utilizan credenciales independientes. cf-aig-authorization autentica al llamador en AI Gateway. El encabezado Authorization habitual autentica la solicitud de la puerta de enlace en Workers AI. Un token de puerta de enlace válido no es automáticamente una credencial de Workers AI, y una credencial de Workers AI no permite omitir una puerta de enlace autenticada.
Creará una puerta de enlace autenticada desechable en el Cloudflare Dashboard, creará un token de AI Gateway con permisos limitados, enviará una solicitud breve al modelo Llama 3.3 alojado en Cloudflare y examinará el registro resultante. Después sustituirá únicamente la credencial de la puerta de enlace por un valor no válido para demostrar qué límite rechaza la solicitud. Por último, eliminará la puerta de enlace, eliminará su token para que ya no pueda autorizar solicitudes y cerrará la sesión de Wrangler.
Si accedió directamente a este curso, complete primero Conectar LabEx a su cuenta de Cloudflare. Allí aprenderá a utilizar el terminal de la máquina virtual de LabEx, autorizar dispositivos con Wrangler, confirmar la cuenta y trabajar con identificadores de cuenta explícitos. El laboratorio de inferencia de Workers AI también es un requisito previo útil.
AI Gateway está disponible en el plan Free y sus registros principales son gratuitos dentro de los límites de la cuenta. El modelo seleccionado @cf/meta/llama-3.3-70b-instruct-fp8-fast puede utilizar la asignación gratuita compartida de Workers AI con facturación Standard. No se requieren Workers Paid ni Unified Billing. Deténgase en lugar de reintentar repetidamente si la asignación diaria de Workers AI de la cuenta no está disponible.
La configuración instala Node.js 22.22.0 y Wrangler 4.132.0 local al proyecto en /home/labex/project/ai-gateway-route. Proporciona evaluaciones independientes de solo lectura, pero no autoriza Wrangler, crea un token o una puerta de enlace, envía inferencias ni modifica su cuenta de Cloudflare. LabEx no guarda esta máquina virtual temporal cuando termina el laboratorio. Aun así, deberá eliminar explícitamente el token en la nube y borrar su copia en la máquina virtual para completar la limpieza antes de que se destruya la máquina virtual.
Autorizar la máquina virtual y registrar los nombres utilizados
En este paso, conectará la máquina virtual nueva a su cuenta de aprendizaje y guardará nombres que permitan identificar sin ambigüedades los recursos de este laboratorio.
El inicio de sesión de dispositivo de Wrangler autoriza Workers AI, pero no crea la credencial independiente de llamador de AI Gateway que utilizará más adelante. Mantener separadas estas credenciales facilita ver el límite de confianza.
Entre en el proyecto preparado y confirme la versión fijada de la CLI:
cd /home/labex/project/ai-gateway-route
npx wrangler --version
Debe aparecer 4.132.0. Inicie la autorización del dispositivo con la identidad de la cuenta y acceso a Workers AI:
npx wrangler login --device --browser=false --scopes account:read user:read ai:write
Abra el enlace mostrado, introduzca el código y autorice la cuenta de aprendizaje prevista. Después, consulte la identidad estructurada:
npx wrangler whoami --json
Confirme que aparece loggedIn: true. Cree un ID único para la puerta de enlace y el nombre de su token asociado. Sustituya YOUR_ACCOUNT_ID por el ID real de 32 caracteres que se muestra para la cuenta prevista:
GATEWAY_ID="labex-c09-g01-$(openssl rand -hex 6)"
TOKEN_NAME="$GATEWAY_ID-token"
cat > .labex/state.json <<JSON
{
"accountId": "YOUR_ACCOUNT_ID",
"gatewayId": "$GATEWAY_ID",
"tokenName": "$TOKEN_NAME"
}
JSON
cat .labex/state.json
El sufijo aleatorio evita colisiones. El archivo de estado contiene identificadores de recursos, no credenciales, y permite que todos los comandos posteriores se dirijan exactamente al recurso que pertenece a este laboratorio.
Crear una puerta de enlace autenticada y un token de llamador
En este paso, creará el punto de control y una credencial que permite tanto llamarlo como inspeccionarlo.
Abra el Cloudflare Dashboard y seleccione AI → AI Gateway → Create gateway → Custom gateway. Utilice como nombre de la puerta de enlace el gatewayId de .labex/state.json. Mantenga estos ajustes:
- registro de solicitudes: activado;
- autenticación de la puerta de enlace: activada;
- caché, límites de velocidad, límites de gasto y reintentos: desactivados;
- facturación de Workers AI: Standard.
La facturación Standard mantiene el uso de Workers AI dentro de su asignación normal. Unified Billing es una vía de pago diferente y queda fuera de este laboratorio para principiantes.
Cuando Cloudflare abra el recurso nuevo, utilice la ruta de navegación y la pestaña Overview seleccionada para confirmar que se encuentra dentro de la puerta de enlace desechable exacta, no en la lista de puertas de enlace de toda la cuenta.

Después de crearla, abra Settings. Confirme que el ID mostrado coincide exactamente con el ID guardado y que el registro y la autenticación están activados.
Ahora seleccione Create an AI Gateway authentication token. Asígnele el tokenName guardado, seleccione únicamente la cuenta de aprendizaje prevista y añada estos permisos:
- AI Gateway — Run permite al llamador acceder a una puerta de enlace autenticada;
- AI Gateway — Edit permite que el laboratorio lea y elimine recursos de AI Gateway mediante la API de administración.
No añada permisos de Workers AI a este token. Workers AI seguirá autorizado mediante la credencial independiente y de corta duración de Wrangler.

Cree el token solo después de revisar la cuenta y los permisos. Cloudflare muestra su valor una sola vez. Guárdelo de forma privada sin mostrarlo en pantalla:
bash -c '
while :; do
read -rsp "Paste the AI Gateway token: " GATEWAY_TOKEN
printf "\n"
[ -n "$GATEWAY_TOKEN" ] && break
printf "Token cannot be empty; paste it again.\n" >&2
done
umask 077
printf "%s" "$GATEWAY_TOKEN" > .labex/gateway-token
unset GATEWAY_TOKEN
chmod 600 .labex/gateway-token
'
El terminal preparado utiliza zsh de forma interactiva, por lo que este bloque inicia un breve subproceso de Bash para utilizar el prompt oculto de read de Bash. Si pega un valor vacío, el comando lo rechaza antes de volver al intérprete de comandos. El token permanece únicamente en el subproceso y en el archivo privado.
El token se mantiene deliberadamente fuera de la configuración y de la salida de los comandos. Verifique la puerta de enlace real mediante la API de administración autenticada:
ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
-H "Authorization: Bearer $GATEWAY_TOKEN" \
"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID" \
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const b=JSON.parse(s),g=b.result||{};console.log(JSON.stringify({success:b.success,id:g.id,collect_logs:g.collect_logs,authentication:g.authentication},null,2))})'
unset GATEWAY_TOKEN
Debe aparecer el ID utilizado, con collect_logs y authentication establecidos en true. No se muestra ningún secreto.

Enrutar una solicitud de Workers AI a través de la puerta de enlace
En este paso, enviará una solicitud pequeña a través de la puerta de enlace en lugar de enviarla directamente a Workers AI.
La URL de la puerta de enlace nativa del proveedor contiene la cuenta, la puerta de enlace, el proveedor y el modelo. Los dos encabezados de autorización permanecen separados deliberadamente:
caller → cf-aig-authorization → AI Gateway → Authorization → Workers AI model
Obtenga el token actual y de corta duración de Workers AI de Wrangler como datos estructurados y, después, realice la solicitud. El comando escribe únicamente la respuesta JSON en el disco; no muestra ninguna de las dos credenciales:
ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
MODEL='@cf/meta/llama-3.3-70b-instruct-fp8-fast'
GATEWAY_TOKEN=$(cat .labex/gateway-token)
UPSTREAM_TOKEN=$(npx wrangler auth token --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).token))')
curl --http1.1 -fsS \
-H "cf-aig-authorization: Bearer $GATEWAY_TOKEN" \
-H "Authorization: Bearer $UPSTREAM_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"prompt":"In one sentence, explain why an AI gateway is useful.","max_tokens":64}' \
"https://gateway.ai.cloudflare.com/v1/$ACCOUNT_ID/$GATEWAY_ID/workers-ai/$MODEL" \
> .labex/valid-response.json
unset GATEWAY_TOKEN UPSTREAM_TOKEN
node -e 'const b=require("./.labex/valid-response.json"); console.log(b.result?.response ?? b.result)'
El texto puede variar porque la generación no es determinista. La evaluación solo comprueba que el proveedor devolvió un resultado correcto y no vacío a través de la puerta de enlace utilizada.
Aislar el límite de autenticación de la puerta de enlace
En este paso, conservará la credencial válida de Workers AI, pero sustituirá únicamente la credencial de la puerta de enlace.
Una prueba negativa controlada debe cambiar una sola condición cada vez. Si ambas credenciales fueran no válidas, un error HTTP no indicaría qué sistema rechazó la solicitud. Esta solicitud conserva el token ascendente válido de Wrangler y envía un valor cf-aig-authorization claramente no válido:
ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
MODEL='@cf/meta/llama-3.3-70b-instruct-fp8-fast'
UPSTREAM_TOKEN=$(npx wrangler auth token --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).token))')
STATUS=$(curl --http1.1 -sS -o .labex/invalid-response.json -w '%{http_code}' \
-H 'cf-aig-authorization: Bearer deliberately-invalid' \
-H "Authorization: Bearer $UPSTREAM_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"prompt":"This request must not reach the model.","max_tokens":8}' \
"https://gateway.ai.cloudflare.com/v1/$ACCOUNT_ID/$GATEWAY_ID/workers-ai/$MODEL")
unset UPSTREAM_TOKEN
printf '%s\n' "$STATUS" | tee .labex/invalid-status.txt
Debe aparecer 401 o 403. No muestre el cuerpo de la respuesta: el estado es evidencia suficiente y mantener limitada la salida de error reduce la posibilidad de exponer detalles de la solicitud.
Relacionar la solicitud con su registro de la puerta de enlace
En este paso, utilizará la observabilidad para relacionar el comportamiento en tiempo de ejecución con un registro visible de la puerta de enlace.
La observabilidad consiste en recopilar suficientes evidencias para explicar qué hizo un sistema después de que una solicitud saliera del llamador. Un registro de la puerta de enlace puede mostrar el proveedor, el modelo, el estado, la latencia y el uso de tokens sin volver a solicitar nada al modelo. Los registros pueden tardar un poco en aparecer.
Lea los registros existentes mediante la API de administración autenticada. Esta es una comprobación de solo lectura; no envía otra solicitud al modelo:
ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
-H "Authorization: Bearer $GATEWAY_TOKEN" \
"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID/logs?per_page=50" \
> .labex/logs.json
unset GATEWAY_TOKEN
node - <<'NODE'
const body = require('./.labex/logs.json')
const model = '@cf/meta/llama-3.3-70b-instruct-fp8-fast'
const matches = (body.result || []).filter(row =>
row.provider === 'workers-ai' && row.model === model
)
console.log(matches.map(row => ({
id: row.id,
provider: row.provider,
model: row.model,
success: row.success,
created_at: row.created_at
})))
if (!matches.some(row => row.success === true)) process.exit(2)
NODE
Debe aparecer una entrada con provider: "workers-ai", el modelo previsto y success: true. Si el comando termina sin esa entrada, espere unos 20 segundos y vuelva a ejecutar este mismo bloque de solo lectura en lugar de enviar más solicitudes de inferencia.
Abra la vista Logs de la puerta de enlace en el Dashboard. Busque la fila correcta de Workers AI correspondiente a @cf/meta/llama-3.3-70b-instruct-fp8-fast. Confirme el estado correcto, el proveedor y el modelo antes de abrir su panel de detalles.

La duración exacta, el número de tokens y el texto generado pueden variar. Esos valores describen esta solicitud; no son objetivos que deba reproducir exactamente. No introduzca nunca credenciales ni información personal en un prompt solo para que un registro sea más fácil de encontrar.

Eliminar la puerta de enlace desechable
En este paso, eliminará el recurso en la nube mientras la credencial de administración todavía está disponible.
La limpieza debe dirigirse al ID exacto utilizado y debe demostrarse mediante un inventario autenticado. Que una página no esté disponible debido al cierre de sesión o a un fallo de red no demuestra que se haya eliminado.
ACCOUNT_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).accountId')
GATEWAY_ID=$(node -p 'JSON.parse(require("fs").readFileSync(".labex/state.json")).gatewayId')
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS -X DELETE \
-H "Authorization: Bearer $GATEWAY_TOKEN" \
"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways/$GATEWAY_ID" \
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const b=JSON.parse(s);if(!b.success)process.exit(1);console.log("gateway deletion accepted")})'
unset GATEWAY_TOKEN
GATEWAY_TOKEN=$(cat .labex/gateway-token)
curl --http1.1 -fsS \
-H "Authorization: Bearer $GATEWAY_TOKEN" \
"https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/ai-gateway/gateways" \
> .labex/gateways-after-delete.json
unset GATEWAY_TOKEN
node -e 'const b=require("./.labex/gateways-after-delete.json"),id=process.argv[1],found=(b.result||[]).some(g=>g.id===id);console.log("gateway absent:",!found);if(found)process.exit(1)' "$GATEWAY_ID"
Debe aparecer gateway absent: true. Esta segunda solicitud enumera las puertas de enlace con una autorización válida y falla si el ID utilizado todavía existe. Las demás puertas de enlace de su cuenta nunca se modifican.
Eliminar el token y cerrar la sesión
En este paso, eliminará las dos credenciales independientes en el orden inverso al que las utilizó.
En el Cloudflare Dashboard, abra My Profile → API Tokens. Busque el nombre exacto del token guardado en .labex/state.json, abra su menú Actions, seleccione Delete, revise la confirmación y elimine únicamente ese token. Al eliminarlo, su acceso se revoca inmediatamente. Ahora es seguro eliminarlo porque la puerta de enlace ya no existe.
Elimine su copia local y, después, finalice la autorización independiente de Wrangler en la máquina virtual:
shred -u .labex/gateway-token
npx wrangler logout
npx wrangler whoami --json || true
Debe aparecer una salida estructurada con loggedIn: false. La sesión del navegador del Dashboard es independiente y permanece iniciada. Ejecute la comprobación local final:
test ! -e .labex/gateway-token && echo "local gateway token removed"
El mensaje confirma que la copia en la máquina virtual ya no existe. El botón Check de LabEx repite de forma independiente las comprobaciones del archivo local y del cierre de sesión de Wrangler; su script de backend no forma parte intencionadamente del proyecto del estudiante.
Ahora ha eliminado la puerta de enlace, ha borrado su token de llamador y administración, ha eliminado la copia local del token y ha desconectado la máquina virtual nueva. Cuando termine el laboratorio, LabEx destruirá esta máquina virtual temporal en lugar de guardarla; aun así, la limpieza en la nube sigue siendo importante, porque destruir una máquina virtual por sí solo no puede revocar un token de Cloudflare ni eliminar una puerta de enlace.
Resumen
Creó un Cloudflare AI Gateway autenticado y enrutó una inferencia real de Workers AI a través de él. Mantuvo separada la autorización de la puerta de enlace de la autorización del modelo ascendente, cambió una sola credencial para identificar el límite que rechazaba la solicitud y relacionó la solicitud correcta con su registro de la puerta de enlace. Por último, demostró la eliminación autenticada del recurso antes de eliminar el token y cerrar la sesión de la máquina virtual.
El siguiente laboratorio se basa en esta ruta de solicitudes observable. Añadirá pequeños metadatos que no contienen secretos, rastreará un error deliberado y utilizará evidencias de la puerta de enlace en lugar de adivinar dónde falló una solicitud.



