Desplegar CoPyRIT en Azure Container Apps

Objetivo

Tenemos la imagen de CoPyRIT en Azure Container Registry. En este post la desplegamos en Azure Container Apps, configuramos la managed identity para el pull de imágenes, pasamos las credenciales de Azure OpenAI al contenedor, y verificamos que CoPyRIT arranca y es accesible desde el navegador.

Sobre la autenticación: Entra ID vs lab simplificado

El template Bicep oficial de PyRIT (infra/main.bicep) implementa autenticación completa con Entra ID usando MSAL y PKCE el frontend autentica usuarios contra Azure AD, el backend valida JWTs. Es la arquitectura correcta para un despliegue en equipo o en producción.

Para este lab con Azure for Students hay un problema práctico que nos hemos encontrado , el crear app registrations en Entra ID requiere permisos de administrador del tenant que las suscripciones de estudiante no tienen. El intento de az ad app create devuelve Insufficient privileges to complete the operation.

La solución para el lab es desplegar sin autenticación Entra CoPyRIT arranca con el middleware de auth deshabilitado y la URL actúa como único control de acceso. Los logs lo confirman explícitamente:

Entra ID auth middleware DISABLED — ENTRA_TENANT_ID or ENTRA_CLIENT_ID not set.
All requests will be allowed without authentication.

Arquitectura


Paso 1: Crear el Log Analytics Workspace

Azure Container Apps requiere un Log Analytics Workspace para el envío de logs del contenedor. Sin él no se puede crear el Container Apps Environment.

bash

az monitor log-analytics workspace create \
  --resource-group rg-lab-pyrit \
  --workspace-name law-copyrit-lab \
  --location swedencentral \
  --output table

Output :

Name             ProvisioningState    Location       RetentionInDays
---------------  -------------------  -------------  -----------------
law-copyrit-lab  Succeeded            swedencentral  30

Por qué Log Analytics: Container Apps no expone logs directamente los envía a un workspace de Log Analytics desde donde puedes consultarlos con KQL. Para el lab es especialmente útil porque nos permite ver el arranque del contenedor, errores de configuración, y más adelante los logs de los ataques PyRIT.


Paso 2: Crear el Container Apps Environment

El environment es el entorno de ejecución compartido para uno o más Container Apps. Gestiona la red, el escalado y la integración con Log Analytics.

bash

# Obtener Customer ID y key del workspace (con limpieza de espacios)
LAW_ID=$(az monitor log-analytics workspace show \
  --resource-group rg-lab-pyrit \
  --workspace-name law-copyrit-lab \
  --query customerId --output tsv | tr -d '[:space:]')

LAW_KEY=$(az monitor log-analytics workspace get-shared-keys \
  --resource-group rg-lab-pyrit \
  --workspace-name law-copyrit-lab \
  --query primarySharedKey --output tsv | tr -d '\n\r')

# Crear el environment
az containerapp env create \
  --name cae-copyrit-lab \
  --resource-group rg-lab-pyrit \
  --location swedencentral \
  --logs-workspace-id $LAW_ID \
  --logs-workspace-key $LAW_KEY \
  --output table

Output :

Location        Name             ResourceGroup
--------------  ---------------  ---------------
Sweden Central  cae-copyrit-lab  rg-lab-pyrit

Paso 3: Crear la User-Assigned Managed Identity

La managed identity es la identidad que usará el Container App para autenticarse contra otros servicios Azure — en este caso, para hacer pull de la imagen desde ACR sin necesidad de credenciales estáticas.

bash

az identity create \
  --name id-copyrit-lab \
  --resource-group rg-lab-pyrit \
  --output table

Paso 4: Asignar el rol AcrPull a la identity

bash

# Obtener los IDs necesarios
IDENTITY_PRINCIPAL_ID=$(az identity show \
  --name id-copyrit-lab \
  --resource-group rg-lab-pyrit \
  --query principalId --output tsv | tr -d '[:space:]')

ACR_ID=$(az acr show \
  --name acrcyberlabpyrit \
  --resource-group rg-lab-pyrit \
  --query id --output tsv | tr -d '[:space:]')

# Asignar el rol
az role assignment create \
  --assignee-object-id $IDENTITY_PRINCIPAL_ID \
  --assignee-principal-type ServicePrincipal \
  --role AcrPull \
  --scope $ACR_ID

Paso 5: Desplegar el Container App

Este es el paso central. Creamos el Container App pasando las credenciales de Azure OpenAI via la variable de entorno PYRIT_ENV_CONTENTS, que el start.sh del contenedor escribe en ~/.pyrit/.env al arrancar.

bash

# Recargar todas las variables necesarias
IDENTITY_ID=$(az identity show \
  --name id-copyrit-lab \
  --resource-group rg-lab-pyrit \
  --query id --output tsv | tr -d '[:space:]')

IDENTITY_CLIENT_ID=$(az identity show \
  --name id-copyrit-lab \
  --resource-group rg-lab-pyrit \
  --query clientId --output tsv | tr -d '[:space:]')

AOAI_KEY=$(az cognitiveservices account keys list \
  --name openai-cyberlab-cibersecblog \
  --resource-group rg-lab-pyrit \
  --query key1 --output tsv | tr -d '[:space:]')

# Contenido del .env que leerá PyRIT dentro del contenedor
PYRIT_ENV=$(cat <<EOF
AZURE_OPENAI_CHAT_ENDPOINT=https://openai-cyberlab-cibersecblog.openai.azure.com/
AZURE_OPENAI_CHAT_KEY=$AOAI_KEY
AZURE_OPENAI_CHAT_DEPLOYMENT=gpt-4o-atacante
EOF
)

# Desplegar
az containerapp create \
  --name copyrit-lab \
  --resource-group rg-lab-pyrit \
  --environment cae-copyrit-lab \
  --image acrcyberlabpyrit.azurecr.io/copyrit:latest \
  --registry-server acrcyberlabpyrit.azurecr.io \
  --registry-identity $IDENTITY_ID \
  --user-assigned $IDENTITY_ID \
  --target-port 8000 \
  --ingress external \
  --cpu 1.0 \
  --memory 2.0Gi \
  --min-replicas 1 \
  --max-replicas 1 \
  --env-vars \
      PYRIT_MODE=gui \
      AZURE_CLIENT_ID=$IDENTITY_CLIENT_ID \
      "PYRIT_ENV_CONTENTS=$PYRIT_ENV" \
  --output table

Output esperado:

Name         Location        ResourceGroup    Fqdn
-----------  --------------  ---------------  ------------------------------------------------------------
copyrit-lab  Sweden Central  rg-lab-pyrit     copyrit-lab.wittyground-b288107c.swedencentral.azurecontainerapps.io

Cómo llegan las credenciales al contenedor: El parámetro PYRIT_ENV_CONTENTS contiene el contenido completo del fichero .env de PyRIT como string. El start.sh del contenedor detecta esta variable y la escribe en /home/vscode/.pyrit/.env antes de arrancar el backend. PyRIT lee ese fichero al inicializarse y configura los endpoints de Azure OpenAI. Es el mecanismo que usa el Microsoft AI Red Team internamente documentado en los comentarios del propio start.sh.


Paso 6: Verificar el arranque en los logs

Antes de abrir el navegador, verificamos que el contenedor arrancó correctamente:

bash

az containerapp logs show \
  --name copyrit-lab \
  --resource-group rg-lab-pyrit \
  --tail 30

Los logs que confirman el arranque correcto:

PYRIT_MODE: gui
Python version: Python 3.11.2
Running PyRIT version: 0.15.0.dev0
Wrote .env file from PYRIT_ENV_CONTENTS (3 lines)
Starting PyRIT GUI on port 8000...
Using SQLite database (AZURE_SQL_SERVER not set)
Loaded environment file: /home/vscode/.pyrit/.env
✅ Serving frontend from /app/pyrit/backend/frontend

Dos líneas importantes a entender:

Wrote .env file from PYRIT_ENV_CONTENTS (3 lines) : confirma que las credenciales de Azure OpenAI llegaron al contenedor y se escribieron correctamente en el fichero que PyRIT espera.

Using SQLite database (AZURE_SQL_SERVER not set): PyRIT usará SQLite local para persistir el historial de ataques. Esto significa que si el contenedor se reinicia, el historial se pierde. Para un lab es aceptable; en producción se usaría Azure SQL con managed identity.


Paso 7: Acceder a CoPyRIT

En el despliegue nos darán la url , entramos y veremos lo siguiente

La interfaz muestra tres elementos:

Labels: operator y operation. Son metadatos que PyRIT adjunta a cada ataque para poder filtrarlo y encontrarlo después en el historial. El operator identifica al red teamer; la operation agrupa ataques relacionados bajo una misma campaña.

Target: el sistema que vamos a atacar. Está pendiente de configurar — lo haremos en el Post 5 apuntando a gpt-4o-atacante.

Recent operations:vacío por ahora. Aquí aparecerán todos los ataques que lancemos con su estado y resultados.


Limitaciones

Nos hemos encontrado con que la herramienta en la actualidad solo perrmite realizar ataques manuales mediante interfaz gráfica, las automatizaciones, scoring y reporte solo se puede gestionar a través de terminal con python.


Resumen del estado actual del lab

Colcusiones

Es una herramienta interesante sobretodo a futuro , ya que en la actualidad está muy limitada en cuánto a su interfaz gráfica , si lo que quieres es usarla a nivel terminal o implementarla con otras herramientas , si que es potente y cumple con lo que promete , sin embargo como aplicación con interfaz gráfica ,está muy verde todavía

Con esto terminamos la parte de Co-PyRit , seguiremos probando más herramientas.

Documentación consultada

Entradas relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *