{"slug": "building-a-local-ai-soc-analyst-on-an-m1-macbook-pro", "title": "Building a Local AI SOC Analyst on an M1 MacBook Pro", "summary": "The article describes the development of a local AI-powered SOC analyst that runs on an M1 MacBook Pro, designed to assist with daily security operations by triaging and analyzing alerts from existing cloud-native monitoring tools like Datadog, PagerDuty, and Sysdig. The solution uses Ollama to run local models (llama3.2:3b and qwen3:8b) within a Python harness, focusing on summarizing findings, correlating evidence, and producing daily security notes without automating production changes. A key lesson was that the model alone was insufficient; success required combining the right model with controlled prompts, use-case-driven analysis, and realistic hardware expectations.", "body_md": "## How I solved a real SOC operations problem for Datadog, AWS, Cloudflare, Sysdig, PagerDuty with an AI runner, a local AI harness with a tricky model selection process\n\n## Executive Summary\n\nWe started with a practical SOC problem: build an AI-based SOC analyst that runs locally on an M1 MacBook Pro and helps with daily security operations across an existing cloud-native monitoring and alerting stack.\n\nThe environment already had strong telemetry and alerting coverage:\n\n- AWS CloudTrail\n- AWS Security Hub\n- Route53 VPC DNS Firewall\n- SES\n- SNS\n- Cloudflare logs\n- Application logs\n- GitHub audit logs crawler\n- Datadog Cloud Security detections\n- Datadog monitors for Kubernetes and AWS metrics\n- Datadog dashboards covering many SOC use cases\n- Sysdig runtime policies for Kubernetes\n- PagerDuty alert routing\n\nThe problem was not lack of logs or alerts. The real challenge was analyst workflow. The SOC still needed a repeatable way to review alerts, correlate evidence, summarize findings, identify missing context, and produce daily security notes without manually jumping between tools every time.\n\nThe working solution became a local AI SOC analyst pattern:\n\n```\nOllama                Local model runner\nllama3.2:3b           Stable default model for M1 daily SOC work\nqwen3:8b              Optional larger model for focused deeper analysis\nPython harness        SOC workflow, prompts, guardrails, and integrations\nAI runner CLI         Analyst-facing command-line interface\nDatadog               Primary log, signal, dashboard, and monitoring source\nPagerDuty             Alert and incident routing source\nSysdig                Separate runtime policy signal source\nHuman analyst         Final decision authority\n```\n\nThe important lesson was that the model alone was not the solution. The working solution came from combining the right model, a controlled harness, bounded prompts, use-case-driven analysis, and realistic expectations about local MacBook hardware.\n\n## The Original Problem\n\nThe goal was to build a local AI-based SOC analyst on an M1 MacBook Pro.\n\nThe main telemetry flow looked like this:\n\n```\nAWS CloudTrail\nAWS Security Hub\nRoute53 VPC DNS Firewall\nSES\nSNS\nCloudflare logs\nApplication logs\nGitHub audit logs crawler\n        |\n        v\nDatadog\n        |\n        v\nDatadog Cloud Security rules\nDatadog monitors\nDatadog dashboards\n        |\n        v\nPagerDuty\n```\n\nSysdig was separate:\n\n```\nKubernetes runtime activity\n        |\n        v\nSysdig runtime policies\n        |\n        v\nPagerDuty\n```\n\nThat distinction mattered. Datadog was the central place for logs, detections, monitors, and dashboards. Sysdig was not sending its logs to Datadog, so Sysdig alerts had to be treated as a separate runtime security signal path.\n\nThe expected solution was not a generic local chatbot. The expected solution was a repeatable local SOC assistant that could support:\n\n- Daily SOC review\n- Alert triage\n- CloudTrail analysis\n- AWS Security Hub finding review\n- Route53 DNS Firewall activity review\n- SES and SNS activity review\n- Cloudflare security event review\n- GitHub audit log review\n- Application log review\n- PagerDuty incident summarization\n- Sysdig runtime alert review\n- SOC note drafting\n- Recommended follow-up queries\n\n## Key Design Decision: AI Should Not Replace Detection\n\nWe made one important architectural decision early: the local AI model should not become the detector.\n\nDatadog and Sysdig already perform that role:\n\n- Datadog receives logs and metrics.\n- Datadog Cloud Security rules generate security signals.\n- Datadog monitors detect operational and Kubernetes-related issues.\n- Sysdig runtime policies detect Kubernetes runtime policy violations.\n- PagerDuty routes alerts from Datadog and Sysdig.\n\nThe local AI should sit above those systems as a triage and analysis layer.\n\nThat means the AI helps answer:\n\n- What happened?\n- Which user, workload, IP, service, account, repository, or API was involved?\n- Is this likely malicious, expected change, duplicate, benign true positive, or false positive?\n- What evidence is missing?\n- Which Datadog queries should be run next?\n- Should this be escalated?\n- What should the SOC note say?\n- Is containment recommended, and does it require human approval?\n\nThis keeps the control boundary clean. Detection stays with Datadog and Sysdig. Alerting stays with PagerDuty. The local AI helps the analyst move faster, ask better questions, and document the investigation more consistently.\n\n## Final Architecture\n\nThe final working architecture was intentionally simple:\n\n```\n              +------------------------------+\n              | AWS / Cloudflare / GitHub    |\n              | Apps / SES / SNS / DNS FW    |\n              +---------------+--------------+\n                              |\n                              v\n                         +---------+\n                         | Datadog |\n                         | Logs    |\n                         | Signals |\n                         | Metrics |\n                         | Monitors|\n                         +----+----+\n                              |\n                              v\n                         +---------+\n                         |PagerDuty|\n                         +----+----+\n\n       +------------------+        +---------+\n       | Sysdig Runtime   |------->|PagerDuty|\n       | Policies         |        +---------+\n       +------------------+\n\n                              |\n                              v\n\n              +------------------------------+\n              | Local AI SOC Analyst         |\n              | M1 MacBook Pro               |\n              |                              |\n              | Ollama                       |\n              | llama3.2:3b / qwen3:8b       |\n              | Python SOC Harness           |\n              | AI Runner CLI                |\n              +------------------------------+\n```\n\nThe local AI analyst was designed as read-only first.\n\nIt can summarize, correlate, recommend, and draft. It should not automatically make production changes.\n\nHuman approval should still be required for actions such as:\n\n- Disabling IAM users\n- Rotating access keys\n- Blocking IPs globally\n- Changing Cloudflare WAF behavior\n- Muting Datadog monitors\n- Resolving PagerDuty incidents\n- Changing Sysdig policies\n- Quarantining Kubernetes workloads\n- Modifying production infrastructure\n\nThis matters because a wrong automated containment action can create a larger operational incident than the original alert.\n\n## What the AI Runner Does\n\nThe AI runner is the analyst-facing command-line interface.\n\nIt is what we run during daily operations.\n\nExamples:\n\n```\npython ai_runner.py triage-json samples/sample_cloudtrail_delete_trail.json \\\n  --use-case UC-006.3-cloudtrail-logging-disabled\npython ai_runner.py security-signals --hours 24\npython ai_runner.py pagerduty --hours 24\npython ai_runner.py daily --hours 24 --out reports/daily_soc_report.md\n```\n\nThe runner coordinates the work:\n\n- Pull security data from the configured source.\n- Select the right SOC prompt.\n- Build a bounded event bundle.\n- Send the prompt and evidence to Ollama.\n- Receive structured analysis from the local model.\n- Print the result or write a report.\n- Keep the workflow repeatable.\n\nThe runner is not the intelligence layer by itself. Its value is operational discipline. It prevents the analyst from manually copying logs, manually selecting prompts, manually formatting output, and manually saving results every time.\n\n## What the Harness Does\n\nThe harness is the control layer around the model.\n\nThis is the difference between a chatbot and a SOC workflow tool.\n\nThe harness handles:\n\n- Datadog API access\n- PagerDuty API access\n- Optional Sysdig API access\n- Use-case-specific prompts\n- SOC output structure\n- Context size limits\n- Model timeout configuration\n- Evidence-oriented analysis\n- Daily report generation\n- Read-only operating behavior\n- Repeatable command structure\n\nThe harness gives the model boundaries.\n\nFor SOC operations, this is critical. A local AI model should not receive an unbounded pile of logs and be asked, “Is anything bad?” That produces weak output and increases hallucination risk.\n\nInstead, the harness asks focused questions:\n\n- Analyze this CloudTrail event for possible defense evasion.\n- Summarize Datadog security signals from the last 24 hours.\n- Review PagerDuty incidents for security relevance.\n- Draft a daily SOC report from bounded evidence.\n- Identify missing evidence and recommended follow-up queries.\n\nThe model reasons. The harness controls the task.\n\n## Model Selection Strategy\n\nAt first, a larger model such as `qwen3:8b`\n\nlooked attractive because the problem involved cloud logs, security reasoning, and structured analysis.\n\nThat was a reasonable starting point. Larger models can be useful when the event bundle is small and the question requires deeper reasoning.\n\nHowever, the target machine was an M1 MacBook Pro, not a dedicated GPU workstation. That changed the practical answer.\n\nDuring testing, the first small triage workflow succeeded, but the machine became sluggish. Later, the heavier daily report failed with a local Ollama timeout:\n\n```\nReadTimeout: HTTPConnectionPool(host='127.0.0.1', port=11434): Read timed out. (read timeout=300)\n```\n\nThat error was useful because it showed:\n\n- The Python harness was running.\n- The harness reached Ollama on localhost.\n- Ollama was processing the request.\n- The model did not complete within the configured timeout.\n\nSo the issue was not the SOC design. The issue was local inference load: model size, prompt size, timeout, and hardware limits.\n\nThe model strategy was adjusted:\n\n| Task | Model | Why |\n|---|---|---|\n| Smoke testing | `llama3.2:3b` |\nFast and stable on M1 |\n| Daily SOC report | `llama3.2:3b` |\nMore reliable for bounded daily reporting |\n| Focused deeper investigation | `qwen3:8b` |\nUseful when the event bundle is smaller |\n| Large multi-source correlation | Avoid on M1 unless carefully limited | Can cause slowdowns or timeouts |\n\nThe final default became:\n\n```\nSOC_MODEL=llama3.2:3b\nSOC_FAST_MODEL=llama3.2:3b\n```\n\nThis was the right operational tradeoff.\n\nA smaller model that finishes reliably is more useful than a larger model that freezes the analyst workstation or times out during daily operations.\n\n## Hardware Constraint: The M1 MacBook Pro Matters\n\nThe M1 MacBook Pro can run useful local AI workflows, but the workflow must be tuned.\n\nThe main constraints were:\n\n- Local model cold start time\n- Memory pressure\n- Swap usage\n- Large prompt size\n- Long generation time\n- Ollama timeout\n- Large 24-hour log bundles\n\nThe fix was not to abandon the local approach. The fix was to make the workflow smaller and more controlled:\n\n```\nUse a smaller default model.\nLimit daily prompt size.\nStart with 6-hour reports.\nIncrease to 24 hours after validation.\nIncrease the Ollama timeout where needed.\nAvoid sending excessive raw logs to the model.\nUse focused use-case prompts.\n```\n\nThat is what made the solution usable.\n\n## Problems We Hit and How We Fixed Them\n\n### 1. `ollama ps`\n\nShowing Nothing\n\nWhen checking which model was running, `ollama ps`\n\nreturned nothing.\n\nThat does not always mean something is broken.\n\n`ollama ps`\n\nshows models currently loaded in memory. If the model finished and unloaded, it may show nothing.\n\nUseful checks:\n\n```\nollama list\n```\n\nShows installed models.\n\n```\nollama ps\n```\n\nShows currently loaded models.\n\n```\nollama run llama3.2:3b\n```\n\nManually starts a model.\n\nThis distinction helped avoid misdiagnosing a normal Ollama state as a failure.\n\n### 7. Mac was Freezing\n\nThe Mac became sluggish after running the local model.\n\nThe likely cause was local inference load, especially if a larger model was used.\n\nThe fix was to run the smaller model first:\n\n```\nSOC_MODEL=llama3.2:3b python ai_runner.py triage-json samples/sample_cloudtrail_delete_trail.json \\\n  --use-case UC-006.3-cloudtrail-logging-disabled\n```\n\nFor stability, Ollama can also be limited:\n\n```\nexport OLLAMA_NUM_PARALLEL=1\nexport OLLAMA_MAX_LOADED_MODELS=1\nexport OLLAMA_KEEP_ALIVE=30m\n```\n\n### 7. Daily Report Timeout\n\nThe daily command failed because the model did not return within the configured timeout:\n\n```\nReadTimeout: HTTPConnectionPool(host='127.0.0.1', port=11434): Read timed out. (read timeout=300)\n```\n\nThe fix had three parts:\n\n- Use\n`llama3.2:3b`\n\nfor daily reports. - Reduce the daily prompt size.\n- Increase the local model timeout where appropriate.\n\nA safer first run was:\n\n```\nSOC_MODEL=llama3.2:3b python ai_runner.py daily --hours 6 --out reports/daily_soc_report.md\n```\n\nThen scale to:\n\n```\nSOC_MODEL=llama3.2:3b python ai_runner.py daily --hours 24 --out reports/daily_soc_report.md\n```\n\nThe lesson: daily reports should summarize bounded evidence, not feed unlimited raw logs into a local model.\n\n## First Successful SOC Triage\n\nThe first successful test used a sample CloudTrail `StopLogging`\n\nevent.\n\nThat is a meaningful test because attempts to stop CloudTrail logging may indicate defense evasion, unauthorized administrative activity, or compromised credentials.\n\nThe AI produced a high-risk SOC-style result similar to:\n\n```\n{\n  \"severity\": \"High\",\n  \"confidence\": 85,\n  \"disposition\": \"true_positive\",\n  \"summary\": \"Suspicious attempt to stop CloudTrail logging...\",\n  \"suspicious_indicators\": [\n    \"StopLogging event by IAM user 'svc-deploy'\",\n    \"Source IP 203.0.113.45\",\n    \"User agent python-requests/2.32\"\n  ]\n}\n```\n\nThis proved the core workflow:\n\n```\nLocal venv works.\nDependencies are installed.\nAI runner executes.\nHarness builds the prompt.\nOllama receives the request.\nLocal model returns SOC-style analysis.\n```\n\nThe next improvement was to tighten expected output so the model always includes missing evidence and recommended follow-up queries. For production SOC use, those fields matter because they keep the analyst grounded in evidence.\n\n## Example SOC Use Cases\n\n### CloudTrail Logging Disabled\n\nUse case:\n\n```\nUC-006.3-cloudtrail-logging-disabled\n```\n\nPurpose:\n\nInvestigate possible CloudTrail tampering or defense evasion.\n\nExample command:\n\n```\npython ai_runner.py datadog-query \\\n  --query 'source:cloudtrail @evt.name:(StopLogging OR DeleteTrail OR UpdateTrail OR PutEventSelectors)' \\\n  --hours 24 \\\n  --use-case UC-006.3-cloudtrail-logging-disabled\n```\n\nFollow-up evidence should include:\n\n- Actor identity\n- Source IP\n- User agent\n- IAM permissions\n- Change ticket\n- Trail status after the event\n- Related IAM changes\n- Security Hub findings\n- Other Datadog signals for the same account or identity\n\n### IAM Privilege Escalation\n\nUse case:\n\n```\nUC-007-iam-privilege-escalation\n```\n\nExample command:\n\n```\npython ai_runner.py datadog-query \\\n  --query 'source:cloudtrail @evt.name:(AttachUserPolicy OR PutUserPolicy OR CreateAccessKey OR UpdateAssumeRolePolicy OR PassRole)' \\\n  --hours 24 \\\n  --use-case UC-007-iam-privilege-escalation\n```\n\nThe AI should help determine whether the activity was expected administration, automated deployment behavior, or suspicious privilege escalation.\n\n### Cloudflare WAF Activity\n\nUse case:\n\n```\nUC-011-cloudflare-waf-attack\n```\n\nExample command:\n\n```\npython ai_runner.py datadog-query \\\n  --query 'source:cloudflare (@action:block OR @action:challenge OR @security_action:block)' \\\n  --hours 24 \\\n  --use-case UC-011-cloudflare-waf-attack\n```\n\nThe AI should summarize source distribution, attacked paths, WAF actions, spike patterns, and whether any traffic bypassed protections.\n\n### Route53 DNS Firewall Activity\n\nUse case:\n\n```\nUC-010-route53-dns-firewall-blocks\n```\n\nExample command:\n\n```\npython ai_runner.py datadog-query \\\n  --query 'source:route53resolverdnsfirewall OR source:route53 @action:block' \\\n  --hours 24 \\\n  --use-case UC-010-route53-dns-firewall-blocks\n```\n\nThe AI should help identify suspicious domains, affected workloads, recurring clients, and whether the blocked activity suggests malware, misconfiguration, or expected testing.\n\n### GitHub Audit Risk\n\nUse case:\n\n```\nUC-014-github-audit-risk\n```\n\nExample command:\n\n```\npython ai_runner.py datadog-query \\\n  --query 'source:github (@action:*deploy_key* OR @action:*repo* OR @action:*workflow* OR @action:*branch_protection*)' \\\n  --hours 24 \\\n  --use-case UC-014-github-audit-risk\n```\n\nThe AI should focus on risky repository changes, workflow changes, deploy key activity, branch protection changes, and unusual administrative actions.\n\nThose mentioned cases are one of few. The possibility is huge here. If you can follow the architecture then success will be yours.\n\n## Daily SOC Workflow\n\nThe stable workflow became:\n\n### 1. Start Ollama\n\n```\nollama serve\n```\n\n### 2. Activate the project environment\n\n```\ncd /Users/tariqual/Documents/local_ai_soc_analyst\nsource .venv/bin/activate\n```\n\n### 3. Confirm model availability\n\n```\nollama list\n```\n\n### 4. Run a smoke test\n\n```\npython ai_runner.py triage-json samples/sample_cloudtrail_delete_trail.json \\\n  --use-case UC-006.3-cloudtrail-logging-disabled\n```\n\n### 5. Run a safe daily report first\n\n```\nSOC_MODEL=llama3.2:3b python ai_runner.py daily --hours 6 --out reports/daily_soc_report.md\n```\n\n### 6. Run the full daily report after the safe run works\n\n```\nSOC_MODEL=llama3.2:3b python ai_runner.py daily --hours 24 --out reports/daily_soc_report.md\n```\n\n### 7. Review the output as an analyst\n\nThe report should be reviewed for:\n\n- P0 and P1 items\n- CloudTrail administrative changes\n- Security Hub critical or high findings\n- Cloudflare attack patterns\n- Route53 DNS Firewall blocks\n- SES or SNS abuse indicators\n- GitHub audit activity\n- PagerDuty incidents\n- Sysdig runtime alerts\n- Missing evidence\n- Recommended Datadog queries\n- Escalation or containment recommendations\n\nThe daily report is an analyst aid. It is not an automatic incident declaration.\n\n## Why This Works\n\nThe final solution works because it respects both the SOC workflow and the hardware.\n\nIt does not try to make the local model do everything.\n\nIt uses the existing security stack correctly:\n\n```\nDatadog detects and stores telemetry.\nSysdig detects runtime policy violations.\nPagerDuty routes alerts.\nThe local AI harness gathers and structures evidence.\nThe model reasons over bounded context.\nThe analyst makes the final decision.\n```\n\nThat is a realistic AI SOC operating model.\n\n## What We Learned\n\n### 1. The model is only one part of the solution\n\nA strong model without a workflow becomes a chatbot. A smaller model with a strong harness can become a useful SOC assistant.\n\n### 2. Local hardware must shape the design\n\nThe M1 MacBook Pro can support useful local AI workflows, but model size and prompt size must be controlled.\n\n### 3. Daily SOC reporting needs summarization, not raw log dumping\n\nLarge prompts cause slowdowns and timeouts. The better pattern is to query, reduce, summarize, and then report.\n\n### 4. Read-only first is the right security posture\n\nThe AI can recommend containment, but production changes should remain human-approved.\n\n### 5. Evidence discipline matters\n\nThe AI output should separate observed facts, assumptions, missing evidence, and recommended next actions.\n\n### 6. The harness is the operational control plane\n\nThe harness provides repeatability, guardrails, prompts, source integration, and output structure. That is what makes the solution operationally useful.\n\n## Final Outcome\n\nWe achieved a working local AI SOC analyst solution that fits the original problem set.\n\nThe final solution:\n\n- Runs locally on an M1 MacBook Pro.\n- Uses Ollama as the local model runner.\n- Uses\n`llama3.2:3b`\n\nas the stable default model. - Allows\n`qwen3:8b`\n\nfor focused deeper analysis when the machine can handle it. - Uses a Python harness to control prompts, context, and workflows.\n- Uses an AI runner CLI for repeatable SOC commands.\n- Works with Datadog, PagerDuty, and optional Sysdig integration.\n- Supports CloudTrail, Security Hub, Route53 DNS Firewall, SES, SNS, Cloudflare, GitHub audit, application logs, and Kubernetes-related alert review.\n- Produces useful triage output and daily SOC reports.\n- Avoids unsafe automation by keeping containment human-approved.\n\nThe biggest success was not just getting a model to run locally. The success was turning local AI into a controlled SOC workflow that works despite hardware limitations.\n\nThat is the practical path for introducing AI into security operations: start with a real problem, keep the architecture simple, control the blast radius, tune for the hardware, and make the analyst workflow better.", "url": "https://wpnews.pro/news/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro", "canonical_source": "https://dev.to/mike_anderson_d01f52129fb/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro-2cl9", "published_at": "2026-05-24 04:16:29+00:00", "updated_at": "2026-05-24 04:31:40.725318+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "large-language-models", "cybersecurity", "developer-tools"], "entities": ["Ollama", "llama3.2", "qwen3", "Datadog", "PagerDuty", "Sysdig", "AWS", "M1 MacBook Pro"], "alternates": {"html": "https://wpnews.pro/news/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro", "markdown": "https://wpnews.pro/news/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro.md", "text": "https://wpnews.pro/news/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro.txt", "jsonld": "https://wpnews.pro/news/building-a-local-ai-soc-analyst-on-an-m1-macbook-pro.jsonld"}}