Communitygithub.com

aca-web-publish

Despliega contenido estático privado en Azure sin exponer Blob Storage públicamente, utilizando Azure Container Apps y autenticación a nivel de aplicación.

¿Qué es aca-web-publish?

Esta habilidad permite desplegar sitios web estáticos privados en Azure de forma segura, sin exponer directamente el almacenamiento Blob al público. El contenido se sube a un Azure Blob Storage privado en nivel Cold, y un pequeño contenedor Docker en Azure Container Apps (ACA) actúa como proxy, manejando la autenticación a nivel de aplicación (OAuth con GitHub, Google o Entra ID) y transmitiendo el contenido del Blob a los usuarios autenticados. ACA utiliza una identidad administrada asignada por el sistema con el rol 'Storage Blob Data Reader' para acceder al almacenamiento, por lo que los usuarios del navegador nunca reciben claves de blob, URL SAS ni claves de cuenta. La habilidad soporta despliegue con nombres de dominio personalizados (con certificados) o el hostname por defecto de ACA, y permite elegir entre un registro de contenedores público (GHCR) o privado (ACR). Incluye un checklist detallado de implementación, tareas de operación día 2 (agregar usuarios, rotar secretos, subir contenido) y scripts de despliegue listos para usar.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add tkubica12/skill-aca-web-publish

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

ACA Web Publish

Usa esta habilidad para desplegar contenido estático privado en Azure sin exponer Blob Storage públicamente. El patrón por defecto es:

  1. El contenido estático se sube a Azure Blob Storage privado y se establece en nivel Cold.
  2. Una imagen Docker pequeña se ejecuta en Azure Container Apps (ACA).
  3. El contenedor implementa autenticación a nivel de aplicación y transmite el contenido del Blob a través de ACA.
  4. ACA utiliza una identidad administrada asignada por el sistema con el rol Storage Blob Data Reader.
  5. Los usuarios del navegador nunca reciben claves de blob, URL SAS, URL directas de blob ni claves de cuenta de almacenamiento.
  6. No se utiliza ACA Easy Auth.

Modelo de interacción obligatorio

A menos que el usuario ya haya proporcionado todas las opciones explícitamente, usa la herramienta ask_user antes de implementar. Recopila:

DecisiónValor predeterminado recomendado
Proveedor de autenticaciónGitHub
Usuarios permitidosSin valor predeterminado; si está vacío, nadie puede iniciar sesión
Modo de registroImagen pública GHCR si el repositorio puede alojar un paquete público; ACR si la solución debe ser privada/autocontenida
DNS personalizadoPreferir DNS personalizado si el usuario tiene una zona DNS de Azure
Directorio de contenidoPreguntar por la ruta local
Nombres de recursos de AzureGenerar valores predeterminados seguros, pero preguntar antes de cambiar infraestructura existente

Antes de solicitar cualquier ID de cliente OAuth o secreto, primero determina si el hostname público final ya es conocido:

  • Con DNS personalizado, pregunta primero por el hostname y la zona DNS. Luego proporciona al usuario el enlace al portal del proveedor y las URL de redirección exactas para ese hostname personalizado antes de recopilar los ID de cliente/secretos.
  • Con el hostname integrado de ACA, no preguntes todavía por los ID de cliente/secretos OAuth porque el hostname no se conoce hasta que ACA exista. Primero crea un endpoint ACA de arranque, captura su URL https://<app>.<region>.azurecontainerapps.io, luego proporciona al usuario el enlace al portal del proveedor y las URL de redirección exactas y recopila los ID de cliente/secretos.

Nunca pidas al usuario que cree una aplicación OAuth desde URL de marcador de posición. Recopila los ID de cliente/secretos con ask_user; nunca muestres secretos en la respuesta final y nunca los confirmes.

Valores predeterminados clave

  • El proveedor de autenticación predeterminado es github.
  • Proveedores de autenticación admitidos: github, google, entra, none.
  • none es solo para despliegues explícitamente públicos o de prueba interna.
  • Si la autenticación está habilitada y no hay usuarios permitidos configurados, denegar el acceso a todos.
  • Usar usuarios permitidos separados por comas:
    • GitHub: handles como tkubica12,octocat.
    • Google: direcciones de correo electrónico.
    • Entra: ID de objeto o UPN/direcciones de correo electrónico, según la implementación.
  • Se pueden usar listas de correo electrónico opcionales para GitHub como defensa en profundidad, pero los handles son la identidad principal de GitHub.
  • La cuenta de almacenamiento debe mantener publicNetworkAccess=Enabled a menos que ACA tenga una ruta de VNet/punto final privado hacia Blob. Mantener allowBlobPublicAccess=false y allowSharedKeyAccess=false.
  • ACA debe ser pequeño: comenzar con 0.25 CPU y 0.5Gi de memoria.
  • ACA debe escalar a cero con un comportamiento de inactividad/enfriamiento de 60 minutos cuando la superficie CLI de ACA/KEDA activa lo admita; de lo contrario, usar mínimo de réplicas 0 y documentar la limitación.

Opciones de registro

Modo GHCR

Usar GHCR cuando la imagen contiene solo código de proxy/autenticación y ningún contenido. La imagen/paquete debe ser pública para que ACA pueda obtenerla sin credenciales. Crear un flujo de trabajo de GitHub Actions desde assets/publish-web-image.yml para construir y enviar la imagen.

Modo ACR

Usar ACR cuando el usuario desea una solución Azure completamente privada y autocontenida. Crear un ACR, construir o enviar la imagen allí, y otorgar a la identidad administrada de ACA el rol AcrPull.

Para ACR, evitar crear ACA directamente desde la imagen privada antes de que AcrPull esté configurado. Crear primero la aplicación con una imagen de arranque pública y una identidad asignada por el sistema, otorgar a esa identidad AcrPull, configurar el registro con --identity system, luego actualizar la aplicación a la imagen de ACR.

Al construir con az acr build desde terminales Windows, usar --no-logs para evitar fallos de codificación Unicode/consola de transmisión de registros de Azure CLI; consultar el resultado de la construcción en su lugar.

Sincronización del hostname OAuth

El registro de la aplicación OAuth debe usar el host final visible en el navegador en la URL de inicio/página principal y de devolución de llamada.

Flujo con DNS personalizado

  1. Preguntar por el hostname personalizado y la zona DNS.
  2. Mostrar el enlace de registro del proveedor y las URL exactas, por ejemplo https://site.example.com y https://site.example.com/oauth/github/callback.
  3. Recopilar el ID de cliente y el secreto.
  4. Desplegar ACA, DNS, configuración de autenticación, contenido y enlace de certificado.

Flujo con hostname integrado de ACA

  1. Desplegar primero un endpoint ACA de arranque para descubrir el hostname integrado. Usar el script de despliegue con -BootstrapOnly o crear el shell de ACA/aplicación contenedora manualmente.
  2. Mostrar el enlace de registro del proveedor y las URL exactas usando el hostname descubierto, por ejemplo https://<fqdn> y https://<fqdn>/oauth/github/callback.
  3. Recopilar el ID de cliente y el secreto.
  4. Completar el despliegue aplicando la configuración de autenticación, subiendo el contenido y cambiando a la imagen proxy si la aplicación fue arrancada.

Archivos necesarios para copiar o adaptar

Usar estos activos como puntos de partida para la implementación:

  • assets/blob_proxy_app.py: Aplicación FastAPI con proxy Blob y cambio de proveedor.
  • assets/requirements.txt: Dependencias de ejecución de Python.
  • assets/Dockerfile: Imagen mínima para ACA.
  • assets/deploy-aca-web.ps1: Script de despliegue de Azure opinado.
  • assets/publish-web-image.yml: Flujo de trabajo de GitHub Actions para publicación GHCR.

Leer estas referencias cuando sea necesario:

  • references/architecture.md: Arquitectura, reglas de almacenamiento y notas de escalado.
  • references/auth.md: Pasos de registro OAuth y variables de entorno.
  • references/day-2.md: Agregar usuarios, rotar secretos, subir contenido y solución de problemas.

Lista de verificación de implementación

  1. Confirmar el directorio de contenido y el punto de entrada del sitio generado.
  2. Elegir DNS personalizado o hostname integrado de ACA.
  3. Elegir el proveedor de autenticación.
  4. Si el hostname es conocido, proporcionar al usuario los enlaces de registro de la aplicación específicos del proveedor y las URL de devolución de llamada exactas; si se usa el hostname integrado de ACA, arrancar ACA primero y luego proporcionar esas URL.
  5. Recopilar los valores de registro de la aplicación.
  6. Recopilar los usuarios permitidos.
  7. Elegir GHCR o ACR.
  8. Copiar/adaptar la aplicación de muestra y el Dockerfile en el repositorio de destino.
  9. Si es modo GHCR, agregar el flujo de trabajo y hacer que el paquete resultante sea público.
  10. Desplegar ACA, Blob Storage privado, RBAC, secretos, variables de entorno y DNS opcional.
  11. Subir contenido a Blob y establecer nivel Cold.
  12. Prueba de humo:
    • la solicitud no autenticada redirige al proveedor, a menos que AUTH_PROVIDER=none;
    • el usuario permitido puede cargar index.html;
    • el usuario no permitido recibe un 403;
    • las solicitudes de rango multimedia devuelven 206 Partial Content;
    • el acceso anónimo directo a Blob falla.

Manejo de tareas del día 2

Para "agregar usuario", actualizar solo ALLOWED_USERS o las variables de entorno de listas de permitidos específicas del proveedor y reiniciar/revisar ACA.

Para "subir nuevo contenido", regenerar la salida estática local, ejecutar la sincronización de Blob con eliminación habilitada solo si la salida local es autoritativa, luego establecer nivel Cold.

Preferir AzCopy para sitios grandes o muchos archivos. Si AzCopy no está disponible y el sitio es pequeño, az storage blob upload-batch --auth-mode login de Azure CLI es una alternativa aceptable; para sitios grandes, instalar AzCopy primero o usar el script de despliegue con -InstallAzCopy.

Para "cambiar proveedor de autenticación", crear primero el registro del nuevo proveedor, establecer secretos/variables de entorno, verificar el inicio de sesión, luego eliminar los secretos del proveedor obsoleto.

Para "mover de GHCR a ACR", desplegar ACR, otorgar AcrPull, actualizar la referencia de la imagen y mantener el contenido de Blob sin cambios.

Skills relacionados