Getting started
Create a new repository from the Rust plugin template by clicking Use this template on GitHub. Clone your new repository and rename the project inCargo.toml and plugin.toml to match your plugin name.The template gives you a working plugin with Cargo configuration, a plugin.toml manifest, a build.rs, example source code, and CI already set up.Prerequisites
- Rust toolchain (stable, 2024 edition)
Project structure
Cargo.toml
plugin.toml
Every plugin needs a plugin.toml manifest alongside its binary. This tells the daemon how to manage your plugin.build.rs
The build.rs ensures cargo re-runs the proc-macro when plugin.toml changes:src/main.rs
The SDK uses attribute macros to wire your plugin into the runtime. You annotate your struct and impl block instead of manually implementing traits.#[malbox::handlers] macro scans your impl block for annotated methods and generates the necessary trait implementations. Your method names can be anything you like - the attributes determine their role.Handler methods
When
on_start takes a typed parameter, the macro deserializes the raw HashMap<String, String> config into that type automatically.Pushing results
Results are pushed to the daemon viactx.results(). You can call push methods multiple times to stream results incrementally. There are three result types:json() returns Result<PluginResult> (serialization can fail), while bytes() and file() return PluginResult directly.Each result name should match an entry in your plugin.toml under [results.*].Reports
For structured analysis output with verdicts, indicators, TTPs, and frontend-renderable sections, use theReportBuilder to construct a Report and push it as a result. Reports support:- Verdicts with classification (clean/suspicious/malicious/unknown), confidence, and score
- Indicators (IOCs) with open-vocabulary types like
sha256,ipv4,domain - TTPs referencing MITRE ATT&CK techniques
- Artifact references linking to sibling
PluginResultentries - Presentation sections with typed blocks (markdown, tables, code, hex dumps, graphs, timelines, and more)
Handling errors
The SDK uses its ownResult<T> type aliased to std::result::Result<T, SdkError>. Handler methods return Result<()> and can use ? to propagate errors naturally.Subscribing to events
Declare subscriptions in the[events] section of your plugin.toml, then use #[malbox::on_event(...)] in your handler impl to react to specific event variants:Result<()>.See the Events Reference for the full list of available events.Holding state
Your plugin struct can hold fields. For concurrent access withExecutionContext::Parallel, wrap mutable state in Mutex or similar:Thread safety
When usingExecutionContext::Parallel, multiple on_task calls may execute concurrently. Protect shared mutable state with Mutex, RwLock, or atomic types. Health checks may also arrive on a different thread regardless of execution context.Testing
The SDK provides atestkit feature for writing unit tests without a running daemon. Enable it in your Cargo.toml:Context::test_new() to create a mock context for testing handler logic.Build
Linux
Host plugins always target Linux (they run on the daemon machine). Guest plugins targeting a Linux guest VM also use this.Deploy
Place the compiled binary andplugin.toml in a subdirectory of the daemon’s plugin directory. The daemon discovers plugins automatically on startup.~/.config/malbox/plugins/
my-host-plugin-bin
plugin.toml