Skip to content

Audit Log — Guía del Operador

Lea en su idioma: English · Português · Español

Estado del alcance (post Scope-Freeze 2026-05-10) — La capacidad de audit log se amplió para incluir la cadena de hash tamper-evident del Self-Upgrade (scaffold SELFUP-7), los eventos de telemetría del Lab Deployment Staging, las transcripciones de comandos de orquestación SSH/TELNET con redacción (según SSH-7), y el audit de ingress/egress de RELAY.Art (ADR 0020). El runbook de recolección de evidencias para SOC 2 Type II vive en runbooks/soc2-evidence-collection.md.

Esta página describe el audit logging que mantiene el Dashboard de TLSStress.Art. Los audit logs son la evidencia del operador de que LICENSE + USAGE_POLICY se respetan; también constituyen un registro forense útil al investigar incidentes.

Qué se audita

Dos streams de auditoría distintos:

1. Auditoría de aceptación de licencia — tabla audit_license_acceptance

Una fila por par (operador, license_version). Todo usuario autenticado debe producir una fila antes de que el Dashboard pase a ser utilizable. Consulte PRIVACY_POLICY.md para el schema y la justificación.

Schema (migration Drizzle 0019_license_acceptance.sql):

audit_license_acceptance (
  id                       uuid        PRIMARY KEY,
  session_user             text        NOT NULL,           -- session cookie 'agentcluster_session' user
  role                     enum        NOT NULL,           -- employee | partner
  declared_email           text        NOT NULL,           -- lowercased
  declared_email_raw       text        NOT NULL,           -- original casing
  license_version          text        NOT NULL,
  usage_policy_version     text        NOT NULL,
  privacy_policy_version   text        NOT NULL,
  telemetry_consent        boolean     NOT NULL DEFAULT false,
  client_ip                text,                           -- X-Forwarded-For of acceptance request
  user_agent               text,                           -- HTTP User-Agent
  accept_language          text,                           -- HTTP Accept-Language
  admin_note               text,                           -- free-form, for admin remediation
  accepted_at              timestamptz NOT NULL DEFAULT now(),
  UNIQUE (session_user, license_version)
);

2. Auditoría de acciones — tabla audit_log (existente)

Una fila por acción no trivial (intentos de login, cambios de configuración, eventos de ciclo de vida de ejecución, decisiones de scaling). Consulte dashboard/src/lib/audit.ts y dashboard/src/db/schema.ts.

Cómo consultar

Vía la página del visor admin

Abra /admin/audit/license-acceptances en el Dashboard (role admin requerido — la misma env var ADMIN_BASIC_AUTH que protege el resto de la UI admin). Tabla paginada read-only con filtros por rango de fechas, role, substring de email.

Vía SQL

Conéctese al Postgres del cluster vía psql (o pgAdmin / DBeaver):

# Get the connection details from the running pod:
kubectl exec -n web-agents postgres-0 -- env | grep POSTGRES_

# Open psql:
kubectl exec -it -n web-agents postgres-0 -- psql -U $POSTGRES_USER $POSTGRES_DB

Consultas útiles:

-- Most recent acceptances (latest first):
SELECT accepted_at, session_user, role, declared_email, client_ip, license_version
  FROM audit_license_acceptance
  ORDER BY accepted_at DESC
  LIMIT 50;

-- All partner acceptances in the last 30 days:
SELECT *
  FROM audit_license_acceptance
  WHERE role = 'partner'
    AND accepted_at > now() - INTERVAL '30 days'
  ORDER BY accepted_at DESC;

-- Operators who haven't accepted the latest license version yet:
SELECT DISTINCT session_user
  FROM audit_log     -- pull the list of recently-active users from the action audit
  WHERE created_at > now() - INTERVAL '7 days'
  EXCEPT
SELECT session_user
  FROM audit_license_acceptance
  WHERE license_version = 'PolyForm-Noncommercial-1.0.0+AppendixA-2026-05-06';

-- Count of acceptances per role:
SELECT role, count(*)
  FROM audit_license_acceptance
  GROUP BY role;

-- Operators who consented to telemetry:
SELECT session_user, declared_email, accepted_at
  FROM audit_license_acceptance
  WHERE telemetry_consent = true;

Vía API (solo admin)

La página del visor admin (/admin/audit/license-acceptances) lee GET /api/admin/audit/license-acceptances que retorna un array JSON. El endpoint requiere la cookie agentcluster_session Y autenticación admin.

Tareas operativas

Actualizando versiones de license / privacy policy

Cuando se realiza un cambio material en LICENSE o en cualquier archivo *_POLICY.md:

  1. Actualice la constante correspondiente en dashboard/src/lib/license-versions.ts:
    export const LICENSE_VERSION = 'PolyForm-Noncommercial-1.0.0+AppendixA-2026-XX-XX';
    
  2. Haga build + deploy del Dashboard — la próxima carga de página de cada operador dispara el License Acceptance Modal porque la fila de aceptación existente es de un license_version más antiguo.
  3. Las filas antiguas PERMANECEN en la tabla de auditoría (el historial de auditoría es inmutable por diseño).

Removiendo la autorización de un operador

Si un operador debe perder acceso (salió de la empresa, asociación terminada, etc.):

  1. Revoque su credencial del Dashboard (rote ADMIN_BASIC_AUTH o actualice el SSO).
  2. Opcionalmente, retenga la fila para el historial de auditoría (recomendado) — de todos modos no puede usar el sistema sin una sesión.
  3. Para señalizar explícitamente "ya no autorizado" sin borrar la fila:
    UPDATE audit_license_acceptance
       SET admin_note = 'Authorisation revoked on 2026-XX-XX by <admin>: <reason>'
     WHERE session_user = '<username>';
    

Limpiando la base de datos para handover

Al donar el cluster a otro equipo:

TRUNCATE audit_license_acceptance, audit_log;

Después del truncate: - Cada operador debe re-aceptar la licencia (comportamiento correcto para un handover) - El historial de auditoría pasado se pierde (intencional — el nuevo equipo empieza limpio)

Si se necesita preservar el historial de auditoría antes del handover, haga dump primero:

kubectl exec -n web-agents postgres-0 -- pg_dump --table audit_license_acceptance --table audit_log $POSTGRES_DB > audit-backup-$(date +%F).sql

Sealed audit log — WORM hash-chain & RFC 5424 (SaaS control plane)

El control plane comercial agrega un audit trail tamper-evident más allá de la tabla legada audit_log (audit epic, 2026-06). Resumen para el operador:

  • WORM (write-once). admin_audit_events es append-only: un trigger de DB rechaza cualquier UPDATE y cualquier DELETE antes de la ventana de retención. Las filas llevan un seq monotónico, el prev_hash de la fila anterior, y el hash SHA-256 de esta fila sobre su canonical JSON — una hash chain.
  • Verificar la chain. El admin console expone un verifier; programáticamente, re-hash cada fila y confirma hash[n] == H(prev_hash[n] || canonical(row[n])) y prev_hash[n] == hash[n-1]. Cualquier ruptura localiza la fila adulterada.
  • Signed export. El export produce un stream syslog RFC 5424 más una firma desprendida para que un auditor verifique la integridad offline. Field-length ceilings mantienen conformidad.
  • Forwarding & retención. Configura forwarding syslog + retención vía customer_audit_forward_config. Target de forwarding, formato (RFC 5424) y ventana de retención son definidos por el operador.

Follow-ups externos conocidos: registrar un IANA Private Enterprise Number (el SD-ID usa un placeholder PEN) y habilitar mTLS/CA-bundle en el canal de forwarding.

Postura de compliance

La tabla de auditoría satisface estos requisitos de compliance:

Requisito Fuente Cómo audit_license_acceptance lo satisface
Registros de consentimiento GDPR Art. 7(1), LGPD Art. 8 §6 Cada fila ES un registro de consentimiento — qué se aceptó, cuándo, por quién
Base legal demostrable GDPR Art. 6, LGPD Art. 7 La fila de aceptación + este PRIVACY_POLICY.md establecen la base
Pista de auditoría de acceso SOC 2 CC6, ISO 27001 A.12.4 Combinada con la tabla audit_log, historial completo de acciones
Derecho de acceso (titular de los datos) GDPR Art. 15 El operador puede hacer self-query filtrando por su propio session_user
Derecho al borrado GDPR Art. 17 DELETE contra la fila cuando un operador lo solicite

Este proyecto NO es un proveedor SaaS; los datos viven en la infraestructura propia del operador, de modo que la mayoría de las obligaciones de compliance recaen sobre el operador (dueño del cluster) y no sobre el licenciante. Esta página documenta cómo cumplirlas.

Relacionados