Skip to content

SOC Integration Guide

Audience SOC analysts and engineers, platform team
Status IMPLEMENTED (export, dedup, dispatch; modules/sentinel creates the table, DCR and rules). Agree the event list (config/siem-events.yaml) with your security operations team.
Decision ADR-020 · event catalogue config/siem-events.yaml

1. What the SOC receives (and doesn't)

Eleven curated event types that indicate active risk or possible compromise: exposed active secrets, malicious packages, KEV-listed vulnerabilities on internet-facing apps, P1 SLA breaches, evidence integrity failures, forged-evidence attempts, SoD violation attempts, bulk exports, privileged activations, mass-closure anomalies, and daily integrity checkpoints. Routine findings are not sent.

2. Sentinel setup

Step Owner Detail
1 SOC Create custom table AppSecPlatform_CL (schema below) and a Data Collection Rule + endpoint
2 SOC/IAM Grant the platform worker's managed identity Monitoring Metrics Publisher on the DCR
3 Platform Configure DCE URL, DCR immutable ID and stream name in platform config
4 SOC Deploy analytics rules (the Azure example's examples/terraform/azure/modules/sentinel) and set table retention ≥ evidence retention (for checkpoint.daily)

Table schema

Column Type Notes
TimeGenerated datetime occurred_at
EventId string Idempotency key
EventType string e.g. secret.exposed_active
Severity string informational / low / medium / high
AppKey, AppTier string, int Correlation with app inventory
Repo string org/repo
ResourceIds dynamic Azure resource IDs / AWS ARNs
VulnIds dynamic CVE/GHSA/MAL ids
Actor string Identity-provider subject or GitHub/GitLab login
PlatformUrl string Deep link (requires platform access)
CorrelationId string
Details dynamic Minimal, no secret values

3. Example analytics rules (KQL sketches)

Exposed secret used after exposure (correlate with your identity provider's service principal or workload sign-ins):

AppSecPlatform_CL
| where EventType == "secret.exposed_active"
| extend AppId = tostring(Details.client_id)
| join kind=inner (AADServicePrincipalSignInLogs | where TimeGenerated > ago(1d)) on $left.AppId == $right.AppId
| where TimeGenerated1 > TimeGenerated

KEV vulnerability on internet-facing app + WAF hits on the app's host:

AppSecPlatform_CL
| where EventType == "vuln.kev_internet_exposed"
| extend Host = tostring(Details.host)
| join kind=inner (AzureDiagnostics | where Category == "FrontDoorWebApplicationFirewallLog") on $left.Host == $right.host_s

Repeated forged evidence attempts by one actor:

AppSecPlatform_CL
| where EventType == "evidence.untrusted_producer"
| summarize count() by Actor, bin(TimeGenerated, 1d) | where count_ >= 3

The rules are illustrative. Table and field names for source logs must be confirmed against the workspace.

4. Other SIEMs (Splunk, Elastic, Exabeam, …)

The same events go to any SIEM through one of two sinks (one SIEM sink is active per deployment):

  • HTTPS (siem_http): set AAP_SIEM_HTTP_URL and store the ingest token with aap secrets put siem-http-token. For Splunk, also set AAP_SIEM_HTTP_FORMAT=splunk_hec.
  • Syslog (syslog): RFC 5424 messages over TLS (RFC 5425). Set AAP_SIEM_SYSLOG=host:port (usually port 6514), and AAP_SIEM_SYSLOG_CA for a private CA.

Field names are the same as in the Sentinel table above; agree the mapping and detection rules with the SOC.

5. Escalation and response

Event SOC response AppSec contact
secret.exposed_active Hunt for credential use. Confirm rotation with the owner. Platform on-call / AppSec
package.malicious_detected Incident: assess CI runners and secrets exposed to builds AppSec lead
evidence.integrity_failure Incident: possible platform compromise Platform on-call + AppSec lead
Others Triage per SOC playbook AppSec triage channel