.agents/skills/audit-logging/SKILL.md
Audit logging for compliance and security. Structured audit events, immutable logs, user action tracking, database change tracking, and regulatory compliance (SOC2, HIPAA, GDPR). USE WHEN: user mentions "audit log", "audit trail", "activity log", "change tracking", "compliance logging", "who changed what", "SOC2 logging" DO NOT USE FOR: application logging - use logging skills; error tracking - use observability skills
npx skillsauth add d-subrahmanyam/deno-fresh-microservices audit-loggingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
interface AuditEvent {
id: string;
timestamp: string; // ISO 8601
actor: {
id: string;
type: 'user' | 'system' | 'api_key';
ip?: string;
userAgent?: string;
};
action: string; // 'user.created', 'order.deleted'
resource: {
type: string; // 'user', 'order'
id: string;
};
changes?: { // Before/after for updates
field: string;
before: unknown;
after: unknown;
}[];
metadata?: Record<string, unknown>;
}
class AuditService {
async log(event: Omit<AuditEvent, 'id' | 'timestamp'>): Promise<void> {
const auditEntry: AuditEvent = {
id: randomUUID(),
timestamp: new Date().toISOString(),
...event,
};
// Write to append-only table
await db.auditLog.create({ data: auditEntry });
// Optionally stream to external system
await this.eventStream?.publish('audit', auditEntry);
}
}
// Usage in service layer
async function updateUser(userId: string, data: UpdateUserDto, actor: Actor) {
const before = await db.user.findUnique({ where: { id: userId } });
const after = await db.user.update({ where: { id: userId }, data });
await audit.log({
actor: { id: actor.id, type: 'user', ip: actor.ip },
action: 'user.updated',
resource: { type: 'user', id: userId },
changes: diffFields(before, after, ['name', 'email', 'role']),
});
return after;
}
function diffFields(before: any, after: any, fields: string[]) {
return fields
.filter((f) => before[f] !== after[f])
.map((f) => ({ field: f, before: before[f], after: after[f] }));
}
function auditMiddleware(action: string) {
return (req: Request, res: Response, next: NextFunction) => {
const originalJson = res.json.bind(res);
res.json = (body) => {
audit.log({
actor: { id: req.user?.id ?? 'anonymous', type: 'user', ip: req.ip },
action,
resource: { type: action.split('.')[0], id: req.params.id ?? body?.id },
});
return originalJson(body);
};
next();
};
}
app.delete('/api/users/:id', auditMiddleware('user.deleted'), deleteUserHandler);
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
timestamp TIMESTAMPTZ NOT NULL DEFAULT now(),
actor_id TEXT NOT NULL,
actor_type TEXT NOT NULL,
actor_ip INET,
action TEXT NOT NULL,
resource_type TEXT NOT NULL,
resource_id TEXT NOT NULL,
changes JSONB,
metadata JSONB
);
-- Append-only: revoke UPDATE and DELETE
REVOKE UPDATE, DELETE ON audit_logs FROM app_user;
-- Indexes for common queries
CREATE INDEX idx_audit_actor ON audit_logs (actor_id, timestamp DESC);
CREATE INDEX idx_audit_resource ON audit_logs (resource_type, resource_id, timestamp DESC);
CREATE INDEX idx_audit_action ON audit_logs (action, timestamp DESC);
| Anti-Pattern | Fix |
|--------------|-----|
| Logging inside transaction (fails = no log) | Log after successful commit |
| Mutable audit table | Revoke UPDATE/DELETE, use append-only |
| Missing actor identity | Always capture who performed the action |
| Logging sensitive field values | Redact PII (email → j***@example.com) |
| No retention policy | Partition by month, archive after retention period |
development
Guidelines for building high-performance APIs with Fastify and TypeScript, covering validation, Prisma integration, and testing best practices
development
FastAPI modern Python web framework. Covers routing, Pydantic models, dependency injection, and async support. Use when building Python APIs. USE WHEN: user mentions "fastapi", "pydantic", "async python api", "python rest api", asks about "dependency injection python", "python openapi", "python swagger", "async endpoints", "python api validation", "fastapi middleware" DO NOT USE FOR: Django apps - use `django` instead, Flask apps - use `flask` instead, synchronous Python APIs without type hints, GraphQL-only APIs
tools
FastAPI integration testing specialist. Covers synchronous TestClient, async httpx AsyncClient, dependency injection overrides, auth testing (JWT, OAuth2, API keys), WebSocket testing, file uploads, background tasks, middleware testing, and HTTP mocking with respx, responses, and pytest-httpserver. USE WHEN: user mentions "FastAPI test", "TestClient", "httpx async test", "dependency override test", "respx mock", asks about testing FastAPI endpoints, authentication in tests, or HTTP client mocking. DO NOT USE FOR: Django - use `pytest-django`; pytest internals - use `pytest`; Container infrastructure - use `testcontainers-python`
development
Expert in FastAPI Python development with best practices for APIs and async operations