# @suaveplan/api-plugin-audit - Hono plugin wrapping @suaveplan/audit-logging as a write-through audit trail for @suaveplan/api. Installs a global middleware recording method/path/status/duration/response-size/request-id/principal-id/tenant-id per request, exposes auditService in ServiceRegistry, and surfaces c.get("audit") for handler-level events. Configurable redaction, sampling, and exclusion. Sink is caller-supplied (any AuditStorageAdapter); default is in-memory for dev. Server-tier — Bun + Node. Hono plugin that wraps `@suaveplan/audit-logging` as a write-through audit trail for `@suaveplan/api`. Installs a global per-request audit middleware (method / path / status / duration / response size / request id / principal id / tenant id), exposes `auditService` in the host `ServiceRegistry`, and surfaces `c.get("audit")` for handler-level semantic events. Sink is caller-supplied; default is an in-memory adapter for development. ## Documentation tree - [audit-context](./src/context/audit-context.md) — Builds the per-request `AuditContext` handle the audit middleware attaches to `c.set("audit", context)` before invoking… - [context-augmentation](./src/context/context-augmentation.md) — TypeScript module augmentation that adds the `audit: AuditContext` slot to Hono's `ContextVariableMap`. Without it, `c.… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable error-code registry for `@suaveplan/api-plugin-audit` and the concrete `AuditPluginError` class used… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable error-code registry for `@suaveplan/api-plugin-audit` and the concrete `AuditPluginError` class used… - [middleware](./src/middleware/audit-middleware.md) — Builds the global Hono middleware that records one audit event per non-excluded request through the underlying `AuditLo… - [audit-middleware](./src/middleware/audit-middleware.md) — Builds the global Hono middleware that records one audit event per non-excluded request through the underlying `AuditLo… - [otel](./src/otel/instruments.md) — Owns the OpenTelemetry instrument bundle the audit plugin emits to every request lifecycle. Resolving the instruments l… - [instruments](./src/otel/instruments.md) — Owns the OpenTelemetry instrument bundle the audit plugin emits to every request lifecycle. Resolving the instruments l… - [plugin](./src/plugin/plugin.md) — Top-level factory for the audit plugin. `createAuditPlugin(options)` Zod-validates the caller's options at the boundary… - [plugin](./src/plugin/plugin.md) — Top-level factory for the audit plugin. `createAuditPlugin(options)` Zod-validates the caller's options at the boundary… - [redact](./src/redact/redact.md) — Lightweight, allocation-free-ish payload redactor used by the audit middleware to scrub secret-bearing fields from per-… - [redact](./src/redact/redact.md) — Lightweight, allocation-free-ish payload redactor used by the audit middleware to scrub secret-bearing fields from per-… - [schemas](./src/schemas/options.md) — Zod schema that validates `AuditPluginOptions` at the `createAuditPlugin` factory boundary and produces the resolved `A… - [options](./src/schemas/options.md) — Zod schema that validates `AuditPluginOptions` at the `createAuditPlugin` factory boundary and produces the resolved `A… - [audit-service](./src/services/audit-service.md) — Constructs the `AuditService` adapter the plugin registers in `ServiceRegistry` under the `auditService` slot. The adap… - [registry-augmentation](./src/services/registry-augmentation.md) — Declares the `auditService` slot on `@suaveplan/api-plugin/service-registry`'s `ServiceRegistry` interface via TypeScri… - [types](./src/types/types.md) — Central, runtime-free declaration of the interfaces the plugin's lifecycle, middleware, services, and context helpers d… - [types](./src/types/types.md) — Central, runtime-free declaration of the interfaces the plugin's lifecycle, middleware, services, and context helpers d… ## Install ```bash bun add @suaveplan/api-plugin-audit ``` ## Quick start ```ts import { MemoryAuditAdapter } from "@suaveplan/audit-logging"; import { createAuditPlugin } from "@suaveplan/api-plugin-audit"; const plugin = createAuditPlugin({ sink: new MemoryAuditAdapter(), secretKey: process.env.AUDIT_SECRET_KEY, samplingRate: 1, // record every request excludePaths: ["/health", "/openapi.json"], }); // Register on your @suaveplan/api PluginRegistry alongside auth/tenant/etc. ``` Inside a route handler: ```ts app.post("/users/:id/delete", async (c) => { const audit = c.get("audit"); await audit.log({ type: "user.deleted", severity: "warning", actor: { userId: c.get("user")?.id }, target: { type: "user", id: c.req.param("id") }, }); return c.json({ ok: true }); }); ``` ## Modules - [plugin/plugin](./src/plugin/plugin.md) — `createAuditPlugin` factory. - [middleware/audit-middleware](./src/middleware/audit-middleware.md) — per-request middleware. - [services/audit-service](./src/services/audit-service.md) — `auditService` adapter. - [services/registry-augmentation](./src/services/registry-augmentation.md) — `ServiceRegistry` slot. - [context/audit-context](./src/context/audit-context.md) — handler-level `c.get("audit")`. - [context/context-augmentation](./src/context/context-augmentation.md) — Hono `ContextVariableMap` slot. - [redact/redact](./src/redact/redact.md) — payload redactor. - [otel/instruments](./src/otel/instruments.md) — OpenTelemetry counters + histogram. - [schemas/options](./src/schemas/options.md) — Zod options schema + defaults. - [error-codes/error-codes](./src/error-codes/error-codes.md) — `AUDIT_PLUGIN_*` registry. ## Features - One audit event per non-excluded request, recorded through the underlying `AuditLogger` (chain-integrity, GDPR export, retention all inherited). - Configurable redaction (case-insensitive headers, exact query / body field names). - Head-end sampling gate with caller-supplied (or default `Math.random`) RNG. - Excluded paths skip recording but still install the `audit` context slot. - Middleware NEVER throws into the request response — sink failures are logged at warn and counted via `audit.sink_failures_total`. - `auditService` registered with `ctx.registerService("auditService", ...)` and exposed through the typed `ServiceRegistry` slot. - Hono `ContextVariableMap` augmented with `audit: AuditContext` so handlers fire explicit events without import boilerplate. - Four OpenTelemetry instruments: `audit.requests_recorded_total{outcome,sampled}`, `audit.requests_excluded_total`, `audit.sink_failures_total`, `audit.middleware_duration_ms`.