Appearance
Security Monitoring Architecture
Rebased from the
bedrock-soccodebase on 2026-06-10 (review issue #138). Counts, pipeline order, and job mapping below cite their source files; if this doc andbedrock-socdisagree, the code wins.
Overview
Cirius Group runs an agent-based security monitoring system deployed as Azure Container Apps Jobs. The consolidated orchestrator (job-orchestrator-cirius) runs 81 detection agents per cycle across PROD + DDE + AWS + HOME, drawn from 126 agent modules in the bedrock-soc repo, followed by a multi-stage triage pipeline. A 5-minute mini-orchestrator provides rapid response between cycles; a daily maintenance run covers posture. Findings post to the SOC platform; urgent incidents page Rory via Telegram. No human is required in the loop for detection — only for triage and response.
(The long-standing "17-agent system" label describes the original 2025 deployment and is retired.)
Branding — MSSP vs. Customer Entity
Two distinct identities run through everything the SOC produces. Keeping them straight is a hard rule, not a style preference — it is the difference between a service voice and a legal entity.
| Identity | Role | Where it appears |
|---|---|---|
| Bedrock Cybersecurity | The MSSP — the managed-security service voice | Outbound sender / report-issuer branding: email "from" name, report headers, heartbeat and notification voice, anything that speaks as the provider |
| Cirius Group | The customer / monitored entity being protected | SENTINEL report subjects, the audited-entity field, and all HIPAA legal text — anything that names who is under audit |
Rules:
- Reports and emails are issued by Bedrock Cybersecurity. When the SOC speaks in the provider's voice — the sender name, report-issuer line, heartbeat and alert notifications — that voice is Bedrock Cybersecurity, the MSSP.
- Cirius Group stays as the customer entity. Do not rebrand Cirius Group out of SENTINEL report subjects, the audit-entity reference, or HIPAA legal text. There, Cirius Group is the entity being monitored, not the service provider — swapping it for Bedrock there would be wrong.
- Incident links point to
soc.bedrockcybersecurity.org(incidents moved offsecops→soc).
Shipped in bedrock-soc (#237 / #238 / #239). If a report, email, or template mixes the two voices, the test is simple: who is speaking (Bedrock, the MSSP) vs. who is being audited (Cirius Group, the customer).
Stack
| Component | Resource | Location |
|---|---|---|
| Agent runtime | Container Apps Jobs (consolidated *-cirius + specialized) | rg-logging-logs, logging subscription |
| Container registry | ciriusagentsprod.azurecr.io | logging subscription |
| SOC platform | ca-soc-prod — soc.bedrockcybersecurity.org | rg-logging-logs |
| SecOps dashboard | ca-secops-prod — secops.bedrockcybersecurity.org (read-only aggregator) | rg-logging-logs |
| Database | PostgreSQL — psql-soc-prod (SOC platform); UBA baselines in psql-secops-prod | logging subscription |
| Log sources | cirius-logging-law-central (PROD, ID 5d76d1f2), DDE LAW, OPS LAWs | per tenant |
| AI inference | Azure OpenAI | cirius-openai-prod.openai.azure.com |
Pipeline (per orchestrator cycle, in order)
Source: bedrock-soc/agents/orchestrator.py.
- Mini agents — 81 registry agents post NEW incidents in parallel waves of 5; then the UEBA baseliner and the SLA agent (refreshes SLA state, Telegram AT_RISK warnings).
- Analyst agent (rules engine, no LLM) — moves NEW → CLOSED (known-good / CM-ticket / maintenance-window match) or OPEN.
- Engineer agent — closes recurring noise with CM tickets; proposes PENDING known-good rules. Then the auto-correlator (links OPEN incidents sharing actor/resource) and the kill-chain correlator (multi-stage chains in a 120-min window → CRITICAL chain incident).
- History matcher — closes patterns resolved 5+ times as FP in 90 days (never touches CRITICAL). Then threat-intel enrichment of surviving OPEN incidents (AbuseIPDB / VirusTotal / HIBP / Shodan).
- Detection agent (LLM) — enriches remaining OPEN incidents; triage agent (LLM) auto-closes obviously-benign ones.
- SecurityAgent (LLM) — paging decision over first-time incidents, per-environment prompts; urgent → Telegram.
- Post-run: vuln findings mirrored to bedrock-findings, CMDB sync, email heartbeat report; Mondays add known-good counter reset + stale-rule pruning.
Container Apps Jobs (Consolidated — June 2026)
The per-environment split (formerly job-orchestrator-prod / job-secops-dde / job-secops-aws) shipped and was later consolidated into tenant-wide jobs. Source of truth: azure-infra/logging/secops_cirius.tf and the bedrock-soc repo.
| Job | Scope | Schedule |
|---|---|---|
job-orchestrator-cirius | Main incident pipeline — PROD + DDE + AWS + HOME (81 agents + full pipeline) | Every 4 hours |
job-mini-orchestrator-cirius | 9 read-only rapid checks (cortex, execution ×2, network ×2, identity, GuardDuty, CloudTrail root, IAM); triggers the main job on urgent signal, 60-min cooldown | Every 5 minutes |
job-secops-maintenance-cirius | 22 posture agents — backup, VM status, certs, endpoint, MDR coverage, supply chain, credential inventory | Daily 07:00 UTC |
Specialized jobs run alongside: job-uba-baseline-{prod,dde} (weekly Sun 02:00 UTC), job-findings-agents-prod, job-audit-evidence-prod (daily), job-sentinel-*, job-grc-agents-prod. Eleven external-surface agents (HIBP, CT logs, Shodan, typosquat, DNS/email security, GHAS…) run as scheduled GitHub Actions rather than Container Apps Jobs (bedrock-soc/README.md).
Note:
orchestrator.py's docstring still says "every 6 hours"; the 4-hour figure followsbedrock-soc/CLAUDE.mdand README (newer, post-consolidation). The actual cron lives in azure-infra Terraform.
Agent Inventory (by category)
126 agent modules; 81 run per main CIRIUS cycle. Chronic agents (61 names in agents/agent_config.py::CHRONIC_AGENTS) keep one long-lived incident per condition (no date in ioc_key); behavioral agents date-stamp so each day's signal is a distinct ticket.
| Category | Count | Notable agents | Data sources |
|---|---|---|---|
| Kill chain — PROD / DDE / AWS | 7 + 7 + 7 | execution, persistence, credential_dumping, lateral_movement, exfiltration, defense_evasion, encryption (+_dde, aws_* variants) | Sentinel LAW SecurityEvent KQL; CloudTrail (7 accounts) |
| ATT&CK coverage net | 2 | kql_coverage, kql_coverage_dde — 655 KQL queries / 527 techniques | both Sentinel LAWs |
| Universal translator agents | 3 | universal_sentinel(_dde), universal_aws — translator-mapped detections, replacing per-stage DDE agents | SentinelKQL / CloudTrail translators |
| Identity & auth | 6 PROD + 5 DDE | identity, entra, sp_signin, ad, dcsync, ad_identity | SigninLogs, AuditLogs, DC SecurityEvent |
| Break-glass | 3 | break_glass{,_dde,_aws} — any activity pages, no exceptions | Entra logs, Palo syslog, AWS root CloudTrail |
| UBA | 9 PROD + 4 DDE + 2 AWS | impossible travel, MFA fatigue, dormant account, off-hours privileged, logon velocity, bulk data access, longitudinal drift | Sign-in logs vs p50/p95 baselines (psql-secops-prod) |
| Azure activity / M365 / DLP | 6 | azure_activity, office, purview_dlp (+_dde) | AzureActivity, OfficeActivity, Purview |
| Network & log integrity | 2 + 6 | network(_dde); log_volume, fim, syslog (+_dde) | Palo Alto CEF, OPS LAWs, FIM |
| EDR / vendor | 4 | cortex, cortex_version, edr_silence, canary | Cortex XDR API, LAW heartbeat, canary health |
| AWS infra activity | 4 | aws_security, aws_cloudtrail, aws_palo, aws_winevent | Security Hub/GuardDuty, CloudTrail, S3 archives |
| HOME workstations | 3 | device_alert, device_process, device_network | MDE device tables via Defender XDR connector |
| Supply chain | 1 | sbom_scanner | SBOMs in cirius-audit-evidence-prod |
| Maintenance (daily) | 12 PROD + 4 DDE + 5 AWS + 1 HOME | backup, vm_status, disk_space, cert_expiry, arctic_wolf_coverage, keeper, twingate, mdfc, credential_inventory… | Azure/AWS APIs, vendor APIs |
| External surface (GH Actions) | 11 | hibp, cert_transparency, shodan_exposure, typosquat, dns_monitor, email_security, github_security… | external APIs |
| LLM analyst packages | 7 | azure_auditor, cti_analyst, detection_engineer, identity_analyst, sentinel | Graph/MDFC/Intune, KEV+OTX+VT, LAW backtests |
Full per-agent registry: bedrock-soc/agents/orchestrator.py:1379-1605. Environment membership is decided by the registry dicts (PROD_AGENTS / DDE_AGENTS / AWS_AGENTS / HOME_AGENTS / MAINTENANCE_*) selected by the job's --environment arg — agents do not self-declare. Every finding is stamped with source_system via _env_to_source_system().
Break-Glass Accounts (Permanently Unsuppressible)
Any activity from the 18 break-glass accounts triggers CRITICAL immediately with no suppression possible — not by known-good rules, not by analyst override. Hard-blocked at the SOC API layer (bedrock-soc/app/routers/known_good.py).
Incident Lifecycle
NEW ──► CLOSED (Analyst Agent: known-good rule match)
NEW ──► OPEN (Analyst Agent: no known-good match)
OPEN ──► INVESTIGATING (analyst picks up)
INVESTIGATING ──► RESOLVEDAll state transitions are in the SOC platform at soc.bedrockcybersecurity.org. Telegram is read-only — no buttons, no approvals via Telegram.
Known-Good Rules
Rules are DB-driven; agents fetch on startup via GET /api/known-good. Hit counters increment fire-and-forget (POST /api/known-good/{id}/hit). Rory is the sole authority for creating or modifying rules. Break-glass accounts are permanently excluded from any rule scope.
Change Management Integration
Every merged PR auto-creates a CM ticket via POST /api/changes. The analyst agent calls GET /api/changes/recent before opening an incident — a matching CM within the window suppresses infrastructure-change alerts. This prevents agent noise during normal Terraform apply cycles.
Notification Rules
| Condition | Channel |
|---|---|
| Every orchestrator run completes | Email (heartbeat) |
| SecurityAgent pages on CRITICAL/HIGH incident | Telegram |
| SLA AT_RISK warnings | Telegram |
| Known-good rule match (CLOSED) | No notification |
| Analyst moves to INVESTIGATING | SOC UI only |
All outbound email and reports are issued in the Bedrock Cybersecurity (MSSP) voice; Cirius Group is named only as the monitored/audited entity. See Branding — MSSP vs. Customer Entity.
Last updated: June 2026 — full rebase from bedrock-soc (issue #138): consolidated jobs, real pipeline order, 126-module / 81-per-cycle agent inventory by category. API contract: SOC API Reference.