Convertir incidentes en barreras de seguridad
Los incidentes sin barreras de seguridad se repiten. Las barreras de seguridad son alertas, pruebas, reglas de linting y listas de verificación que hacen que el mismo fallo sea más difícil o visible antes. Los equipos de Python las codifican en pytest, Ruff, revisión de Alembic y alertas de consumo de SLO.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
# Regresión de pytest del post-mortem INC-8842
def test_migration_uses_concurrently_for_large_tables():
sql = Path("alembic/versions/20260612_add_invoice_idx.py").read_text()
assert "CONCURRENTLY" in sql or "op.create_index" not in sql# Alerta: Indicador principal de profundidad de la cola de Celery
- alert: BillingQueueDepthHigh
expr: celery_queue_length{queue="billing"} > 10000
for: 5mCuándo usar esto:
- Los elementos de acción del post-mortem necesitan una entrega concreta
- La misma clase de incidente ocurrió dos veces en un trimestre
- La auditoría solicita controles preventivos
- Fatiga de guardia debido a páginas ruidosas pero prevenibles
Ejemplo de trabajo
"""guardrails_example.py - pruebas impulsadas por incidentes y verificaciones en tiempo de ejecución."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class Guardrail:
incident_id: str
kind: str # test | alert | lint | runbook
description: str
verify: str
GUARDRAILS: list[Guardrail] = [
Guardrail(
incident_id="INC-8842",
kind="test",
description="Los índices de tablas grandes usan CONCURRENTLY",
verify="pytest tests/test_migrations.py -k concurrently",
),
Guardrail(
incident_id="INC-9011",
kind="alert",
description="Tasa de consumo de P95 del checkout",
verify="Grafana: CheckoutSLOBurn",
),
Guardrail(
incident_id="INC-9011",
kind="lint",
description="No hay sleep síncrono en rutas asíncronas",
verify="scripts/check_async_blocking.py en CI",
),
]
def audit_open_guardrails(registry: list[Guardrail]) -> None:
for g in registry:
print(f"[{g.incident_id}] {g.kind}: {g.description} -> {g.verify}")
if __name__ == "__main__":
audit_open_guardrails(GUARDRAILS)# tests/test_incident_9011_loop_block.py
import ast
from pathlib import Path
def test_no_time_sleep_in_async_functions():
src = Path("src/api/routes/checkout.py").read_text()
tree = ast.parse(src)
for node in ast.walk(tree):
if isinstance(node, ast.AsyncFunctionDef):
for child in ast.walk(node):
if isinstance(child, ast.Call):
func = child.func
if isinstance(func, ast.Attribute) and func.attr == "sleep":
raise AssertionError(f"time.sleep en async {node.name}")Lo que esto demuestra:
- Las barreras de seguridad se vinculan a los IDs de incidentes para trazabilidad
- Las pruebas de regresión codifican mecánicas de fallo específicas
- Los scripts de CI detectan patrones de bloqueo asíncrono
- La revisión de operaciones audita los comandos de verificación, no solo el cierre de tickets
Inmersión Profunda
Cómo funciona
- Indicadores principales - La profundidad de la cola y la espera del pool predicen 5xx antes de que los clientes lo noten.
- Pruebas de regresión - Seguro barato; se ejecutan en cada PR que toca rutas relacionadas.
- Política de linting/CI - Codifica elementos de la lista de verificación de revisión que las máquinas aplican.
- Actualizaciones de runbooks - Barreras de seguridad humanas cuando la automatización no es práctica.
- Métricas sobre barreras de seguridad - Seguimiento del tiempo medio de implementación de elementos de acción después de SEV1.
Tipos de Barreras de Seguridad
| Tipo | Ejemplo | Verifica |
|---|---|---|
| Prueba unitaria/integración | Replay de SQL de migración incorrecto | CI en verde |
| Prueba de contrato | Esquema pydantic de API/worker | Cambio disruptivo bloqueado |
| Alerta | Tasa de consumo de SLO 2x | El paginador se activa en prueba de staging |
| Regla personalizada de Ruff | Prohibir lru_cache(maxsize=None) | El PR falla |
| Día de juego | Reversión en menos de 10 minutos | RTO medido |
Notas de Python
# pyproject.toml - pip-audit en CI
[tool.uv]
dev-dependencies = ["pip-audit>=2.7"]
# scripts/ci.sh
# uv run pip-audit -r requirements.lockTrampas
- Elementos de acción que dicen "sé más cuidadoso" - No son barreras de seguridad. Solución: Requerir una prueba, alerta o verificación automatizada por elemento.
- Alertas sin enlace a runbook - El guardia ignora el ruido. Solución: La anotación apunta a los pasos de mitigación.
- Pruebas que simulan el error - La regresión nunca falla. Solución: Probar en el límite de integración que falló en producción.
- Barreras de seguridad en un solo servicio - El equipo hermano repite el incidente. Solución: La plataforma promueve el patrón al repositorio de plantillas.
- Cerrar tickets sin verificación - La deriva regresa. Solución: La revisión de operaciones mensual ejecuta el comando
verifydel registro.
Alternativas
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| Lista de verificación manual | Proceso humano de baja frecuencia | Fallo técnico repetible |
| Cambio de arquitectura | Defecto de diseño fundamental | Falta de alerta única |
| Eliminar función | El riesgo supera el valor | Ruta de ingresos principal |
| Ingeniería del caos | Validar barrera de seguridad bajo estrés | Antes de que exista monitorización básica |
Preguntas Frecuentes
¿Cuántas barreras de seguridad por incidente?
Preferir 1-3 elementos de alto apalancamiento. Demasiados diluyen la propiedad.
¿Quién es responsable de la entrega de barreras de seguridad?
El propietario del servicio implementa; la plataforma se encarga de las plantillas compartidas y los ganchos de CI.
¿Deben las barreras de seguridad bloquear el despliegue?
Sí, para migraciones y seguridad. Solo advertencias para la primera iteración, luego promover a fallo duro.
¿Cómo protegerse de problemas asíncronos?
Verificación AST estática más prueba de tiempo de pytest bajo carga concurrente en CI.
¿Qué pasa con las interrupciones de terceros?
Pruebas de disyuntor y regresión del comportamiento de fallback; runbook de comunicación de página de estado.
¿Necesitamos un registro de barreras de seguridad?
Útil a escala: hoja de cálculo o YAML que enumera el ID del incidente, el comando de verificación, el propietario.
¿Cómo prevenir la fatiga de alertas?
Ajustar umbrales con datos de incidentes; llamar por consumo de SLO, no por picos únicos.
¿Pueden las aplicaciones LLM tener barreras de seguridad?
Sí: suites de evaluación para regresiones de prompts, alertas de presupuesto de tokens, pruebas de políticas de rechazo.
¿Cuándo eliminar una barrera de seguridad?
Cuando la ruta de código se elimina o es reemplazada por un control de plataforma. Documentar en el registro de cambios.
¿Cómo medir el éxito?
Tasa de incidentes repetidos, tendencia de MTTR y antigüedad de elementos de acción < 30 días.
Relacionado
- Post-Mortems sin Culpa y RCA - genera elementos de acción
- Salud de Guardia - alertas sostenibles
- Modos Comunes de Fallo en Producción - qué prevenir
- Pruebas con pytest - inicio de pruebas de regresión
- Linting y Formateo - política de CI
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.