Daemon Management
The Daemon Management module provides cross-platform service generation and lifecycle management.
Overview
This module enables AIV agents to run as system services on:
- Linux - systemd unit files
- macOS - launchd plist files
- Windows - (planned)
Features
- 🔧 Automatic service file generation
- 🔄 Auto-restart on failure
- 📊 Resource limits (memory, CPU)
- 🔐 Security hardening options
- 📁 Working directory management
- 🌐 Environment variable support
Installation
typescript
import {
DaemonManager,
createDaemonManager,
DaemonConfig,
} from '@aiversum/aiv-agents/daemon';Basic Usage
Creating a Daemon Manager
typescript
const daemon = createDaemonManager({
name: 'aiv-soc-agent',
description: 'AIV SOC Security Agent',
command: '/usr/bin/node',
args: ['dist/agent.js'],
workingDirectory: '/opt/aiv/agents/soc',
user: 'aiv',
group: 'aiv',
});Generating Service Files
typescript
// Get the unit file content
const unitContent = daemon.generateUnit();
console.log(unitContent);
// Output for systemd:
// [Unit]
// Description=AIV SOC Security Agent
// After=network.target
//
// [Service]
// Type=simple
// User=aiv
// Group=aiv
// WorkingDirectory=/opt/aiv/agents/soc
// ExecStart=/usr/bin/node dist/agent.js
// Restart=always
// RestartSec=10
//
// [Install]
// WantedBy=multi-user.targetInstalling the Service
typescript
// Install to system (requires elevated permissions)
await daemon.install();
// Or get the install path
const path = daemon.getInstallPath();
// Linux: /etc/systemd/system/aiv-soc-agent.service
// macOS: ~/Library/LaunchAgents/ai.aiversum.aiv-soc-agent.plistConfiguration
Full Configuration Options
typescript
interface DaemonConfig {
// Required
name: string; // Service name (alphanumeric + hyphens)
description: string; // Human-readable description
command: string; // Executable path
// Optional
args?: string[]; // Command arguments
workingDirectory?: string; // Working directory
user?: string; // Run as user
group?: string; // Run as group
// Restart behavior
restart?: 'always' | 'on-failure' | 'no';
restartDelay?: number; // Seconds between restarts
// Resource limits
memoryLimit?: string; // e.g., '512M', '2G'
cpuQuota?: number; // Percentage (0-100)
// Environment
environment?: Record<string, string>;
environmentFile?: string; // Path to env file
// Logging
logPath?: string; // Custom log path
logLevel?: 'debug' | 'info' | 'warn' | 'error';
// Security (systemd only)
sandbox?: boolean; // Enable sandboxing
noNewPrivileges?: boolean; // Prevent privilege escalation
}Example: High-Security Configuration
typescript
const secureAgent = createDaemonManager({
name: 'aiv-secure-agent',
description: 'Hardened AIV Agent',
command: '/usr/bin/node',
args: ['agent.js'],
workingDirectory: '/opt/aiv/secure',
// Run as dedicated user
user: 'aiv-secure',
group: 'aiv-secure',
// Resource limits
memoryLimit: '1G',
cpuQuota: 50,
// Auto-restart
restart: 'on-failure',
restartDelay: 30,
// Security hardening
sandbox: true,
noNewPrivileges: true,
// Environment
environment: {
NODE_ENV: 'production',
LOG_LEVEL: 'info',
},
});Platform-Specific Features
systemd (Linux)
The module generates compliant systemd unit files with:
ini
[Unit]
Description=AIV Agent
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=aiv
Group=aiv
WorkingDirectory=/opt/aiv
# Command
ExecStart=/usr/bin/node agent.js
# Restart policy
Restart=always
RestartSec=10
# Resource limits
MemoryLimit=1G
CPUQuota=50%
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=aiv-agent
[Install]
WantedBy=multi-user.targetlaunchd (macOS)
Generates compliant plist files:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.aiversum.aiv-agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/node</string>
<string>agent.js</string>
</array>
<key>WorkingDirectory</key>
<string>/opt/aiv</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/aiv/agent.log</string>
<key>StandardErrorPath</key>
<string>/var/log/aiv/agent.error.log</string>
</dict>
</plist>Service Lifecycle
Start/Stop/Restart
typescript
// Start the service
await daemon.start();
// Stop the service
await daemon.stop();
// Restart the service
await daemon.restart();
// Check status
const status = await daemon.status();
console.log(status); // 'running' | 'stopped' | 'failed'Uninstall
typescript
// Remove the service
await daemon.uninstall();Events
The daemon manager emits events:
typescript
daemon.on('install', ({ path }) => {
console.log(`Service installed at ${path}`);
});
daemon.on('start', () => {
console.log('Service started');
});
daemon.on('stop', ({ reason }) => {
console.log(`Service stopped: ${reason}`);
});
daemon.on('error', ({ error }) => {
console.error('Service error:', error);
});Security Considerations
Permissions
- Service files are created with
0o644permissions - Environment files should be
0o600 - Working directories should be owned by the service user
User Isolation
Always run services as dedicated non-root users:
bash
# Create dedicated user
sudo useradd -r -s /bin/false aiv-agent
# Set ownership
sudo chown -R aiv-agent:aiv-agent /opt/aiv/agentSandboxing (systemd)
Enable sandboxing for maximum isolation:
typescript
const sandboxed = createDaemonManager({
// ...
sandbox: true,
noNewPrivileges: true,
});This adds protections:
ProtectSystem=strict- Read-only /usr, /boot, /etcProtectHome=true- No access to /homePrivateTmp=true- Isolated /tmpNoNewPrivileges=true- Cannot gain privileges
API Reference
See the DaemonManager API Reference for complete documentation.
Testing
bash
# Run daemon module tests
npm test -- --grep "daemon"
# Test count: 99 tests