Product Craft Bible
Activity logs & audit trails
Inicio SaaS y Admin Activity logs & audit trails
SaaS y Admin

Activity logs & audit trails

8 reglas OWASP Logging Cheat Sheet (when/where/who/what) · GitHub Audit Log · Stripe Activity LogsInfisical, Building Audit Logs (human-readable description)OWASP Logging Cheat Sheet (datos a nunca registrar) · OWASP Top 10:2025 A09GitHub Audit Log (qualifiers tipados) · Stripe Activity Logs · Infisical
130

Activity logs & audit trails

8 reglas
1150

Captura los cuatro ejes en cada entrada: quien, que, sobre que y cuando

Cada entrada del log debe responder cuatro preguntas sin ambiguedad: quien realizo la acción (el actor autenticado, no solo una IP), que hizo exactamente (verbo legible más categoría), sobre que recurso actuo (objeto con nombre, no ID crudo) y cuando ocurrio (timestamp ISO 8601 con zona horaria explicita). Omitir cualquiera de los cuatro convierte el log en evidencia parcial, inútil para una auditoria legal o para reconstruir un incidente. Cuando el actor es el sistema y no un humano, diferencialo con una etiqueta tipo [Sistema] para que nadie confunda una acción automática con una manual.

OWASP Logging Cheat Sheet (when/where/who/what) · GitHub Audit Log · Stripe Activity Logs
Preferir
Maria Lopez cambio el rol de Juan Garcia a Admin
14 jun 2026, 10:32 AM CST Panel de Administración
Sistema  roto la sesión inactiva de Ana Ruiz
14 jun 2026, 11:05 AM CST
Evitar
usr_891 → role_update → usr_443 · 1718368320
1151

Escribe mensajes en lenguaje humano, no en códigos de maquina

La descripción de cada evento debe ser una oración en prosa que cualquier stakeholder no técnico pueda leer sin un diccionario de códigos. El patrón recomendado es sujeto + verbo en pasado + objeto + contexto: "Carlos Perez invito a sofia@empresa.com como Miembro". Resuelve los nombres propios al renderizar, o guarda un snapshot del nombre en el momento del evento, para que un rename futuro no rompa la lectura historica. Usa verbos específicos: "elimino", no "actualizo"; "exporto", no "acciono".

Infisical, Building Audit Logs (human-readable description)
Preferir
Carlos Perez invito a sofia@empresa.com como Miembro Panel de Equipo · hace 3 horas
Evitar
EVENT_TYPE: user_invite_created | ACTOR_ID: usr_012 | TARGET: sofia@empresa.com | TS: 1718281920
1152

Muestra el diff en el detalle expandible, nunca el valor sensible

El detalle de una entrada de edición debe expandirse para mostrar el antes y el después campo por campo, con resaltado de lo que cambio. Pero los logs se exportan y son accesibles a multiples roles: nunca registres contrasenas, tokens, números de tarjeta ni claves de cifrado. Si el campo modificado es sensible, el evento se registra pero el valor se muestra como [redactado]. Así el auditor confirma que la contrasena cambio sin que el log se convierta en un vector de filtración.

OWASP Logging Cheat Sheet (datos a nunca registrar) · OWASP Top 10:2025 A09
Preferir
Maria Lopez actualizo su contrasena
Campo: password
[redactado] [redactado]
Campo: display_name
M. Lopez Maria Lopez
Evitar
Maria cambio su contrasena
Anterior: MiPass123! · Nuevo: NuevoPass456#
1153

Filtra por actor, acción, objeto y rango de fecha con chips eliminables

Un log sin filtros es inútil a escala. Los filtros mínimos son actor (quien), tipo de acción (que), recurso (sobre que) y rango de fechas. Cada filtro activo debe mostrarse como chip eliminable para que el usuario entienda el estado actual de la vista de un vistazo. Además, ofrece enlaces directos desde el recurso al log ya prefiltrado ("Ver actividad de este usuario"), para que el auditor no tenga que reconstruir el filtro a mano. Un buscador de texto libre que solo hace match en la descripción no sustituye a los filtros tipados.

GitHub Audit Log (qualifiers tipados) · Stripe Activity Logs · Infisical
Preferir
Evitar
Buscar en el log...
1154

Exporta para auditoria respetando los filtros activos y etiquetando cada columna

Compliance, legal y seguridad necesitan llevar los logs fuera del sistema para reportes o reguladores. El export debe respetar los filtros activos (no descargar el log completo cuando el usuario filtro por fecha y actor), ofrecer al menos CSV y JSON, y etiquetar cada campo con nombre claro: actor_name, action_type, timestamp_utc, nunca f1 o col_4. Incluye metadata de cadena de custodia en el archivo: quien lo genero, cuando y con que filtros. El botón debe declarar el alcance: "Exportar (247 registros)".

GitHub Audit Log export (JSON/CSV con filtros) · GDPR Art. 30 (registros de tratamiento)
Preferir
Exportar 247 registros filtrados
Actor: Maria Lopez · role_update · 1–14 jun · columnas etiquetadas + metadata de export
CSV JSON
Evitar
Exportar todo (últimos 100,000 registros)
1155

Garantiza inmutabilidad: append-only, sin editar ni borrar, ni para superadmins

Un log que un administrador puede modificar o borrar no es evidencia confiable. La implementación debe ser append-only a nivel de base de datos (sin UPDATE ni DELETE en la tabla de audit), con verificación de integridad por hash chaining para detectar cualquier alteración. En la UI, ningun control de edición o papelera debe ser visible en el log, ni siquiera para superadmins: lo único que aparece al hacer hover es "Ver detalle". Comunica la garantía con un badge visible: "Inmutable · Hash verificado".

OWASP Logging Cheat Sheet (tamper detection) · AuditKit SOC2 (hash chaining) · Infisical (read-only)
Preferir
Audit log Inmutable · Hash verificado
Maria cambio el rol de JuanVer detalle
Carlos invito a sofia@empresa.comVer detalle
Evitar
Audit log
Maria cambio el rol de Juan
Carlos invito a sofia@empresa.com
1156

Registra IP, dispositivo y destaca los eventos de seguridad

El contexto de origen, dirección IP, pais aproximado y dispositivo o user-agent, convierte una entrada en evidencia accionable: permite detectar un acceso desde una geografia inusual o un dispositivo nuevo. Los eventos de seguridad (login fallido repetido, cambio de contrasena, MFA deshabilitado, sesión sospechosa) deben destacarse visualmente del ruido operativo con un acento de color y un icono, no perderse en una lista uniforme. Para logs fríos enmascara la IP a /24 para cumplir GDPR sin perder la señal de geolocalización.

GitHub Audit Log (pais de origen) · OWASP Top 10:2025 A09 · GDPR (truncado de IP)
Preferir
5 intentos de login fallidos para ana@empresa.com
187.x.x.0/24MexicoChrome / macOS
Maria Lopez exporto el reporte mensual
201.x.x.0/24MexicoSafari / iOS
Evitar
Login fallido
Cambio de contrasena
Vista de reporte
1157

Haz accesible la tabla densa: role=log para feeds y time datetime en cada fecha

Un feed de actividad en vivo debe envolver su contenedor en role="log", que implica aria-live="polite" y aria-atomic="false": el lector de pantalla anuncia cada nueva entrada sin interrumpir la narración en curso. Dale un aria-label descriptivo y, para tablas paginadas, confirma los resultados de filtro con una region aria-live ("Mostrando 50 resultados"). Cada timestamp debe usar <time datetime="2026-06-14T10:32:00-06:00">: el texto visible puede ser relativo ("hace 3 horas") mientras el atributo conserva la fecha absoluta con zona horaria para la tecnologia de asistencia.

W3C WCAG Technique ARIA23 (role=log) · WCAG 4.1.3 Status Messages (AA)
Preferir
role="log" aria-live="polite"
Maria cambio el rol de Juanhace 3 h
Carlos invito a sofia@empresa.comhace 2 h
Evitar
<div class="log-feed">
Maria cambio el rol de Juan06/14/26 10:32
Carlos invito a sofia@empresa.com06/14/26 11:05