@reaatech/mcp-gateway-audit
v1.1.0
Published
Compliance audit trail logging for mcp-gateway
Readme
@reaatech/mcp-gateway-audit
Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.
Compliance audit trail logging for the MCP Gateway. Captures security-relevant events with structured JSON output, supports multiple storage backends, tamper-evident chaining, and query capabilities.
Installation
npm install @reaatech/mcp-gateway-audit
# or
pnpm add @reaatech/mcp-gateway-auditFeature Overview
- 8 event types —
auth.success,auth.failure,rate_limit.exceeded,allowlist.denied,tool.executed,cache.hit,cache.miss,upstream.error - Configurable severity —
low,medium,highper event type - Three storage backends — console (stdout), file (JSONL), and in-memory (queryable)
- Composite logging — fan out to multiple backends simultaneously
- Tamper-evident mode — SHA-256 chaining for integrity verification
- Query API — filter by tenant, event type, date range, limit, and success/failure
- Dual ESM/CJS output — works with
importandrequire
Quick Start
import {
createAuditEvent,
ConsoleAuditLogger,
FileAuditLogger,
} from "@reaatech/mcp-gateway-audit";
// Console logger (development)
const consoleLogger = new ConsoleAuditLogger();
consoleLogger.log(createAuditEvent("tool.executed", {
requestId: "req-abc123",
tenantId: "acme-corp",
userId: "user-456",
tool: "glean_search",
success: true,
durationMs: 234,
}));
// File logger (production)
const fileLogger = new FileAuditLogger({ path: "/var/log/gateway/audit.json" });
fileLogger.log(createAuditEvent("auth.failure", {
requestId: "req-def789",
metadata: { reason: "invalid_token" },
}));API Reference
Event Creation
| Export | Description |
|--------|-------------|
| createAuditEvent(type, data?) | Create a typed audit event with auto-generated ID, timestamp, and severity |
Loggers
| Export | Description |
|--------|-------------|
| ConsoleAuditLogger | Writes JSON events to console.log |
| FileAuditLogger | Appends JSONL events to a file |
| CompositeAuditLogger | Fans out to multiple logger backends |
| TamperEvidentLogger | Wraps a logger with SHA-256 chain integrity |
| AuditLogger | Type alias for the logger interface |
Storage
| Export | Description |
|--------|-------------|
| MemoryAuditStorage | In-memory store with query capabilities |
| FileAuditStorage | File-based store with append and query |
| createAuditQueryService(store) | Create a query service over any storage backend |
Integrity
| Export | Description |
|--------|-------------|
| computeEventHash(event) | Compute SHA-256 hash of an event |
| verifyAuditChain(events) | Verify the tamper-evident chain of events |
Event Types
| Export | Description |
|--------|-------------|
| getEventTypeConfig(type) | Get metadata for an event type |
| getEventSeverity(type) | Get severity for an event type |
| EVENT_TYPE_CONFIGS | Map of all event type configurations |
Event Types Reference
| Event Type | Severity | Description |
|------------|----------|-------------|
| auth.success | low | Successful authentication |
| auth.failure | medium | Failed authentication attempt |
| rate_limit.exceeded | medium | Rate limit exceeded |
| allowlist.denied | high | Tool access denied by allowlist |
| tool.executed | low | Tool execution completed |
| cache.hit | low | Cache served the response |
| cache.miss | low | Cache miss — upstream was called |
| upstream.error | high | Upstream server returned an error |
Types
| Type | Description |
|------|-------------|
| AuditEvent | { id, timestamp, eventType, severity, tenantId?, userId?, requestId?, tool?, success?, durationMs?, cacheHit?, upstream?, metadata? } |
| AuditEventType | String union of all event types |
| AuditSeverity | 'low' \| 'medium' \| 'high' |
| AuditStorageType | 'memory' \| 'file' |
| AuditQueryParams | { tenantId?, eventType?, startDate?, endDate?, limit?, success?, offset? } |
Audit Log Format
{
"id": "evt-abc123",
"timestamp": "2026-04-15T23:00:00Z",
"eventType": "tool.executed",
"severity": "low",
"tenantId": "acme-corp",
"userId": "user-123",
"requestId": "req-abc123",
"tool": "glean_search",
"success": true,
"durationMs": 234,
"cacheHit": false,
"upstream": "primary"
}Usage Patterns
Composite logging (console + file)
import { ConsoleAuditLogger, FileAuditLogger, CompositeAuditLogger } from "@reaatech/mcp-gateway-audit";
const logger = new CompositeAuditLogger([
new ConsoleAuditLogger(),
new FileAuditLogger({ path: "/var/log/gateway/audit.json" }),
]);
logger.log(createAuditEvent("auth.success", { tenantId: "acme-corp" }));
// → Written to both console and fileTamper-evident audit chain
import { FileAuditLogger, TamperEvidentLogger, verifyAuditChain } from "@reaatech/mcp-gateway-audit";
const baseLogger = new FileAuditLogger({ path: "./audit.json" });
const logger = new TamperEvidentLogger(baseLogger);
// Log events — each gets a chain hash referencing the previous event
logger.log(createAuditEvent("tool.executed", { tool: "glean_search" }));
logger.log(createAuditEvent("tool.executed", { tool: "serval_query" }));
// Verify integrity later
const events = loadAuditLog("./audit.json");
const result = verifyAuditChain(events);
console.log(result.valid, result.errors);Querying audit logs
import { MemoryAuditStorage, createAuditQueryService } from "@reaatech/mcp-gateway-audit";
const storage = new MemoryAuditStorage();
const query = createAuditQueryService(storage);
const results = query({
tenantId: "acme-corp",
eventType: "auth.failure",
startDate: new Date("2026-01-01"),
limit: 50,
});
console.log(`Found ${results.total} auth failures for acme-corp`);Fastify
Recording is framework-agnostic (recordAudit(ctx, decision, options)). Both the
Express middleware (auditMiddleware) and the Fastify plugin write through the
same core, and both default to a silent sink — nothing is written to stdout
(reserved for the MCP JSON-RPC stream) unless you supply a logger.
import Fastify from "fastify";
import { fastifyAuth } from "@reaatech/mcp-gateway-auth/fastify";
import { ConsoleAuditLogger } from "@reaatech/mcp-gateway-audit";
import { fastifyAudit } from "@reaatech/mcp-gateway-audit/fastify";
const app = Fastify();
await app.register(fastifyAuth);
await app.register(fastifyAudit, { logger: new ConsoleAuditLogger() });Use SilentAuditLogger (the default) on hosts that forbid stdout writes, or any
AuditLogger (FileAuditLogger, CompositeAuditLogger, custom). fastify is an
optional peer dependency.
Registration order: auth → rate-limit → allowlist → audit → cache —
register fastifyAudit after fastifyAllowlist and before fastifyCache.
Related Packages
- @reaatech/mcp-gateway-core — Audit event type definitions
- @reaatech/mcp-gateway-gateway — Full gateway server (integrates audit logging)
