Un registro de seguridad sirve para reconstruir quién intentó hacer qué, sobre qué recurso, cuándo y con qué resultado. No es una copia de todas las solicitudes ni un volcado de excepciones. Su objetivo es aportar evidencia útil para investigar accesos y acciones sospechosas, con el mínimo de datos necesario y controles que eviten que el propio registro se convierta en una fuente de exposición.
Para diseñar logging de seguridad en PHP, conviene definir primero los eventos que importan y el uso que tendrán: detección, investigación, auditoría operativa o cumplimiento de una política interna. Después se establece un formato común, se decide quién puede consultar los registros y se prueba el recorrido completo. Un log que existe pero no permite ordenar eventos, identificar el resultado o distinguir intentos de acciones completadas no resuelve la necesidad de investigación.
Separar logs técnicos, actividad y eventos de seguridad

Los logs técnicos describen el funcionamiento de la aplicación: errores, excepciones, latencia, fallos de conexión o problemas de configuración. Ayudan a diagnosticar disponibilidad y comportamiento. El registro de actividad documenta acciones de negocio atribuibles a usuarios, como editar una factura o cambiar datos de una cuenta. Los eventos de seguridad, en cambio, se centran en hechos relevantes para proteger identidades, permisos, recursos y límites de acceso.
Hay intersecciones, pero no son categorías intercambiables. Un cambio de rol puede ser actividad de negocio y evento de seguridad; una excepción de base de datos suele ser técnica, aunque una serie de fallos en una operación sensible pueda merecer una alerta de seguridad. Definir propósitos evita duplicar información sin criterio y permite asignar retenciones, acceso y formatos adecuados.
No use el log de seguridad como almacén de auditoría ilimitado ni como sustituto de métricas y trazas. Tampoco asuma que registrar un evento equivale a detectarlo: para generar alertas hacen falta reglas, umbrales y responsables de respuesta. Documente qué sistema produce cada dato y qué equipo lo utiliza.
Elegir acciones y contexto que permitan investigar
Empiece por un inventario de acciones y amenazas relevantes para la aplicación. Entre los eventos que suelen requerir consideración están los inicios de sesión fallidos, bloqueos de cuenta, cambios de credenciales, concesiones o revocaciones de permisos, cambios de configuración, exportaciones sensibles y operaciones administrativas. La lista debe reflejar el producto: registrar cada lectura de una página puede generar ruido, mientras que omitir una modificación de privilegios impide reconstruir un acceso indebido.
Para cada evento, defina qué pregunta debe poder responderse. Si se investiga un cambio de permiso, por ejemplo, importa identificar al actor, el usuario o recurso afectado, el permiso anterior y el nuevo, el resultado y el momento. En una autenticación fallida, puede ser relevante el identificador de cuenta normalizado o seudonimizado según la política, además del resultado y el origen de la solicitud si su recogida está justificada. Evite inferir una identidad a partir de una dirección IP compartida.
Distinga intento, decisión y resultado. Una petición denegada no es una modificación completada; una solicitud aceptada puede fallar antes de persistir. Registre el resultado real y, cuando haga falta para investigar, la etapa alcanzada. Defina también qué significa cada valor, como denied, failed o succeeded, para que distintos componentes no los usen de forma contradictoria.
Usar un esquema consistente y correlacionable
Un formato estructurado, normalmente JSON, facilita filtrar y correlacionar eventos en herramientas operativas. Como base, considere estos campos:
- Identificador del evento: nombre estable y versionado, por ejemplo
authorization.permission_changed. - Instante: fecha y hora en UTC, con precisión adecuada y relojes de los sistemas sincronizados.
- Actor: identificador interno o seudónimo; represente explícitamente a procesos y tareas automatizadas.
- Acción y recurso: operación realizada y tipo e identificador del recurso afectado, evitando incluir su contenido.
- Resultado: éxito, rechazo o fallo, con un motivo categorizado y no sensible.
- Correlación: identificador de solicitud o de operación para relacionar eventos sin volcar la solicitud entera.
- Origen contextual: servicio o componente que emitió el evento y, si está justificado, datos limitados del origen de red.
Los nombres de campos y sus tipos deben mantenerse estables. Una correlación de solicitud tiene que ser generada o validada por la infraestructura; aceptar sin control un identificador arbitrario puede permitir colisiones o confusión. No incluya cabeceras completas, cuerpos HTTP ni parámetros indiscriminadamente. El contexto debe ayudar a reconstruir la secuencia, no replicar todos los datos procesados.
Excluir secretos y minimizar datos personales
Nunca registre contraseñas, tokens de acceso, claves API, secretos de sesión, códigos de recuperación ni valores que permitan autenticarse. Evite también datos personales completos cuando un identificador interno baste. Para campos como correo, teléfono o dirección, decida si es imprescindible guardarlos, si pueden enmascararse o si conviene usar una referencia seudonimizada. La decisión depende del propósito, el riesgo y las obligaciones aplicables.
La redacción debe ocurrir antes de que el evento salga del proceso, no confiar únicamente en un filtro posterior del agregador. En PHP, evite serializar directamente objetos de petición, cabeceras o excepciones que puedan contener valores sensibles. Cree un objeto o arreglo explícito con una lista permitida de campos; una estrategia de lista de bloqueo es frágil cuando aparecen campos nuevos. Valide y limite también la longitud de valores controlables por el usuario para reducir inyección de líneas, ruido y consumo excesivo.
Pruebe casos en los que los datos secretos aparecen en parámetros o mensajes de error y compruebe que no llegan al destino de logs. La sanitización debe conservar suficiente información para investigar, por ejemplo una categoría de error, sin conservar el mensaje completo si este puede incluir credenciales.
Proteger acceso, integridad y ciclo de vida
Los registros también contienen información sensible. Restrinja quién puede escribir, leer, exportar y administrar la retención; estas funciones pueden requerir permisos distintos. Proteja el transporte y el almacenamiento con los controles apropiados para la infraestructura, y evite que una cuenta comprometida de la aplicación pueda borrar o alterar sin rastro todo el historial. Cuando el riesgo lo justifique, use almacenamiento de solo anexado o controles de integridad verificables y documente sus límites.
Defina una retención explícita por clase de evento. Conservar indefinidamente aumenta exposición y coste; eliminar demasiado pronto puede frustrar una investigación. La política debe contemplar copias, exportaciones, entornos de prueba y solicitudes de borrado que afecten a datos personales. Registre y revise el acceso de operadores a los propios logs, especialmente las exportaciones o cambios de política.
El logging puede fallar por indisponibilidad del destino, límites de almacenamiento o errores de serialización. Decida qué ocurre en cada caso según la criticidad. No convierta una caída del sistema de logs en una vía para completar silenciosamente una operación de alto riesgo, pero tampoco deje que una excepción de logging provoque resultados incoherentes o duplique una transacción. Para operaciones críticas puede ser necesario asegurar la escritura del evento junto con el cambio mediante una estrategia transaccional, como un patrón de outbox. Si se usa una cola, defina reintentos, deduplicación y tratamiento de eventos pendientes.
Probar que el evento existe y es seguro
Las pruebas deben verificar más que una llamada a una función de logging. Recorra escenarios representativos: acceso denegado, privilegio concedido, privilegio revocado y cambio sensible completado o fallido. Compruebe que el evento incluye actor, recurso, resultado, instante y correlación; que el resultado coincide con lo que realmente ocurrió; y que no aparecen contraseñas, tokens ni datos innecesarios.
Incluya pruebas de fallos del destino de logs y observe si la operación principal queda en un estado consistente, si se genera una señal alternativa y si el error se hace visible para operaciones. En una acción sensible, confirme que no se informa de éxito si el cambio no se persistió. También pruebe límites y entradas manipuladas, como saltos de línea en valores controlables, y la lectura por roles: un usuario de negocio no debería acceder por defecto al repositorio de eventos.
Lista de comprobación para revisar una implementación

- ¿Cada evento tiene un propósito, responsable y política de retención definidos?
- ¿Se distinguen intentos, rechazos, fallos y operaciones completadas?
- ¿El esquema permite identificar actor, acción, recurso, resultado e instante?
- ¿Hay correlación con la solicitud sin registrar su contenido completo?
- ¿Se excluyen secretos y se minimizan datos personales antes del envío?
- ¿El acceso, transporte, almacenamiento y eliminación están controlados?
- ¿Se han probado el destino indisponible, la integridad de la operación y los permisos de lectura?
Priorice primero los eventos que protegen cuentas, privilegios y operaciones de mayor impacto. Después estandarice el esquema, limite los datos y automatice pruebas que fallen si un secreto entra en los logs. Así, el logging de seguridad en PHP aporta evidencia accionable sin convertirse en una segunda base de datos de información sensible.



