Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Perform structured log source onboarding into SIEM platforms by configuring collectors, parsers, normalization, and validation for complete security visibility.
.claude/skills/performing-log-source-onboarding-in-siem/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 94% | 31 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | — | — |
| case-19 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-06 | ✗→✓ | ▲ Improved | — | — |
| case-21 | ✗→✓ | ▲ Improved | — | — |
Log source onboarding is the systematic process of integrating new data sources into a SIEM platform to enable security monitoring and detection. Proper onboarding requires planning data sources, configuring collection agents, building parsers, normalizing fields to a common schema, and validating data quality. According to the UK NCSC, onboarding should prioritize log sources that provide the highest security value relative to their ingestion cost.
| Source | Log Type | Security Value | |---|---|---| | Active Directory | Security Event Logs | Authentication, privilege escalation | | Firewalls | Traffic logs | Network access, C2 detection | | EDR/AV | Endpoint alerts | Malware, process execution | | VPN/Remote Access | Connection logs | Unauthorized access | | DNS Servers | Query logs | C2 beaconing, data exfiltration | | Email Gateway | Email security logs | Phishing, BEC |
| Source | Log Type | Security Value | |---|---|---| | Web Proxy | HTTP/HTTPS logs | Web-based attacks, data exfiltration | | Cloud platforms (AWS/Azure/GCP) | Audit logs | Cloud security posture | | Database servers | Audit/query logs | Data access, SQL injection | | DHCP/IPAM | Address allocation | Asset tracking | | File servers | Access logs | Data access monitoring |
| Source | Log Type | Security Value | |---|---|---| | Application servers | App logs | Application-level attacks | | Print servers | Print logs | Data loss prevention | | Badge/physical access | Access logs | Physical security correlation | | Network devices (switches/routers) | Syslog | Network anomalies |
1. Identify the log source:
- System type and version
- Log format (syslog, CEF, JSON, Windows Events, etc.)
- Log volume estimate (EPS - events per second)
- Network location and firewall requirements
2. Assess security value:
- What threats can this source help detect?
- Which MITRE ATT&CK techniques does it cover?
- Is there an existing SIEM parser?
3. Estimate ingestion cost:
- Daily volume in GB
- License impact (per-GB or per-EPS pricing)
- Storage retention requirementsconf# rsyslog configuration for receiving syslog # /etc/rsyslog.d/10-siem-collection.conf # UDP reception module(load="imudp") input(type="imudp" port="514" ruleset="siem_forwarding") # TCP reception module(load="imtcp") input(type="imtcp" port="514" ruleset="siem_forwarding") # TLS reception module(load="imtcp" StreamDriver.AuthMode="x509/name" StreamDriver.Mode="1" StreamDriver.Name="gtls") input(type="imtcp" port="6514" ruleset="siem_forwarding") ruleset(name="siem_forwarding") { # Forward to SIEM action(type="omfwd" target="siem.company.com" port="9514" protocol="tcp" queue.type="LinkedList" queue.filename="siem_fwd" queue.maxdiskspace="1g" queue.saveonshutdown="on" action.resumeRetryCount="-1") }
conf# inputs.conf on Splunk Universal Forwarder [WinEventLog://Security] disabled = 0 index = wineventlog sourcetype = WinEventLog:Security evt_resolve_ad_obj = 1 checkpointInterval = 5 [WinEventLog://System] disabled = 0 index = wineventlog sourcetype = WinEventLog:System [WinEventLog://Microsoft-Windows-Sysmon/Operational] disabled = 0 index = wineventlog sourcetype = XmlWinEventLog:Microsoft-Windows-Sysmon/Operational renderXml = true [WinEventLog://Microsoft-Windows-PowerShell/Operational] disabled = 0 index = wineventlog sourcetype = XmlWinEventLog:Microsoft-Windows-PowerShell/Operational
json{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "CloudTrailToSIEM": { "Type": "AWS::CloudTrail::Trail", "Properties": { "TrailName": "siem-cloudtrail", "S3BucketName": "company-cloudtrail-logs", "IsLogging": true, "IsMultiRegionTrail": true, "IncludeGlobalServiceEvents": true, "EnableLogFileValidation": true, "EventSelectors": [ { "ReadWriteType": "All", "IncludeManagementEvents": true, "DataResources": [ { "Type": "AWS::S3::Object", "Values": ["arn:aws:s3"] } ] } ] } } } }
conf# props.conf [custom:firewall:logs] SHOULD_LINEMERGE = false LINE_BREAKER = ([\r\n]+) TIME_PREFIX = ^ TIME_FORMAT = %Y-%m-%dT%H:%M:%S%z MAX_TIMESTAMP_LOOKAHEAD = 30 TRANSFORMS-firewall = firewall_extract_fields FIELDALIAS-src = src_addr AS src_ip FIELDALIAS-dst = dst_addr AS dest_ip EVAL-action = case(fw_action=="allow", "allowed", fw_action=="deny", "blocked", true(), "unknown") EVAL-vendor_product = "Custom Firewall" LOOKUP-geo = geo_ip_lookup ip AS dest_ip OUTPUT country, city, latitude, longitude # transforms.conf [firewall_extract_fields] REGEX = ^(\S+)\s+(\S+)\s+action=(\w+)\s+src=(\S+):(\d+)\s+dst=(\S+):(\d+)\s+proto=(\w+)\s+bytes=(\d+) FORMAT = timestamp::$1 hostname::$2 fw_action::$3 src_addr::$4 src_port::$5 dst_addr::$6 dst_port::$7 protocol::$8 bytes::$9
| Raw Field | CIM Field | Data Model | |---|---|---| | src_addr | src_ip | Network_Traffic | | dst_addr | dest_ip | Network_Traffic | | dst_port | dest_port | Network_Traffic | | fw_action | action | Network_Traffic | | bytes_sent + bytes_recv | bytes | Network_Traffic | | user_name | user | Authentication | | login_result | action | Authentication | | process_path | process | Endpoint |
spl# Verify events are arriving index=new_source earliest=-1h | stats count by sourcetype, host, source # Check field extraction quality index=new_source earliest=-1h | stats count(src_ip) as has_src count(dest_ip) as has_dest count(action) as has_action count by sourcetype | eval src_coverage=round(has_src/count*100,1) | eval dest_coverage=round(has_dest/count*100,1) | eval action_coverage=round(has_action/count*100,1) # Verify CIM compliance | datamodel Network_Traffic search | search sourcetype=new_sourcetype | stats count by source, sourcetype # Check for timestamp parsing issues index=new_source earliest=-1h | eval time_diff=abs(_time - _indextime) | stats avg(time_diff) as avg_lag max(time_diff) as max_lag by host | where avg_lag > 300
spl# Verify existing correlation searches work with new source index=new_source sourcetype=new_sourcetype | tstats count from datamodel=Authentication by _time span=1h | timechart span=1h count # Create source-specific detection rule [New Source - Authentication Anomaly] search = index=new_source sourcetype=new_sourcetype action=failure \ | stats count by src_ip, user \ | where count > 10
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | pass→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.