m5c detection imports
Detection imports let teams bring foreign rule formats into the Mach5 package workflow. Imports are source inputs, not the runtime format.
Mach5 currently supports Sigma import preview/export for simple match-style rules.
Where import files live
m5c discovers detection import configurations from import.yaml files under packages/**/detection_imports/**.
A typical layout is:
packages/security-analytics/
detection_imports/
sigma/
import.yaml
field-mapping.yaml
sources/
okta-failed-login.yml
github-push-event.yml
Keep the original foreign rules committed next to the import configuration so translations are reproducible.
Build an import configuration
Build an import in this order:
- Choose the source language.
- Add source file globs.
- Add a field mapping file when defaults are not enough.
- Preview the import into a temporary directory.
- Review diagnostics for
partial,requires_contract_mapping, orunsupportedrules. - Promote translated Detection IR only when your team intentionally wants native copies.
- Keep the original source rules as the source of truth unless you deliberately migrate.
Import document
kind: DetectionImport
apiVersion: semantic-catalog.mach5.io/v1alpha1
metadata:
name: sigma-security-analytics
spec:
source_language: sigma
sources:
- sources/*.yml
field_mapping: field-mapping.yaml
default_status: review
on_unsupported: disable
Top-level fields
| Field | Required | Meaning |
|---|---|---|
kind | Yes | Must be DetectionImport. |
apiVersion | Recommended | Current examples use semantic-catalog.mach5.io/v1alpha1. |
metadata.name | Yes | Stable import configuration name. |
spec.source_language | Yes | Source language. Currently sigma is supported. |
spec.sources | Yes | Source files or simple glob patterns, resolved relative to import.yaml. |
spec.field_mapping | Optional | Relative path to a Sigma field mapping file. Defaults are used when omitted. |
spec.default_status | Optional | Review workflow hint for imported rules. |
spec.on_unsupported | Optional | Review workflow hint for unsupported rules. |
Source files
sources accepts relative file paths or simple filename globs with *.
sources:
- sources/*.yml
- more-rules/specific-rule.yaml
Glob expansion is intentionally simple: the * applies to the filename portion in one directory. Use multiple entries for multiple directories.
Sigma rule shape
A simple Sigma source rule looks like this:
title: Okta Failed Authentication Event
id: M5-SA-SIGMA-OKTA-FAILURE-001
status: test
description: Okta authentication failure translated into identity authentication contract matcher.
logsource:
product: okta
service: system
detection:
selection:
outcome.result: FAILURE
condition: selection
tags:
- attack.credential_access
- okta
level: medium
V1 import works best for rules with a single named selection and a condition that directly names that selection.
Supported condition shape:
detection:
selection:
event_type: PushEvent
condition: selection
Compound conditions such as selection and not filter are imported as partial when possible and should be reviewed.
Field mapping file
A field mapping translates Sigma field names into contract fields, family/detector selection, and output entity defaults.
mappings:
outcome.result:
contract: identity.authentication_event.v1
field: status_id
family: identity_access
detector: event_match
entity_kind: principal
entity_field: actor.user.email_addr
source.ip:
contract: identity.authentication_event.v1
field: src_endpoint.ip
family: identity_access
detector: event_match
entity_kind: ip
entity_field: src_endpoint.ip
event_type:
contract: repo.activity.v1
field: event_type
family: repo_activity
detector: event_match
entity_kind: repository
entity_field: repository.full_name
Field mapping entries are keyed by source-language field name. Each entry can define:
| Field | Required | Meaning |
|---|---|---|
contract | Yes | Target contract name used in generated requires.contracts. |
field | Yes | Target contract field used in generated matchers. |
family | Optional | Detection family. Defaults to identity_access when omitted. |
detector | Optional | Detector. Defaults to event_match when omitted. |
entity_kind | Optional | Output entity kind. |
entity_field | Optional | Output entity field. |
When no field mapping file is provided, m5c uses built-in defaults for common Okta and GitHub fields such as outcome.result, source.ip, actor.alternateId, event_type, and repository.full_name.
Value translation
The Sigma importer converts simple field matchers to Detection IR matchers.
| Sigma shape | Detection matcher |
|---|---|
field: value | operator: eq |
field: [a, b] | operator: in |
| `field | contains: value` |
| `field | startswith: value` |
| `field | endswith: value` |
For status_id mappings, common authentication strings are normalized:
| Sigma value | Detection value |
|---|---|
SUCCESS, success | 1 |
FAILURE, failed, failure | 2 |
Unsupported field modifiers or unmapped fields produce import diagnostics.
Preview Sigma output
m5c import sigma packages/security-analytics/detection_imports/sigma \
--out /tmp/m5c-sigma-import/detections \
--reports /tmp/m5c-sigma-import/reports \
--field-mapping packages/security-analytics/detection_imports/sigma/field-mapping.yaml
The command writes Detection IR preview files and import diagnostics. It prints a summary:
imported 10 Sigma rule(s): 8 translated, 1 partial, 1 unsupported
A non-zero exit code indicates unsupported rules were present.
Generated Detection IR
A translated Sigma rule becomes a native Detection document similar to this:
kind: Detection
apiVersion: semantic-catalog.mach5.io/v1alpha1
metadata:
name: okta-failed-authentication-event
labels:
source: sigma
annotations:
mach5.io/import.source_language: sigma
mach5.io/import.source_ref: sources/okta-failed-login.yml
mach5.io/import.status: translated
spec:
id: M5-SA-SIGMA-OKTA-FAILURE-001
title: Okta Failed Authentication Event
family: identity_access
detector: event_match
level: medium
enabled: true
requires:
contracts:
identity.authentication_event.v1: ">=1.0.0 <2.0.0"
matchers:
- field: status_id
operator: eq
value: 2
dedupe:
strategy: event_entity
fields: [detection_id, actor.user.email_addr, event_uid]
Review generated files before enabling or promoting them.
Import statuses
| Status | Meaning |
|---|---|
translated | The rule was translated into native Detection IR. |
partial | The rule was translated with limitations that need review. |
requires_contract_mapping | The rule references fields that have no mapping and produced no usable matcher. |
unsupported | The rule shape is not supported and should not be enabled as-is. |
Unsupported preview files are generated as disabled detections with import diagnostic annotations.
Source of truth
Keep the foreign source files and import configuration as the source of truth unless your team intentionally promotes generated Detection IR.
Recommended workflow:
- Commit
import.yaml, source rules, and field mappings. - Run
m5c validateandm5c lower; normal package flow imports configured sources in memory. - Use
m5c import sigmaonly when you need preview files or diagnostics for review. - Avoid committing generated previews as a second source of truth.
Validate and lower workflow
m5c validate apps/security-analytics --workspace --offline
m5c lower apps/security-analytics --dev --out /tmp/m5c-lowered
Validation loads import configuration. Lowering can include imported detections in the package flow. Use the preview command when you want files and per-rule diagnostics for human review.
Common mistakes
| Mistake | Fix |
|---|---|
| Mapping Sigma fields directly to vendor fields | Map to contract fields. |
| Using compound Sigma conditions without review | Treat the output as partial and inspect diagnostics. |
| Forgetting field mappings for custom fields | Add field-mapping.yaml entries. |
| Committing generated preview files unintentionally | Keep source rules as source of truth unless deliberately promoted. |
| Enabling unsupported generated detections | Keep unsupported or contract-mapping-required imports disabled. |
Best practices
- Map fields into contracts, not directly into vendor-specific runtime names.
- Review
partialtranslations before enabling them. - Keep unsupported imports disabled.
- Add native Detection IR for rules that need semantics beyond simple Sigma matching.
- Use preview reports in pull requests when adding or changing imported rules.