Help us improve
Share bugs, ideas, or general feedback.
From lgpd-skills
Designs immutable, hash-chained audit logs for LGPD compliance (Art. 6, X) with Prisma schema and Next.js middleware. Use for audit logging, accountability, or incident registration.
npx claudepluginhub goul4rt/lgpd-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/lgpd-skills:lgpd-audit-loggingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Log imutável encadeado para prova de conformidade (Art. 6º, X — responsabilização) e registro de incidentes (Art. 10 Res. 15/2024 — 5 anos).
Designs immutable, hash-chained audit logs for LGPD compliance (Art. 6, X) with Prisma schema and Next.js middleware. Use for audit logging, accountability, or incident registration.
Logs security-relevant events (who, what, when, where, outcome) in a structured, tamper-evident format for real-time detection and forensic reconstruction. Use when designing audit infrastructure or preparing for SOC2, HIPAA, or PCI-DSS compliance.
Records audit logs of user inputs (verbatim), agent actions, phase transitions, and gate decisions with ISO 8601 timestamps. Supports SOC2/ISMS-P retention policies (30/90/365 days) per project.
Share bugs, ideas, or general feedback.
Log imutável encadeado para prova de conformidade (Art. 6º, X — responsabilização) e registro de incidentes (Art. 10 Res. 15/2024 — 5 anos).
model AuditLogEntry {
id String @id @default(cuid())
actorId String? // null se sistema
actorType ActorType
action String // "READ", "WRITE", "DELETE", "EXPORT", "DSAR_FULFILLED", "CONSENT_REVOKED"
resource String // "User:abc123", "Order:xyz"
subjectId String? // titular afetado (se aplicável)
legalBasis String?
purpose String?
ipAddress String? @db.Inet
userAgent String?
payloadHash String // SHA-256 do payload (sem PII)
prevHash String? // hash do registro anterior
selfHash String // SHA-256(prevHash || timestamp || action || resource || payloadHash)
timestamp DateTime @default(now())
@@index([subjectId, timestamp])
@@index([actorId, timestamp])
@@index([action, timestamp])
}
enum ActorType { USER ADMIN SYSTEM OPERATOR }
// lib/audit.ts
import { createHash } from "crypto";
import { db } from "./db";
export async function logAudit(entry: {
actorId?: string;
actorType: ActorType;
action: string;
resource: string;
subjectId?: string;
legalBasis?: string;
purpose?: string;
payload?: object;
req?: Request;
}) {
const last = await db.auditLogEntry.findFirst({
orderBy: { timestamp: "desc" },
select: { selfHash: true }
});
const payloadHash = createHash("sha256")
.update(JSON.stringify(entry.payload ?? {}))
.digest("hex");
const timestamp = new Date();
const selfHash = createHash("sha256")
.update(`${last?.selfHash ?? ""}|${timestamp.toISOString()}|${entry.action}|${entry.resource}|${payloadHash}`)
.digest("hex");
return db.auditLogEntry.create({
data: {
...entry,
payload: undefined,
payloadHash,
prevHash: last?.selfHash,
selfHash,
ipAddress: entry.req?.headers.get("x-forwarded-for") ?? null,
userAgent: entry.req?.headers.get("user-agent") ?? null,
timestamp
}
});
}
Script periódico que percorre todas as entries em ordem e verifica que cada selfHash bate. Qualquer divergência = tampering ou bug.
## F6 — Audit logging ✓
- Schema implementado
- Middleware ativo em rotas críticas
- Verificação de integridade agendada (semanal)
- Retenção configurada (5 anos para eventos críticos)
- Próximo: lgpd-encryption-keys