Herramienta CLI para auditar la postura de seguridad de Azure, RBAC, NSGs, almacenamiento, identidad y cifrado
| ID | Categoría | Comprobación | Gravedad |
|---|
| AZ-001 | RBAC | Propietario / Colaborador asignado en el ámbito de la suscripción | CRITICAL |
| AZ-002 | RBAC | Propietario / Colaborador asignado en el ámbito del grupo de recursos | HIGH |
| AZ-003 | Red | NSG con regla de entrada permitida 0.0.0.0/0 | HIGH |
| AZ-004 | Almacenamiento | Cuenta de almacenamiento con acceso público a blobs habilitado | HIGH |
| AZ-005 | Identidad | Usuario de Entra ID sin MFA registrado | HIGH |
| AZ-006 | Identidad | Entidad de servicio con permisos de Propietario / Colaborador | HIGH |
| AZ-007 | Cifrado | Disco administrado sin configuración de cifrado explícita | MEDIUM |
| AZ-008 | Cifrado | Key Vault expuesto a la red pública sin restricciones de firewall | HIGH |
| AZ-009 | Supervisión | Retención del registro de actividad inferior a 90 días | MEDIUM |
| AZ-010 | Supervisión | Microsoft Defender for Cloud no habilitado en tipos de recursos clave | HIGH |
| AZ-011 | Supervisión | Key Vault sin registro de diagnóstico habilitado | MEDIUM |
| AZ-012 | Proceso | Máquina virtual con IP pública asociada directamente | MEDIUM |
| AZ-013 | Proceso | Máquina virtual sin extensión de protección de endpoints | MEDIUM |
| AZ-014 | Proceso | Disco del sistema operativo de máquina virtual sin Azure Disk Encryption (ADE) | MEDIUM |
| AZ-015 | Red | Puerto RDP 3389 expuesto a internet a través de NSG | CRITICAL |
| AZ-016 | Red | Puerto SSH 22 expuesto a internet a través de NSG | CRITICAL |
| AZ-017 | Almacenamiento | Cuenta de almacenamiento que permite tráfico no HTTPS | HIGH |
| AZ-018 | Almacenamiento | Cuenta de almacenamiento que permite versiones TLS heredadas (inferiores a 1.2) | MEDIUM |
| AZ-019 | Identidad | Cuentas de usuario invitado presentes en el inquilino de Entra ID | LOW |
| AZ-020 | Cifrado | Key Vault sin eliminación suave o protección de purga | MEDIUM |
az login (Azure CLI)AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_IDReader en la suscripciónUserAuthenticationMethod.Read.AllApplication.Read.AllLas comprobaciones de identidad (AZ-005, AZ-019) se omiten correctamente si los permisos de Graph API no están disponibles — el resto de la auditoría se ejecuta sin verse afectada.
pip install -e .
# Auditoría completa: todas las comprobaciones, todas las gravedades
azure-auditor
# Apuntar a una suscripción específica
azure-auditor --subscription <subscription-id>
# Mostrar solo hallazgos HIGH y CRITICAL
azure-auditor --severity HIGH
# Guardar el informe JSON en un directorio específico
azure-auditor --output-dir ./reports
# Solo salida de terminal
azure-auditor --no-json
# Registro detallado (verbose)
azure-auditor --verbose
O sin instalar:
PYTHONPATH=src python -m azure_security_auditor.cli --subscription <id>
Terminal — tabla con formato Rich, ordenada por gravedad (CRITICAL primero):
╭──────────────────────────────────────────────────────────────────╮
│ Azure Security Posture Audit │
│ Subscription: My Production Subscription │
│ ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
│ Run at: 2026-07-12T10:00:00Z │
│ Findings: 12 total (2 CRITICAL 6 HIGH 4 MEDIUM 0 LOW) │
╰──────────────────────────────────────────────────────────────────╯
Severity Check ID Check Resource Detail
✖ CRITICAL AZ-015 RDP Port 3389 Exposed to Internet... /subscriptions/. ...
✖ CRITICAL AZ-001 Owner Role Assigned at Subscription... <principal-id> ...
■ HIGH AZ-010 Defender for Cloud Not Enabled — VMs /subscriptions/. ...
...
JSON — se escribe en reports/azure_audit_<subscription>_<timestamp>.json.
src/
azure_security_auditor/
cli.py # Punto de entrada de argparse
engine.py # Orquestador de ThreadPoolExecutor
models.py # Finding, AuditResult, Severity
checks/
rbac.py # AZ-001, AZ-002
network.py # AZ-003, AZ-015, AZ-016
storage.py # AZ-004, AZ-017, AZ-018
identity.py # AZ-005, AZ-019
service_principals.py # AZ-006
encryption.py # AZ-007, AZ-008, AZ-020
monitoring.py # AZ-009, AZ-010, AZ-011
compute.py # AZ-012, AZ-013, AZ-014
reporters/
terminal.py # Salida de tabla Rich
json_reporter.py # Salida de archivo JSON
Utiliza DefaultAzureCredential — prueba en orden:
AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)az login)export AZURE_CLIENT_ID="<app-id>"
export AZURE_CLIENT_SECRET="<secret>"
export AZURE_TENANT_ID="<tenant-id>"
azure-auditor --subscription <subscription-id>