@tevui/nest-audit
v1.0.0
Published
HTTP request, response and audit logging for NestJS applications
Maintainers
Readme
@tevui/nest-audit
HTTP request, response, and audit logging for NestJS applications.
@tevui/nest-audit is a lightweight and configurable audit logging library for NestJS. It automatically captures HTTP request and response information and sends structured audit entries to a configurable storage provider.
The library is designed to provide audit logging with minimal changes to your existing NestJS application.
Features
- Automatic HTTP request and response auditing
- Global NestJS interceptor
- Request body capture
- Response body capture
- Request headers
- Query parameters
- Route parameters
- HTTP status code
- Request duration
- Client IP
- User-Agent
- Authenticated user information
- Request / correlation ID
- Sensitive data redaction
- Configurable excluded routes
@NoAudit()decorator@AuditAction()decorator- Pluggable storage architecture
- TypeScript support
Installation
npm install @tevui/nest-auditThe package expects NestJS and RxJS to be available in your application.
Quick Start
Import AuditModule into your root application module:
import { Module } from "@nestjs/common";
import { AuditModule } from "@tevui/nest-audit";
@Module({
imports: [
AuditModule.forRoot({
capture: {
requestBody: true,
responseBody: true,
headers: true,
query: true,
params: true,
user: true,
},
redact: ["password", "authorization", "accessToken", "refreshToken"],
excludeRoutes: ["/health", "/metrics"],
}),
],
})
export class AppModule {}Once configured, HTTP requests handled by your NestJS application can automatically generate audit entries.
Audit Entry
An audit entry follows a structure similar to:
{
"requestId": "req-01HXYZ123",
"action": "ORDER_CREATED",
"method": "POST",
"path": "/orders",
"statusCode": 201,
"request": {
"headers": {
"content-type": "application/json",
"authorization": "[REDACTED]"
},
"body": {
"productId": "ABC123",
"quantity": 2
},
"query": {},
"params": {}
},
"response": {
"body": {
"id": "order-789",
"status": "created"
}
},
"user": {
"id": "user-456",
"email": "[email protected]"
},
"ip": "127.0.0.1",
"userAgent": "Mozilla/5.0",
"durationMs": 48,
"createdAt": "2026-09-14T14:00:00.000Z"
}Configuration
Capture Options
You can control which parts of the HTTP request and response should be included in the audit entry.
AuditModule.forRoot({
capture: {
requestBody: true,
responseBody: true,
headers: true,
query: true,
params: true,
user: true,
},
});Available options:
| Option | Description |
| -------------- | --------------------------------------- |
| requestBody | Captures the HTTP request body |
| responseBody | Captures the HTTP response body |
| headers | Captures request headers |
| query | Captures query parameters |
| params | Captures route parameters |
| user | Captures authenticated user information |
Sensitive Data Redaction
Audit logs can accidentally expose credentials, access tokens, cookies, or other sensitive information.
@tevui/nest-audit supports recursive sensitive-field redaction.
AuditModule.forRoot({
redact: [
"password",
"passwordConfirmation",
"authorization",
"accessToken",
"refreshToken",
"cookie",
],
});For example:
{
"email": "[email protected]",
"password": "my-secret-password"
}is stored as:
{
"email": "[email protected]",
"password": "[REDACTED]"
}Nested properties are sanitized recursively as well.
{
"credentials": {
"accessToken": "[REDACTED]"
}
}Audit logging should always be configured according to the security, privacy, and regulatory requirements of your application. Avoid collecting data that your application does not need to retain.
Excluding Routes
Some endpoints usually do not need to generate audit records, such as health checks or metrics endpoints.
AuditModule.forRoot({
excludeRoutes: ["/health", "/metrics"],
});@NoAudit()
Individual endpoints can be excluded from audit logging using the @NoAudit() decorator.
import {
NoAudit,
} from '@tevui/nest-audit';
@NoAudit()
@Get('/health')
health() {
return {
status: 'ok',
};
}The decorator can also be applied at controller level.
@NoAudit()
@Controller("/internal")
export class InternalController {
// ...
}Audit Actions
Use @AuditAction() to associate a business action with an HTTP operation.
import {
AuditAction,
} from '@tevui/nest-audit';
@AuditAction('ORDER_CREATED')
@Post('/orders')
createOrder() {
// ...
}The generated audit entry can contain:
{
"action": "ORDER_CREATED",
"method": "POST",
"path": "/orders"
}This makes it possible to use the library not only for HTTP logging, but also for application-level audit trails.
Other examples:
@AuditAction('USER_CREATED')
@AuditAction('USER_DELETED')
@AuditAction('ORDER_CANCELLED')
@AuditAction('PAYMENT_CREATED')
@AuditAction('ACCOUNT_UPDATED')Authenticated Users
When authentication middleware or a NestJS authentication guard attaches a user to:
request.user;the library can include user information in the audit entry.
For example:
request.user = {
id: "user-123",
email: "[email protected]",
};can produce:
{
"user": {
"id": "user-123",
"email": "[email protected]"
}
}The current implementation can resolve the user identifier from common properties such as:
id
userId
subThis makes it compatible with common JWT authentication patterns.
Request IDs
The library can retrieve request identifiers from commonly used headers:
x-request-id
x-correlation-idExample:
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000The identifier can then be included in the audit entry:
{
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}This is useful when correlating application logs and audit events across requests.
Storage
@tevui/nest-audit uses a storage abstraction rather than being directly coupled to a specific database.
A storage provider implements:
export interface AuditStorage {
save(entry: AuditEntry): Promise<void>;
}This design allows different storage implementations to be used without coupling the audit core to MongoDB, PostgreSQL, Elasticsearch, or another persistence technology.
Memory Storage
A simple in-memory storage implementation is included primarily for development and testing.
import { MemoryAuditStorage } from "@tevui/nest-audit";
const storage = new MemoryAuditStorage();Memory storage should not be used as persistent audit storage in production because its contents are lost when the application process terminates.
Custom Storage
You can implement your own storage provider by implementing the AuditStorage interface.
import { AuditEntry, AuditStorage } from "@tevui/nest-audit";
export class MyAuditStorage implements AuditStorage {
async save(entry: AuditEntry): Promise<void> {
// Store the audit entry using your
// preferred database or service.
}
}For example, custom storage providers can integrate with:
- MongoDB
- PostgreSQL
- MySQL
- Elasticsearch
- Redis
- Kafka
- External logging services
The audit core remains independent of the persistence implementation.
Architecture
The library follows a storage-agnostic architecture:
HTTP Request
│
▼
AuditInterceptor
│
▼
NestJS Controller
│
▼
Application Service
│
▼
HTTP Response
│
▼
AuditInterceptor
│
▼
Sensitive Data Sanitizer
│
▼
AuditService
│
▼
AuditStorage
│
├──────────────► Memory
│
├──────────────► MongoDB
│
├──────────────► PostgreSQL
│
└──────────────► Custom StorageThis keeps request capture, data sanitization, and persistence concerns separated.
Why Audit Logging?
Traditional application logs are primarily useful for debugging and observability.
Audit logs answer a different set of questions:
Who performed the operation?
What operation was performed?
When did it happen?
Which endpoint was involved?
What was the result?
How long did the operation take?For example:
{
"action": "ORDER_CANCELLED",
"user": {
"id": "user-123"
},
"method": "DELETE",
"path": "/orders/789",
"statusCode": 200,
"durationMs": 31
}This can be useful for administrative systems, B2B platforms, internal tools, financial applications, and systems where traceability is important.
Performance Considerations
Audit logging should not unnecessarily increase HTTP response latency.
Storage implementations should therefore avoid expensive synchronous operations in the request lifecycle whenever possible.
For high-throughput production environments, audit entries may be sent asynchronously through technologies such as:
Application
│
▼
Audit Logger
│
▼
Queue / Message Broker
│
▼
Audit Worker
│
▼
DatabaseQueue and message-broker integrations are not part of the initial version of the library.
Roadmap
Potential future features include:
- MongoDB storage adapter
- PostgreSQL storage adapter
- Prisma adapter
- TypeORM adapter
- Configurable user extraction
- Custom request ID generators
- Improved correlation ID support
- Exception and error auditing
- Asynchronous audit queues
- Batch persistence
- Custom sanitizers
- Field-level capture rules
- OpenTelemetry integration
Design Principles
The project is built around a few core principles:
Minimal integration
Applications should be able to enable audit logging without modifying every controller.
Storage independence
The audit core should not depend on a specific database.
Security by design
Sensitive information should be sanitized before reaching the storage layer.
Extensibility
Applications should be able to provide their own storage and configuration.
NestJS-native architecture
The library uses NestJS concepts such as modules, dependency injection, interceptors, decorators, and metadata.
Contributing
Contributions, bug reports, and feature suggestions are welcome.
If you find an issue or have an idea for improving the library, feel free to open an issue or submit a pull request.
License
MIT
