Skip to main content
Glama
security-manager.ts•2.86 kB
/** * Security manager for policy enforcement */ import * as path from "path"; import { ISecurityManager } from "../interfaces"; import { SecurityPolicy } from "../types"; import { PathValidationError, RateLimitError } from "../errors"; /** * Security manager implementation */ export class SecurityManager implements ISecurityManager { private policy: SecurityPolicy; private captureCount: Map<string, number[]> = new Map(); constructor(policy?: Partial<SecurityPolicy>) { this.policy = { allowedDirectories: policy?.allowedDirectories || [process.cwd()], blockedWindowPatterns: policy?.blockedWindowPatterns || [], maxCapturesPerMinute: policy?.maxCapturesPerMinute || 60, enableAuditLog: policy?.enableAuditLog !== undefined ? policy.enableAuditLog : true, }; } /** * Validate a file path against security policies */ validatePath(filePath: string): void { const resolved = path.resolve(filePath); // Check for path traversal if (resolved.includes("..")) { throw new PathValidationError("Path traversal detected", { path: filePath, }); } // Check allowed directories const allowed = this.policy.allowedDirectories.some((dir) => { const resolvedDir = path.resolve(dir); return resolved.startsWith(resolvedDir); }); if (!allowed) { throw new PathValidationError("Path outside allowed directories", { path: filePath, allowedDirectories: this.policy.allowedDirectories, }); } } /** * Check rate limit for an agent */ checkRateLimit(agentId: string): void { const now = Date.now(); const captures = this.captureCount.get(agentId) || []; // Remove captures older than 1 minute const recent = captures.filter((t) => now - t < 60000); if (recent.length >= this.policy.maxCapturesPerMinute) { throw new RateLimitError("Rate limit exceeded", { agentId, limit: this.policy.maxCapturesPerMinute, current: recent.length, }); } recent.push(now); this.captureCount.set(agentId, recent); } /** * Log an audit entry */ auditLog(operation: string, params: any, result: any): void { if (this.policy.enableAuditLog) { console.log( JSON.stringify({ timestamp: new Date().toISOString(), operation, params, result: result.status || "unknown", }) ); } } /** * Load security policy from configuration */ loadPolicy(config: SecurityPolicy): void { this.policy = config; } /** * Get current security policy */ getPolicy(): SecurityPolicy { return { ...this.policy, allowedDirectories: [...this.policy.allowedDirectories], blockedWindowPatterns: [...this.policy.blockedWindowPatterns], }; } }

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/Digital-Defiance/mcp-screenshot'

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