Skip to main content
Glama
audit.ts2.62 kB
import { appendFile } from 'fs/promises'; import { getConfig, getOperatorInfo } from './config.js'; import { logger } from './logger.js'; type RiskLevel = 'high' | 'low'; type OperationType = 'plan' | 'execute' | 'query' | 'error'; interface AuditEntry { correlationId: string; timestamp: string; operatorEmail?: string; operatorName?: string; operationType: OperationType; command: string; riskLevel: RiskLevel; result: 'success' | 'failure' | 'pending'; metadata?: Record<string, unknown>; errorDetails?: string; } const MAX_ENTRIES = 100; const recentEntries: AuditEntry[] = []; export function generateCorrelationId(): string { return `az-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; } export async function logAudit(entry: Omit<AuditEntry, 'timestamp' | 'operatorEmail' | 'operatorName'>): Promise<void> { const config = getConfig(); const operator = getOperatorInfo(); const full: AuditEntry = { ...entry, timestamp: new Date().toISOString(), operatorEmail: operator.email, operatorName: operator.name, }; recentEntries.push(full); if (recentEntries.length > MAX_ENTRIES) recentEntries.shift(); logger.info('Audit entry', { correlationId: full.correlationId, operationType: full.operationType, command: full.command, riskLevel: full.riskLevel, result: full.result, operatorEmail: full.operatorEmail, }); if (config.enableAuditLog) { try { await appendFile(config.auditLogPath, JSON.stringify(full) + '\n', 'utf-8'); } catch (err) { logger.error('Audit log write failed', err instanceof Error ? err : new Error(String(err))); } } } export function getRecentAuditEntries(email?: string, limit = 20): AuditEntry[] { let entries = [...recentEntries].reverse(); if (email) entries = entries.filter(e => e.operatorEmail === email); return entries.slice(0, limit); } export function createAuditContext( command: string, riskLevel: RiskLevel, operationType: 'plan' | 'execute' | 'query' ): { correlationId: string; logSuccess: () => Promise<void>; logFailure: (error: string) => Promise<void> } { const correlationId = generateCorrelationId(); return { correlationId, logSuccess: () => logAudit({ correlationId, operationType, command, riskLevel, result: 'success' }), logFailure: (errorDetails: string) => logAudit({ correlationId, operationType, command, riskLevel, result: 'failure', errorDetails }), }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vedantparmar12/Azure-_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server