Complete implementation code for ultra-low-cost AI automation. Start with FREE rules engine, add strategic AI where it provides maximum value.
70% automation with zero AI costs using pure PHP logic
Routes requests to appropriate processing tier based on complexity
rulesEngine = $rulesEngine;
$this->aiService = $aiService;
$this->cache = $cache;
}
public function processEvidenceRequest(string $questionId, array $evidenceData): array
{
$question = AssessmentEventsQuestion::find($questionId);
// Check cache first
$cacheKey = $this->generateCacheKey($question->control_id, $evidenceData);
if ($cached = $this->cache->get($cacheKey)) {
$this->logCostSaving('cache_hit', 0);
return $cached;
}
// Assess complexity to determine processing tier
$complexity = $this->assessComplexity($question, $evidenceData);
if ($complexity <= 0.3) {
// Tier 1: FREE Rules Engine (70% of requests)
$result = $this->rulesEngine->processEvidence($question, $evidenceData);
$this->logProcessing('rules_engine', 0);
} elseif ($complexity <= 0.7 && $this->hasAIBudget()) {
// Tier 2: Basic AI Analysis (20% of requests)
$result = $this->aiService->basicAnalysis($question, $evidenceData);
$this->logProcessing('basic_ai', $this->getBasicAICost());
} elseif ($this->hasAIBudget()) {
// Tier 3: Advanced AI (10% of requests)
$result = $this->aiService->advancedAnalysis($question, $evidenceData);
$this->logProcessing('advanced_ai', $this->getAdvancedAICost());
} else {
// Fallback to rules if AI budget exceeded
$result = $this->rulesEngine->processEvidence($question, $evidenceData);
$result['ai_budget_exceeded'] = true;
$this->logProcessing('rules_fallback', 0);
}
// Cache result for reuse
$this->cache->put($cacheKey, $result, 3600); // 1 hour cache
return $result;
}
private function assessComplexity(AssessmentEventsQuestion $question, array $evidenceData): float
{
$complexity = 0.0;
// Simple data types = low complexity
if ($this->isSimpleDataValidation($evidenceData)) {
$complexity += 0.1;
}
// Multiple data sources = medium complexity
if (count($evidenceData) > 3) {
$complexity += 0.2;
}
// Complex controls require AI
$aiRequiredControls = ['risk_analysis', 'policy_review', 'anomaly_detection'];
if (in_array($question->control_id, $aiRequiredControls)) {
$complexity += 0.5;
}
// Natural language requirements = high complexity
if ($this->requiresNaturalLanguage($question)) {
$complexity += 0.4;
}
return min(1.0, $complexity);
}
private function generateCacheKey(string $controlId, array $evidenceData): string
{
return 'compliance_analysis_' . $controlId . '_' . md5(json_encode($evidenceData));
}
private function hasAIBudget(): bool
{
$dailySpent = $this->getDailyAISpend();
$dailyBudget = config('ai.daily_budget', 50); // $50 daily = $1500/month
return $dailySpent < $dailyBudget;
}
}
?>
Handles 70% of compliance validation using pure PHP logic - NO AI COSTS
rulesets = [
'user_access' => new UserAccessRules(),
'asset_inventory' => new AssetInventoryRules(),
'policy_compliance' => new PolicyComplianceRules(),
'security_config' => new SecurityConfigRules(),
];
}
public function processEvidence(AssessmentEventsQuestion $question, array $evidenceData): array
{
$controlType = $this->determineControlType($question->control_id);
$ruleset = $this->rulesets[$controlType] ?? $this->rulesets['policy_compliance'];
// Execute rules-based analysis
$analysis = $ruleset->analyze($evidenceData);
// Calculate compliance score using rules
$score = $this->calculateComplianceScore($analysis);
// Generate human-readable summary
$summary = $this->generateRulesSummary($analysis, $score);
return [
'processing_tier' => 'rules_engine',
'control_id' => $question->control_id,
'compliance_score' => $score,
'analysis' => $analysis,
'summary' => $summary,
'conformity_mark' => $score >= 80 ? 'met' : 'not met',
'recommendations' => $ruleset->getRecommendations($analysis),
'cost' => 0.00,
'processing_time' => microtime(true) - LARAVEL_START
];
}
private function determineControlType(string $controlId): string
{
$patterns = [
'user_access' => ['CC6.1', 'A.9.2', 'AC-', 'IA-'],
'asset_inventory' => ['A.8.1', 'CM-8', 'inventory'],
'security_config' => ['CC6.7', 'A.12.6', 'SI-', 'SC-'],
'policy_compliance' => ['CC2.1', 'A.5.1', 'policy', 'procedure']
];
foreach ($patterns as $type => $identifiers) {
foreach ($identifiers as $identifier) {
if (stripos($controlId, $identifier) !== false) {
return $type;
}
}
}
return 'policy_compliance'; // Default
}
private function calculateComplianceScore(array $analysis): int
{
$score = 100;
$deductions = 0;
// Apply rule-based deductions
foreach ($analysis['violations'] as $violation) {
$deductions += $violation['severity'] * 10; // Critical = 30, High = 20, Medium = 10
}
foreach ($analysis['warnings'] as $warning) {
$deductions += 5; // Each warning = 5 points
}
return max(0, $score - $deductions);
}
}
// app/Services/RulesEngine/Rules/UserAccessRules.php
namespace App\Services\RulesEngine\Rules;
class UserAccessRules implements ComplianceRuleInterface
{
public function analyze(array $evidenceData): array
{
$users = $evidenceData['users'] ?? [];
$violations = [];
$warnings = [];
// Rule 1: Check for inactive users (SOC 2 CC6.1)
$inactiveUsers = $this->findInactiveUsers($users);
if (count($inactiveUsers) > 0) {
$violations[] = [
'rule' => 'inactive_users_found',
'severity' => 2, // High severity
'count' => count($inactiveUsers),
'description' => count($inactiveUsers) . ' inactive users found with access'
];
}
// Rule 2: Check privileged user ratio
$privilegedUsers = $this->findPrivilegedUsers($users);
$privilegedRatio = count($privilegedUsers) / count($users);
if ($privilegedRatio > 0.3) { // More than 30% privileged
$warnings[] = [
'rule' => 'excessive_privileged_users',
'ratio' => round($privilegedRatio * 100, 1) . '%',
'description' => 'High percentage of users with privileged access'
];
}
// Rule 3: Check for users without recent password changes
$stalePasswords = $this->findStalePasswords($users);
if (count($stalePasswords) > 0) {
$violations[] = [
'rule' => 'stale_passwords',
'severity' => 2,
'count' => count($stalePasswords),
'description' => 'Users with passwords older than 90 days'
];
}
return [
'total_users' => count($users),
'active_users' => count($users) - count($inactiveUsers),
'privileged_users' => count($privilegedUsers),
'violations' => $violations,
'warnings' => $warnings,
'metrics' => [
'inactive_ratio' => round(count($inactiveUsers) / count($users) * 100, 1),
'privileged_ratio' => round($privilegedRatio * 100, 1)
]
];
}
private function findInactiveUsers(array $users): array
{
$cutoffDate = now()->subDays(90);
return array_filter($users, function($user) use ($cutoffDate) {
$lastLogin = isset($user['last_login']) ?
Carbon::parse($user['last_login']) :
Carbon::parse($user['created_at']);
return $lastLogin->lt($cutoffDate);
});
}
private function findPrivilegedUsers(array $users): array
{
$privilegedRoles = ['admin', 'administrator', 'root', 'super', 'owner'];
return array_filter($users, function($user) use ($privilegedRoles) {
$userRole = strtolower($user['role'] ?? '');
return in_array($userRole, $privilegedRoles) ||
($user['is_admin'] ?? false);
});
}
public function getRecommendations(array $analysis): array
{
$recommendations = [];
foreach ($analysis['violations'] as $violation) {
switch ($violation['rule']) {
case 'inactive_users_found':
$recommendations[] = "Disable or remove {$violation['count']} inactive user accounts";
break;
case 'stale_passwords':
$recommendations[] = "Enforce password reset for {$violation['count']} users with old passwords";
break;
}
}
foreach ($analysis['warnings'] as $warning) {
if ($warning['rule'] === 'excessive_privileged_users') {
$recommendations[] = "Review privileged access - consider least privilege principle";
}
}
return $recommendations;
}
}
?>
Automated asset collection and deduplication using rules-based logic
deduplicateAssets($assets);
// Rule 1: Check asset coverage by type
$assetTypes = $this->categorizeAssets($consolidatedAssets);
if (empty($assetTypes['hardware'])) {
$violations[] = [
'rule' => 'missing_hardware_inventory',
'severity' => 3, // Critical
'description' => 'No hardware assets found in inventory'
];
}
// Rule 2: Check for assets without recent updates
$staleAssets = $this->findStaleAssets($consolidatedAssets);
if (count($staleAssets) > 0) {
$warnings[] = [
'rule' => 'stale_asset_data',
'count' => count($staleAssets),
'description' => 'Assets with data older than 30 days'
];
}
// Rule 3: Validate required asset fields
$incompleteAssets = $this->validateAssetFields($consolidatedAssets);
if (count($incompleteAssets) > 0) {
$violations[] = [
'rule' => 'incomplete_asset_data',
'severity' => 1, // Medium
'count' => count($incompleteAssets),
'description' => 'Assets missing required fields (name, type, owner)'
];
}
return [
'total_assets' => count($consolidatedAssets),
'asset_types' => $assetTypes,
'coverage_score' => $this->calculateCoverageScore($assetTypes),
'violations' => $violations,
'warnings' => $warnings,
'consolidated_assets' => $consolidatedAssets,
'deduplication_stats' => [
'original_count' => count($assets),
'deduplicated_count' => count($consolidatedAssets),
'duplicates_removed' => count($assets) - count($consolidatedAssets)
]
];
}
private function deduplicateAssets(array $assets): array
{
$seen = [];
$result = [];
foreach ($assets as $asset) {
// Generate unique key based on multiple identifiers
$keys = [
$asset['serial_number'] ?? null,
$asset['mac_address'] ?? null,
strtolower($asset['name'] ?? ''),
$asset['ip_address'] ?? null
];
// Create composite key from non-null identifiers
$compositeKey = implode('|', array_filter($keys));
if ($compositeKey && !isset($seen[$compositeKey])) {
$seen[$compositeKey] = true;
$result[] = $asset;
} elseif (!$compositeKey) {
// Keep assets without identifiers but flag them
$asset['missing_identifiers'] = true;
$result[] = $asset;
}
}
return $result;
}
private function categorizeAssets(array $assets): array
{
$categories = [
'hardware' => [],
'software' => [],
'network' => [],
'virtual' => [],
'other' => []
];
foreach ($assets as $asset) {
$type = strtolower($asset['type'] ?? 'other');
$category = $this->mapAssetCategory($type);
$categories[$category][] = $asset;
}
return array_map('count', $categories);
}
private function mapAssetCategory(string $type): string
{
$mappings = [
'server' => 'hardware',
'workstation' => 'hardware',
'laptop' => 'hardware',
'desktop' => 'hardware',
'router' => 'network',
'switch' => 'network',
'firewall' => 'network',
'application' => 'software',
'license' => 'software',
'vm' => 'virtual',
'container' => 'virtual'
];
foreach ($mappings as $pattern => $category) {
if (stripos($type, $pattern) !== false) {
return $category;
}
}
return 'other';
}
private function calculateCoverageScore(array $assetTypes): int
{
$score = 0;
$weights = [
'hardware' => 30,
'software' => 25,
'network' => 25,
'virtual' => 15,
'other' => 5
];
foreach ($assetTypes as $type => $count) {
if ($count > 0) {
$score += $weights[$type] ?? 0;
}
}
return $score;
}
public function getRecommendations(array $analysis): array
{
$recommendations = [];
foreach ($analysis['violations'] as $violation) {
switch ($violation['rule']) {
case 'missing_hardware_inventory':
$recommendations[] = "Configure hardware asset discovery via ConnectWise/RMM integration";
break;
case 'incomplete_asset_data':
$recommendations[] = "Complete asset records - add missing names, types, and owners";
break;
}
}
if ($analysis['coverage_score'] < 80) {
$recommendations[] = "Improve asset coverage by enabling additional integrations";
}
return $recommendations;
}
}
?>
With just this FREE rules engine, you achieve:
Add 20% more automation with $500/month AI budget
Strategic AI usage for complex analysis that rules can't handle
openai = $openai;
$this->costTracker = $costTracker;
}
public function basicAnalysis(AssessmentEventsQuestion $question, array $evidenceData): array
{
// Use GPT-3.5 Turbo for cost-effective analysis
$prompt = $this->buildBasicAnalysisPrompt($question, $evidenceData);
$response = $this->openai->chat()->create([
'model' => 'gpt-3.5-turbo',
'messages' => [
['role' => 'system', 'content' => $this->getSystemPrompt()],
['role' => 'user', 'content' => $prompt]
],
'max_tokens' => 500, // Keep token usage low
'temperature' => 0.1 // Consistent results
]);
$cost = $this->calculateCost($response->usage->totalTokens, 'gpt-3.5-turbo');
$this->costTracker->logUsage('basic_analysis', $cost, $response->usage->totalTokens);
$analysis = json_decode($response->choices[0]->message->content, true);
return [
'processing_tier' => 'basic_ai',
'control_id' => $question->control_id,
'compliance_score' => $analysis['score'] ?? 0,
'summary' => $analysis['summary'] ?? '',
'conformity_mark' => ($analysis['score'] ?? 0) >= 80 ? 'met' : 'not met',
'recommendations' => $analysis['recommendations'] ?? [],
'ai_confidence' => $analysis['confidence'] ?? 0.8,
'cost' => $cost,
'tokens_used' => $response->usage->totalTokens
];
}
private function buildBasicAnalysisPrompt(AssessmentEventsQuestion $question, array $evidenceData): string
{
return "Analyze this compliance evidence for control {$question->control_id}:
Evidence Data: " . json_encode($evidenceData, JSON_PRETTY_PRINT) . "
Provide analysis in this JSON format:
{
\"score\": [0-100 compliance score],
\"summary\": \"[2-3 sentence summary]\",
\"recommendations\": [\"[actionable recommendation 1]\", \"[recommendation 2]\"],
\"confidence\": [0.0-1.0 confidence level],
\"key_findings\": [\"[finding 1]\", \"[finding 2]\"]
}
Focus on:
1. Compliance gaps and violations
2. Risk level assessment
3. Specific actionable recommendations
4. Evidence completeness";
}
private function getSystemPrompt(): string
{
return "You are a compliance analysis expert. Analyze evidence data and provide structured compliance assessments. Be concise, accurate, and focus on actionable insights. Always return valid JSON.";
}
public function advancedAnalysis(AssessmentEventsQuestion $question, array $evidenceData): array
{
// Use GPT-4 for complex reasoning (limited usage)
$prompt = $this->buildAdvancedAnalysisPrompt($question, $evidenceData);
$response = $this->openai->chat()->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'system', 'content' => $this->getAdvancedSystemPrompt()],
['role' => 'user', 'content' => $prompt]
],
'max_tokens' => 1000,
'temperature' => 0.2
]);
$cost = $this->calculateCost($response->usage->totalTokens, 'gpt-4');
$this->costTracker->logUsage('advanced_analysis', $cost, $response->usage->totalTokens);
$analysis = json_decode($response->choices[0]->message->content, true);
return [
'processing_tier' => 'advanced_ai',
'control_id' => $question->control_id,
'compliance_score' => $analysis['score'] ?? 0,
'executive_summary' => $analysis['executive_summary'] ?? '',
'detailed_analysis' => $analysis['detailed_analysis'] ?? '',
'risk_assessment' => $analysis['risk_assessment'] ?? '',
'conformity_mark' => ($analysis['score'] ?? 0) >= 80 ? 'met' : 'not met',
'recommendations' => $analysis['recommendations'] ?? [],
'strategic_insights' => $analysis['strategic_insights'] ?? [],
'ai_confidence' => $analysis['confidence'] ?? 0.9,
'cost' => $cost,
'tokens_used' => $response->usage->totalTokens
];
}
private function calculateCost(int $tokens, string $model): float
{
$pricing = [
'gpt-3.5-turbo' => 0.002, // $0.002 per 1K tokens
'gpt-4' => 0.03 // $0.03 per 1K tokens
];
return ($tokens / 1000) * ($pricing[$model] ?? 0.002);
}
}
// app/Services/AI/CostMonitoring/AICostTracker.php
namespace App\Services\AI\CostMonitoring;
use Illuminate\Support\Facades\{DB, Log, Cache};
class AICostTracker
{
public function logUsage(string $operation, float $cost, int $tokens): void
{
DB::table('ai_usage_logs')->insert([
'operation' => $operation,
'cost' => $cost,
'tokens' => $tokens,
'date' => now()->toDateString(),
'created_at' => now()
]);
// Update daily totals in cache
$dailyKey = 'ai_daily_cost_' . now()->toDateString();
$dailyCost = Cache::get($dailyKey, 0) + $cost;
Cache::put($dailyKey, $dailyCost, 86400); // 24 hours
// Check budget alerts
$this->checkBudgetAlerts($dailyCost);
}
private function checkBudgetAlerts(float $dailyCost): void
{
$dailyBudget = config('ai.daily_budget', 50); // $50/day = $1500/month
if ($dailyCost > $dailyBudget * 0.8) { // 80% threshold
Log::warning("AI daily budget at 80%: ${dailyCost}/${dailyBudget}");
// Send alert to admin
\Mail::to(config('ai.admin_email'))
->send(new \App\Mail\AIBudgetAlert($dailyCost, $dailyBudget));
}
if ($dailyCost > $dailyBudget) {
Log::error("AI daily budget exceeded: ${dailyCost}/${dailyBudget}");
// Disable AI processing for rest of day
Cache::put('ai_budget_exceeded_' . now()->toDateString(), true, 86400);
}
}
}
?>
Add these tables to support AI cost tracking and caching
id();
$table->string('operation'); // basic_analysis, advanced_analysis, etc.
$table->decimal('cost', 8, 4); // Cost in dollars
$table->integer('tokens'); // Tokens used
$table->string('model')->nullable(); // gpt-3.5-turbo, gpt-4
$table->date('date'); // For daily budget tracking
$table->timestamps();
$table->index(['date', 'operation']);
$table->index('date');
});
}
public function down()
{
Schema::dropIfExists('ai_usage_logs');
}
}
// database/migrations/create_compliance_cache_table.php
class CreateComplianceCacheTable extends Migration
{
public function up()
{
Schema::create('compliance_cache', function (Blueprint $table) {
$table->id();
$table->string('cache_key')->unique();
$table->string('control_id');
$table->longText('cached_data'); // JSON
$table->timestamp('expires_at');
$table->timestamps();
$table->index(['control_id', 'expires_at']);
$table->index('expires_at');
});
}
public function down()
{
Schema::dropIfExists('compliance_cache');
}
}
?>
# .env additions for AI implementation
OPENAI_API_KEY=your_openai_api_key_here
# AI Budget Controls
AI_DAILY_BUDGET=50
AI_MONTHLY_BUDGET=1500
AI_ADMIN_EMAIL=admin@yourcompany.com
# Processing Tiers
AI_COMPLEXITY_THRESHOLD_BASIC=0.3
AI_COMPLEXITY_THRESHOLD_ADVANCED=0.7
# Cache Settings
COMPLIANCE_CACHE_TTL=3600
env('AI_DAILY_BUDGET', 50),
'monthly_budget' => env('AI_MONTHLY_BUDGET', 1500),
'admin_email' => env('AI_ADMIN_EMAIL'),
'thresholds' => [
'basic' => env('AI_COMPLEXITY_THRESHOLD_BASIC', 0.3),
'advanced' => env('AI_COMPLEXITY_THRESHOLD_ADVANCED', 0.7),
],
'models' => [
'basic' => 'gpt-3.5-turbo',
'advanced' => 'gpt-4',
],
'pricing' => [
'gpt-3.5-turbo' => 0.002, // per 1K tokens
'gpt-4' => 0.03, // per 1K tokens
],
'cache_ttl' => env('COMPLIANCE_CACHE_TTL', 3600),
];
?>