5.2 KiB
@suaveplan/api-audit-file — audit sink writing JSON-per-line, HMAC-SHA-256 signed records to a rotated file. Size + time rotation, maxFiles retention, bounded-queue backpressure with observable drops, append + strict-sync write modes. Implements RequestAuditSink from @suaveplan/api-host/request-pipeline.
File-rotating, HMAC-signed audit sink for @suaveplan/api-host.
Implements RequestAuditSink from
@suaveplan/api-host/request-pipeline: writes one JSON line per
record with an HMAC-SHA-256 signature, rolls the file on a size OR age
trigger, and prunes the oldest rotated siblings to a configurable
maxFiles retention cap.
Suitable for single-host deployments, on-prem environments without a
log shipper, and any host that prefers durable local storage of the
audit trail. The sibling @suaveplan/api-audit-stdout covers the
log-shipped use case; both sinks share the wire shape so dashboards
union on metric name and partition by the sink attribute.
Documentation tree
- error-codes — Frozen registry of the six stable
AUDIT_FILE.*error codes raised by the file-rotating audit sink, plus the concrete…- error-codes — Frozen registry of the six stable
AUDIT_FILE.*error codes raised by the file-rotating audit sink, plus the concrete…
- error-codes — Frozen registry of the six stable
- fs-helpers — Isolates the
node:fssurface the sink touches behind an injectableFsAdapterinterface and concretenodeFsAdapter…- fs-helpers — Isolates the
node:fssurface the sink touches behind an injectableFsAdapterinterface and concretenodeFsAdapter…
- fs-helpers — Isolates the
- hmac — Wraps
@suaveplan/crypto-hashHMAC-SHA-256 into the two operations the file sink needs: signing a canonical record on…- hmac — Wraps
@suaveplan/crypto-hashHMAC-SHA-256 into the two operations the file sink needs: signing a canonical record on…
- hmac — Wraps
- instruments — Constructs the OTel counter bundle the file sink emits and exposes the canonical
sink="file"attribute set. Every obs…- instruments — Constructs the OTel counter bundle the file sink emits and exposes the canonical
sink="file"attribute set. Every obs…
- instruments — Constructs the OTel counter bundle the file sink emits and exposes the canonical
- retention — Enforces the
maxFilesretention dimension of the rotation policy by deleting the oldest rotated files until at most `…- retention — Enforces the
maxFilesretention dimension of the rotation policy by deleting the oldest rotated files until at most `…
- retention — Enforces the
- rotation — Resolves the rotation policy carried by every
createFileAuditSinkinstance and implements the rotation primitive itse…- rotation — Resolves the rotation policy carried by every
createFileAuditSinkinstance and implements the rotation primitive itse…
- rotation — Resolves the rotation policy carried by every
- schema — Defines the Zod schema and canonical-bytes function that bracket every audit record before it is signed and written. Th…
- schema — Defines the Zod schema and canonical-bytes function that bracket every audit record before it is signed and written. Th…
- sink — The public entry point of
@suaveplan/api-audit-file. ThecreateFileAuditSinkfactory composes the schema, hmac, rot…- sink — The public entry point of
@suaveplan/api-audit-file. ThecreateFileAuditSinkfactory composes the schema, hmac, rot…
- sink — The public entry point of
Install
bun add @suaveplan/api-audit-file
Quickstart
import { createFileAuditSink } from "@suaveplan/api-audit-file/sink";
const sink = await createFileAuditSink({
path: "/var/log/suaveplan/audit.log",
hmacKey: new TextEncoder().encode(process.env.AUDIT_HMAC_KEY ?? ""),
rotation: { maxSizeBytes: 100 * 1024 * 1024, maxAgeMs: 86_400_000, maxFiles: 30 },
appendMode: "strict-sync",
});
await sink.emit(envelopeFromHostPipeline);
await sink.dispose();
Modules
./sink—createFileAuditSink,FileAuditSink,CreateFileAuditSinkOptions,AppendMode../rotation—RotationPolicy,RotationState,resolveRotationPolicy,shouldRotate,rotate../retention—enforceRetention../schema—AuditRecord,AuditRecordSchema,canonicalise,buildSignedLine../hmac—signRecord,verifyRecord../instruments—AuditFileInstruments,createAuditFileInstruments,SINK_ATTRIBUTE../fs-helpers—FsAdapter,nodeFsAdapter,listRotatedFiles,rotatedFilePathAt../error-codes—AUDIT_FILE_CODES,AuditFileError,AuditFileCode.
Error codes
AUDIT_FILE.INVALID_RECORD, AUDIT_FILE.WRITER_FAILED,
AUDIT_FILE.QUEUE_FULL, AUDIT_FILE.ROTATION_FAILED,
AUDIT_FILE.RETENTION_FAILED, AUDIT_FILE.PATH_NOT_WRITEABLE.
OTel instruments
api.audit.records_total{sink="file"}api.audit.dropped_total{sink="file"}api.audit.rotation_evicted_total{sink="file"}
Tier
Server-tier — depends on node:fs/promises.