High-throughput packet-facing parsing, structured events, and extracted artifacts.
Rust engines, Python plugins, and YAML rule packs each have a different job.
The extensibility contract exists to keep packet-facing work, report-facing logic, and site-policy content from collapsing into one unstable blob.
Report-facing enrichment, mapping, correlation, and responder-side overlays.
Declarative mappings, suppressions, and local policy without turning config into another language.
Shared principles
- The portable MarlinSpike report artifact remains the primary handoff between packet analysis and downstream review.
- Optional extensions must run headlessly and must not require Flask, a browser, or a database connection.
- Machine-readable outputs should be deterministic and versioned.
- Packet-facing code should not make site-policy decisions.
- Report-facing code should not parse raw packet captures directly.
- YAML must stay declarative.
Rust engine contract
Rust engines own packet-facing and event-heavy work: reading captures, parsing protocols, normalizing transactions, and emitting structured observations or artifacts.
They do not own final topology scoring, responder-facing finding text, ATT&CK mapping, site-specific policy, or UI behavior.
marlinspike-dpi --input <pcap> --capture-id <id> --output <json> --pretty
The minimum invocation contract is simple: accept an input capture path, accept a stable capture identifier, write JSON output to a caller-specified path, and return non-zero on failure.
Python plugin contract
Python plugins consume a finished MarlinSpike report JSON and emit a sidecar artifact for enrichment, correlation, ATT&CK mapping, IEC 62443 mapping, malware matching, or other post-processing.
python -m marlinspike_plugin_name \
--input-report <report.json> \
--output <artifact.json>
The plugin should not mutate the input report in place. The sidecar artifact is authoritative, while a merged report can exist as a convenience copy.
{
"artifact_type": "plugin_output",
"plugin_id": "marlinspike-plugin-name",
"plugin_version": "0.1.0",
"contract_version": 1,
"summary": {},
"data": {},
"warnings": []
}
YAML rule pack contract
YAML rule packs are the declarative layer. They are meant for mappings, local overrides, enable and disable controls, and policy content that analysts may need to tune without rewriting code during an engagement.
The docs are explicit about what YAML should not become: a general programming language, a hidden parser surface, or a place to bury arbitrary logic that belongs in a plugin.
Rule of thumb for new work
- If it consumes raw
pcap, packet streams, or high-volume protocol events, it probably belongs in a Rust engine. - If it consumes the finished MarlinSpike report artifact, it probably belongs in a Python plugin.
- If analysts should be able to tune it without code changes, it probably belongs in a YAML rule pack.
Need the repo layout around those contracts?
The repo-family page shows how these extension surfaces line up with the suite repo and the future authoritative component repos.