Skip to content

Security

Haveapp1 edited this page Aug 22, 2025 · 1 revision

Security

Security best practices and guidelines for Agentwise deployment and usage.

Overview

Security is a critical consideration when using Agentwise, especially for enterprise applications and proprietary projects. This guide covers comprehensive security practices, threat mitigation, and compliance considerations.

Security Architecture

Multi-Layer Security Model

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            Application Security Layer            β”‚  ← Input validation, sanitization
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚         Authentication & Authorization        β”‚  ← API keys, JWT, RBAC
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚            Network Security Layer             β”‚  ← TLS, firewall rules
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚              Data Protection                 β”‚  ← Encryption at rest/transit
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚            Infrastructure Security           β”‚  ← Container security, OS hardening
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Authentication and Authorization

API Key Management

// Secure API key configuration
{
  "security": {
    "apiKeys": {
      "required": true,
      "rotation": "30d",
      "minLength": 32,
      "algorithm": "HS256"
    }
  }
}

Best Practices:

  • Store API keys in environment variables, never in code
  • Rotate keys regularly (recommended: monthly)
  • Use different keys for different environments
  • Implement key rotation without service interruption
# Secure API key management
export AGENTWISE_API_KEY="$(cat /secure/path/api-key.txt)"
export CLAUDE_API_KEY="$(cat /secure/path/claude-key.txt)"

# Key rotation script
#!/bin/bash
NEW_KEY=$(generate_api_key)
echo $NEW_KEY > /secure/path/new-api-key.txt
# Test with new key
if test_api_key $NEW_KEY; then
  mv /secure/path/new-api-key.txt /secure/path/api-key.txt
  restart_agentwise_service
fi

Role-Based Access Control (RBAC)

// RBAC configuration
{
  "security": {
    "roles": {
      "admin": {
        "permissions": [
          "agents:*",
          "projects:*",
          "config:*",
          "users:*"
        ]
      },
      "developer": {
        "permissions": [
          "projects:create",
          "projects:read",
          "agents:read",
          "tasks:*"
        ]
      },
      "viewer": {
        "permissions": [
          "projects:read",
          "agents:read",
          "tasks:read"
        ]
      }
    },
    "users": {
      "john.doe@company.com": { "role": "developer" },
      "admin@company.com": { "role": "admin" }
    }
  }
}

Data Protection

Encryption

At Rest:

{
  "security": {
    "encryption": {
      "algorithm": "AES-256-GCM",
      "keyRotation": "90d",
      "targets": [
        "configuration_files",
        "cached_data",
        "project_artifacts",
        "logs"
      ]
    }
  }
}

In Transit:

  • All API communications use TLS 1.3
  • Certificate pinning for critical connections
  • Perfect Forward Secrecy (PFS) enabled

Data Sanitization

class DataSanitizer {
  sanitizeInput(data) {
    // Remove sensitive patterns
    const sanitized = data
      .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[EMAIL]')
      .replace(/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g, '[CARD]')
      .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '[SSN]')
      .replace(/sk-[a-zA-Z0-9]{48}/g, '[API_KEY]');
    
    return sanitized;
  }
  
  sanitizeForLogging(data) {
    return {
      ...data,
      apiKey: '[REDACTED]',
      password: '[REDACTED]',
      token: '[REDACTED]'
    };
  }
}

File System Security

Access Control

{
  "security": {
    "fileAccess": {
      "allowedPaths": [
        "/app/projects/**",
        "/app/templates/**",
        "/app/public/**"
      ],
      "deniedPaths": [
        "/etc/**",
        "/root/**",
        "**/.env",
        "**/.git/**",
        "**/node_modules/**",
        "**/*.key",
        "**/*.pem"
      ],
      "maxFileSize": "10MB",
      "allowedExtensions": [
        ".js", ".ts", ".jsx", ".tsx",
        ".py", ".java", ".go",
        ".json", ".yaml", ".md",
        ".css", ".scss", ".html"
      ]
    }
  }
}

File Operations Security

class SecureFileOperations {
  async readFile(filePath) {
    // Validate path
    if (!this.isPathAllowed(filePath)) {
      throw new SecurityError(`Access denied: ${filePath}`);
    }
    
    // Prevent directory traversal
    const resolvedPath = path.resolve(filePath);
    if (!resolvedPath.startsWith(this.getAllowedBasePath())) {
      throw new SecurityError('Directory traversal attempt detected');
    }
    
    // Check file size
    const stats = await fs.stat(resolvedPath);
    if (stats.size > this.maxFileSize) {
      throw new SecurityError('File too large');
    }
    
    return await fs.readFile(resolvedPath, 'utf8');
  }
}

Network Security

TLS Configuration

// Secure server configuration
const tlsOptions = {
  minVersion: 'TLSv1.3',
  ciphers: [
    'TLS_AES_256_GCM_SHA384',
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256'
  ],
  honorCipherOrder: true,
  secureProtocol: 'TLS_method'
};

const server = https.createServer(tlsOptions, app);

Firewall Rules

# UFW firewall configuration
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (change port as needed)
sudo ufw allow 22/tcp

# Allow Agentwise API (if exposed)
sudo ufw allow 3001/tcp

# Allow specific outbound connections only
sudo ufw allow out 443/tcp  # HTTPS
sudo ufw allow out 80/tcp   # HTTP
sudo ufw allow out 53/tcp   # DNS

sudo ufw enable

Container Security

Docker Security

# Secure Dockerfile
FROM node:18-alpine AS builder

# Create non-root user
RUN addgroup -g 1001 -S agentwise && \
    adduser -S agentwise -u 1001 -G agentwise

# Set working directory
WORKDIR /app

# Copy and install dependencies
COPY package*.json ./
RUN npm ci --only=production && \
    npm cache clean --force

# Copy application code
COPY --chown=agentwise:agentwise . .

# Remove unnecessary packages
RUN apk del build-dependencies

# Switch to non-root user
USER agentwise

# Expose port
EXPOSE 3001

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js

# Start application
CMD ["npm", "start"]

Kubernetes Security

apiVersion: v1
kind: SecurityContext
metadata:
  name: agentwise-security-context
spec:
  runAsNonRoot: true
  runAsUser: 1001
  runAsGroup: 1001
  fsGroup: 1001
  seccompProfile:
    type: RuntimeDefault
  capabilities:
    drop:
      - ALL
    add:
      - NET_BIND_SERVICE
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: agentwise-network-policy
spec:
  podSelector:
    matchLabels:
      app: agentwise
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: authorized-namespace
    ports:
    - protocol: TCP
      port: 3001
  egress:
  - to: []
    ports:
    - protocol: TCP
      port: 443  # HTTPS only

Input Validation and Sanitization

Request Validation

const joi = require('joi');

const taskSchema = joi.object({
  description: joi.string().max(1000).required(),
  type: joi.string().valid('frontend', 'backend', 'database', 'testing').required(),
  requirements: joi.object().max(10).required(),
  priority: joi.string().valid('low', 'medium', 'high').default('medium'),
  tokenBudget: joi.number().min(1000).max(100000).default(5000)
});

app.post('/api/v1/tasks', async (req, res) => {
  try {
    const { error, value } = taskSchema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    
    // Process validated input
    const result = await taskService.createTask(value);
    res.json(result);
  } catch (err) {
    logger.error('Task creation failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});

Audit Logging

Comprehensive Logging

class SecurityAuditLogger {
  constructor() {
    this.logger = winston.createLogger({
      level: 'info',
      format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.errors({ stack: true }),
        winston.format.json()
      ),
      transports: [
        new winston.transports.File({ filename: 'security-audit.log' }),
        new winston.transports.Console()
      ]
    });
  }
  
  logAuthentication(event, userId, success, details = {}) {
    this.logger.info('Authentication Event', {
      event,
      userId,
      success,
      timestamp: new Date().toISOString(),
      ip: details.ip,
      userAgent: details.userAgent
    });
  }
  
  logFileAccess(event, userId, filePath, success, details = {}) {
    this.logger.info('File Access Event', {
      event,
      userId,
      filePath: this.sanitizePath(filePath),
      success,
      timestamp: new Date().toISOString(),
      operation: details.operation
    });
  }
  
  logSecurityViolation(violation, userId, details = {}) {
    this.logger.warn('Security Violation', {
      violation,
      userId,
      timestamp: new Date().toISOString(),
      details: this.sanitizeDetails(details)
    });
  }
}

Threat Detection and Prevention

Rate Limiting

const rateLimit = require('express-rate-limit');

// API rate limiting
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP',
  standardHeaders: true,
  legacyHeaders: false
});

// Stricter limits for sensitive endpoints
const strictLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 5, // 5 requests per minute
  skipSuccessfulRequests: true
});

app.use('/api/', apiLimiter);
app.use('/api/v1/auth/', strictLimiter);
app.use('/api/v1/config/', strictLimiter);

Intrusion Detection

class IntrusionDetectionSystem {
  constructor() {
    this.suspiciousPatterns = [
      /\.\.\//g,  // Directory traversal
      /<script/gi, // XSS attempts
      /union.*select/gi, // SQL injection
      /eval\(/gi, // Code injection
      /exec\(/gi  // Command injection
    ];
    
    this.failedAttempts = new Map();
  }
  
  detectThreats(request) {
    const threats = [];
    
    // Check for suspicious patterns
    const payload = JSON.stringify(request.body);
    for (const pattern of this.suspiciousPatterns) {
      if (pattern.test(payload)) {
        threats.push({
          type: 'malicious_payload',
          pattern: pattern.source,
          severity: 'high'
        });
      }
    }
    
    // Check for brute force
    const ip = request.ip;
    const attempts = this.failedAttempts.get(ip) || 0;
    if (attempts > 10) {
      threats.push({
        type: 'brute_force',
        attempts,
        severity: 'critical'
      });
    }
    
    return threats;
  }
}

Secure Configuration Management

Environment Variable Management

# .env.production (example - use secret management in production)
NODE_ENV=production
AGENTWISE_API_KEY="${AGENTWISE_API_KEY}"
CLAUDE_API_KEY="${CLAUDE_API_KEY}"
DATABASE_URL="${DATABASE_URL}"
REDIS_URL="${REDIS_URL}"
JWT_SECRET="${JWT_SECRET}"
ENCRYPTION_KEY="${ENCRYPTION_KEY}"

# Security headers
HSTS_MAX_AGE=31536000
CSP_POLICY="default-src 'self'; script-src 'self' 'unsafe-inline'"
X_FRAME_OPTIONS="DENY"

Secrets Management

// Using HashiCorp Vault
const vault = require('node-vault')({
  endpoint: process.env.VAULT_ENDPOINT,
  token: process.env.VAULT_TOKEN
});

class SecretsManager {
  async getSecret(path) {
    try {
      const result = await vault.read(path);
      return result.data;
    } catch (error) {
      logger.error('Failed to retrieve secret', { path, error: error.message });
      throw new Error('Secret retrieval failed');
    }
  }
  
  async rotateSecret(path, newValue) {
    try {
      await vault.write(path, { value: newValue });
      logger.info('Secret rotated successfully', { path });
    } catch (error) {
      logger.error('Failed to rotate secret', { path, error: error.message });
      throw new Error('Secret rotation failed');
    }
  }
}

Compliance and Standards

SOC 2 Compliance

// SOC 2 controls implementation
const soc2Controls = {
  CC6_1: 'Logical access security measures',
  CC6_2: 'User access provisioning and deprovisioning',
  CC6_3: 'User access authentication',
  CC6_7: 'Data transmission security',
  CC6_8: 'Data disposal'
};

class ComplianceManager {
  async auditAccessControls() {
    // Implement access control auditing
    const users = await this.getAllUsers();
    const violations = [];
    
    for (const user of users) {
      if (!user.lastLogin || Date.now() - user.lastLogin > 90 * 24 * 60 * 60 * 1000) {
        violations.push({
          type: 'inactive_user',
          user: user.id,
          lastLogin: user.lastLogin
        });
      }
    }
    
    return violations;
  }
}

Incident Response

Security Incident Handling

class IncidentResponse {
  async handleSecurityIncident(incident) {
    // Log incident
    securityLogger.logSecurityViolation(incident.type, incident.userId, incident);
    
    // Immediate response based on severity
    switch (incident.severity) {
      case 'critical':
        await this.lockUserAccount(incident.userId);
        await this.alertSecurityTeam(incident);
        await this.initiateForensics(incident);
        break;
        
      case 'high':
        await this.requireReauthentication(incident.userId);
        await this.alertSecurityTeam(incident);
        break;
        
      case 'medium':
        await this.logForReview(incident);
        break;
    }
  }
  
  async generateIncidentReport(incidentId) {
    const incident = await this.getIncident(incidentId);
    
    return {
      id: incident.id,
      timestamp: incident.timestamp,
      type: incident.type,
      severity: incident.severity,
      affectedSystems: incident.affectedSystems,
      responseActions: incident.responseActions,
      resolution: incident.resolution,
      lessonsLearned: incident.lessonsLearned
    };
  }
}

Security Monitoring

Real-time Security Dashboard

class SecurityDashboard {
  getSecurityMetrics() {
    return {
      activeThreats: this.getActiveThreats(),
      failedLogins: this.getFailedLoginCount(),
      suspiciousActivity: this.getSuspiciousActivityCount(),
      systemHealth: this.getSystemHealthStatus(),
      complianceStatus: this.getComplianceStatus()
    };
  }
  
  async generateSecurityReport() {
    const metrics = this.getSecurityMetrics();
    const incidents = await this.getRecentIncidents();
    const vulnerabilities = await this.getVulnerabilities();
    
    return {
      summary: metrics,
      incidents,
      vulnerabilities,
      recommendations: this.getSecurityRecommendations()
    };
  }
}

Security Best Practices Checklist

Development

  • All API keys stored in environment variables
  • Input validation on all endpoints
  • Output sanitization implemented
  • Rate limiting configured
  • HTTPS enforced everywhere
  • Security headers implemented
  • Dependency vulnerability scanning enabled
  • Code security reviews conducted

Deployment

  • Non-root user containers
  • Network policies configured
  • Secrets management implemented
  • Audit logging enabled
  • Monitoring and alerting configured
  • Backup and recovery tested
  • Incident response plan documented
  • Security training completed

Operations

  • Regular security assessments
  • Vulnerability patching schedule
  • Access review quarterly
  • Log monitoring active
  • Incident response tested
  • Compliance audits current
  • Security metrics tracked
  • Team security training updated

For more information, see Configuration, Privacy, or Troubleshooting.

Navigation

πŸš€ Getting Started

πŸ“š Documentation

πŸ› οΈ Development

🎯 Advanced Topics

πŸ“– Resources

βš–οΈ Legal

πŸ”— Quick Links


Support

  • Discord: @vibecodingwithphil
  • GitHub: @VibeCodingWithPhil
Clone this wiki locally