Logger for Auditing
Problem
Record authorization decisions for diagnostics or an audit pipeline without duplicating logging at every call site.
Solution
Provide a logger in WardOptions; Ward invokes it for explained decisions.
ts
import { createWard } from '@vielzeug/ward';
const audit: string[] = [];
const ward = createWard([{ role: 'viewer', resource: 'posts', action: 'read', effect: 'allow' }], {
logger: (ctx) => {
const who = ctx.principal === null ? 'anonymous' : ctx.principal.id;
const outcome = ctx.allowed ? 'allow' : ctx.reason;
audit.push(`${who}:${ctx.resource}:${ctx.action}:${outcome}`);
},
});
ward.explain({ principal: { id: 'u1', roles: ['viewer'] }, resource: 'posts', action: 'read' });
ward.explain({ principal: { id: 'u1', roles: ['viewer'] }, resource: 'posts', action: 'delete' });Pitfalls
- Treat logger output as an event stream; send durable audit records to your own storage layer.
trace(),allowedActions(), andrulesInScope()are inspection APIs and do not invoke the logger.