The recent arrival of the sekoia-automation-sdk on the Python Package Index signals a notable advancement for security teams seeking to automate incident response with greater agility and repeatability. By delivering a concise yet powerful Python library, the SDK enables developers to craft bespoke playbook modules that plug directly into the Sekoia.io orchestration engine, effectively bridging the gap between low‑code automation frameworks and full‑software development practices. This shift is particularly relevant in today’s threat landscape, where adversaries constantly refine their tactics and organizations must be able to deploy new detection logic within minutes rather than weeks. Early users have observed that encoding domain‑specific knowledge into reusable components not only reduces the mean time to contain incidents but also frees analysts from repetitive manual tasks, allowing them to focus on higher‑value threat hunting and strategic initiatives. Moreover, the SDK’s design embraces container‑native principles, meaning each module can be packaged as a Docker image that adheres to organizational security baselines, passes vulnerability scans, and integrates smoothly into existing CI/CD pipelines. As more vendors expose comparable SDKs for their SOAR platforms, the industry is moving toward a model where security automation resembles modern application development, replete with version control, automated testing, and collaborative code reviews. Consequently, teams that adopt this SDK today are positioning themselves to reap the benefits of faster iteration, improved reliability, and easier knowledge transfer across shifts and geographies.
At the core of any playbook module is the trigger, the element responsible for sensing external stimuli and launching the automated workflow. Using the SDK, a trigger is constructed by subclassing the base Trigger class, which grants immediate access to two distinct configuration dictionaries: self.configuration holds parameters unique to the individual trigger, while self.module.configuration contains settings shared across all triggers and actions within the same module. This separation provides a clean way to support multiple triggers that behave differently—say, one that polls a threat‑intel feed every five minutes, another that awaits webhook notifications from a cloud service, and a third that monitors file‑system changes on a hardened host—while still drawing from a common reservoir of credentials, proxy details, or TLS certificates. By manipulating self.configuration, administrators can tweak polling intervals, filter expressions, or query strings without touching the underlying detection logic, whereas adjustments to self.module.configuration affect global behaviors such as outgoing request timeouts or retry policies. The SDK additionally manages the trigger’s lifecycle, ensuring proper initialization, graceful shutdown, and centralized error handling, which eliminates a significant amount of boilerplate code. As a result, developers can devote their attention to the core detection algorithms, confident that the surrounding infrastructure is robust, observable, and aligned with enterprise‑grade operational standards.
Enrichment is a critical step in any effective playbook, and the SDK makes it straightforward to attach contextual artifacts—such as raw log extracts, suspicious files, or screenshot evidence—to the events generated by a trigger. Through a dedicated attachment API, developers can associate arbitrary files with an event, ensuring that those artifacts travel alongside the data as the playbook progresses from one action to the next. To create a file dynamically, the write method accepts a filename and a byte‑string or Unicode payload, storing the result in a temporary workspace that is subsequently mounted into the action containers. This approach proves invaluable when you need to obfuscate a payload, convert log formats, or generate a summary report before passing the information to a decision‑making component. Because the file resides in the same isolated filesystem as the event, any downstream action can retrieve it using familiar Python I/O calls, eliminating the need for redundant data transfers or complex inter‑service messaging. Importantly, the attachment mechanism respects the sandboxing boundaries inherent to the containerized execution environment, guaranteeing that sensitive material never leaks outside the intended playbook scope. Teams can thus construct modular enrichment pipelines where each stage contributes a distinct piece of evidence, culminating in a richer incident narrative that empowers analysts and threat hunters to make faster, more informed decisions.
Actions represent the operational heart of a playbook, performing tasks such as data enrichment, external API calls, or remedial measures. A minimal action in the SDK can be as simple as a class inheriting from Action and overriding the run method to return the arguments it received unchanged. Even this modest example illustrates the fundamental contract: the action receives an input dictionary, applies whatever logic you define, and outputs a dictionary that becomes part of the playbook’s mutable state. By echoing the input, you create a useful passthrough component for debugging or for confirming that the trigger fired as expected. In production scenarios, you would typically transform the input—for instance, pulling an IP address out of a nested JSON structure, querying a reputation service for geolocation and threat intel, and then returning the enriched record. The SDK guarantees that the action’s return value is automatically serialized and made available to subsequent steps, removing the burden of manual context management. This straightforward data‑flow model encourages developers to think in terms of pure functions, which simplifies unit testing, reduces side‑effects, and leads to more reliable automation. Moreover, because each action runs in its own isolated container instance, there is no risk of unintended cross‑talk between concurrent playbooks, ensuring deterministic behavior even under high load.
Just like triggers, actions enjoy full file‑system access, enabling bidirectional exchange of data through the workspace that the SDK provisions for each playbook run. An action can read an attached file by opening it with standard Python calls, using the filename supplied when the trigger attached the artifact. Conversely, an action can write new files—such as a parsed configuration, a generated forensic report, or a quarantined payload—using the write helper, which places the file in the shared workspace so that later actions or even the original event can access it as the playbook proceeds. This symmetry allows designers to assemble sophisticated workflows where a trigger captures a raw payload, one action decodes or deobfuscates it, another runs it through an antivirus engine, and a final action archives the cleaned version for long‑term storage. Because every file operation occurs inside the container’s isolated filesystem, there is no danger of interfering with other playbooks executing simultaneously on the same host. Furthermore, the SDK automatically cleans up temporary workspace files once the playbook run concludes, helping to keep the underlying infrastructure tidy and reducing the operational overhead associated with manual cleanup scripts. Teams can therefore construct complex, multi‑stage automations with confidence that data integrity is preserved and that resource consumption remains predictable.
Many playbooks need to ingest sophisticated input structures—think JSON objects laden with nested configuration, arrays of indicators of compromise, or multi‑step enrichment directives. Rather than forcing developers to wrestle with raw string parsing, the SDK supplies a handy helper that attempts to read the input from a reserved attribute named test; if that attribute is present, its value is used directly. Should test be missing, the helper transparently falls back to reading the contents of a file whose path is recorded in test_path. This dual‑mode strategy lets you build actions that are equally at home in unit‑test environments—where you might inject a JSON object directly for rapid verification—and in production runs—where the platform may opt to pass the input via a temporary file to circumvent command‑line length limitations. By centralizing this logic within a single helper, the SDK eliminates repetitive boilerplate and guarantees uniform behavior across every action in a module. Consequently, developers can concentrate on the core business logic of validating, transforming, or enriching the incoming data, safe in the knowledge that the underlying acquisition mechanism is both resilient and well‑tested. The helper also performs basic type conversions when appropriate, further reducing the chance of runtime errors caused by mismatched data formats.
The symmetry between input and output handling is a hallmark of the SDK’s thoughtful design. Just as actions consume data through the input helper, they often need to emit results that downstream steps or the playbook itself will consume. To this end, the SDK provides an output helper that constructs a dictionary suitable for return values. By default, the helper expects the outcome to be placed under a key named test_path, but if the final argument supplied to the helper is a plain value rather than a file path, it will instead store that value under the key test. This flexibility enables a clean API where you can either return a filepath pointing to a generated artifact—or return the artifact’s content directly—depending on what makes sense for the subsequent consumer. Imagine an action that converts a CSV log into JSON: it might write the JSON to disk and return test_path, allowing the next action to read the file, whereas an action that merely calculates a numeric risk score could return the score via test. The helper also manages proper serialization, ensuring that complex objects such as lists, nested dictionaries, or custom models are correctly encoded for the playbook’s context engine. Consequently, teams can craft actions that are both versatile and easy to chain together, reducing integration friction and accelerating the delivery of new automation capabilities.
In production environments, it is common for a single Docker image to host numerous triggers and actions that share libraries, helper functions, and baseline configuration. The SDK encourages this practice by allowing developers to define multiple classes within the same module, each appropriately marked as a trigger or an action, and then reference them individually in the manifest file. Bundling everything into one image yields several operational advantages: it reduces the overhead of maintaining disparate repositories, simplifies version control, and guarantees that all components run with identical dependency sets. This uniformity also streamlines security and compliance workflows, because a single image can undergo vulnerability scanning, penetration testing, and compliance validation once, and then be reused across countless playbooks. From a development velocity standpoint, a bug fix in a shared utility instantly benefits every trigger and action that depends on it, obviating the need to rebuild and redeploy multiple images. Furthermore, the shared‑image model dovetails naturally with container orchestration platforms such as Kubernetes, where pod templates can reference a single image and rely on environment variables or command‑line arguments to select the specific trigger or action to instantiate. As a result, organizations can maintain a curated library of approved, hardened images that accelerate playbook deployment while upholding strict governance standards.
To make an SDK‑generated module operational inside Sekoia.io, the manifest file must accurately declare the docker_parameters for each trigger and action you intend to expose. These parameters instruct the platform which entrypoint command to launch when a playbook references the component. For a trigger, the manifest typically specifies a command that starts the trigger’s listening loop, enabling it to await incoming signals. For an action, the manifest points to a short‑lived process that executes the run method, produces its output, and then exits cleanly. Correctly configuring these parameters is essential: it ensures the container starts with the right process, that signals such as SIGTERM are propagated properly, and that the platform can monitor the component’s health, resource consumption, and lifecycle events. Mistakes at this stage—such as omitting the entrypoint, mis‑specifying the command, or failing to set appropriate environment variables—are a frequent cause of deployment failures and perplexing debugging sessions. The SDK documentation therefore includes concrete examples and validation tips to help developers align their code with the platform’s expectations. Once the manifest is correctly structured, the module can be uploaded to the Sekoia.io registry, assigned a version number, and then dragged into the visual playbook builder, where non‑technical analysts can assemble sophisticated automation flows without writing a line of code.
The SDK strongly advocates the use of Pydantic for defining configuration models, a recommendation that delivers type safety, automatic validation, and informative error messages straight out of the box. By annotating self.module.configuration with a Pydantic BaseModel subclass, you explicitly declare the permissible shape and data types of the module‑level settings; the SDK then instantiates and validates the object at runtime, raising a clear exception if the supplied configuration deviates from the schema. This eradicates an entire class of bugs linked to missing keys, incorrect data types, or out‑of‑range values, while also providing self‑documenting configuration that modern IDEs can leverage for autocomplete and inline documentation. The same principle applies to trigger configurations: adding a type hint to self.configuration lets the SDK treat it as a Pydantic model, affording you validation for elements such as polling intervals, API tokens, regex patterns, or numeric thresholds. Beyond preventing runtime surprises, Pydantic models emit JSON schemas that can be shared with stakeholders, product managers, or auditors, making it far easier to communicate expected inputs and outputs. In an arena where mis‑configured automation often leads to alert fatigue, missed detections, or unnecessary noise, these safeguards translate directly into heightened reliability, faster onboarding of new playbook developers, and reduced mean time to resolve configuration‑related incidents.
Pydantic’s benefits extend well beyond static configuration to the very data contracts that govern events, action arguments, and action results. By setting the results_model attribute on a trigger class, you instruct the SDK to validate every event emitted by that trigger against the specified model, guaranteeing that downstream actions receive uniformly structured payloads and reducing the likelihood of field‑name typos or missing data. Similarly, you can annotate an action’s arguments with a Pydantic model, enabling the SDK to parse and validate incoming JSON or file‑based inputs before your custom logic runs, thereby catching structural errors early. The results_model attribute on an action works analogously for the return value, ensuring that what you send back conforms to the agreed‑upon schema and that any deviation is flagged immediately. This comprehensive modeling approach creates an explicit contract between triggers and actions, minimizing integration mishaps and enabling isolated unit testing of individual components. Teams can also version these Pydantic models alongside their code, facilitating backward‑compatible upgrades and offering a clear migration path when the schema evolves. Ultimately, treating data as a first‑class citizen with explicit, version‑checked schemas elevates the dependability of the entire automation pipeline, reduces false positives, and improves the overall signal‑to‑noise ratio for security analysts.
Adopting the sekoia-automation-sdk delivers concrete advantages for organizations that aim to modernize their security operations. To begin, prototype a simple trigger that pulls data from a source you already monitor, use the write helper to attach a relevant file, and confirm that the resulting event appears correctly in the playbook builder. Next, construct an action that reads the attached file, performs a transformation—such as parsing, enriching, or filtering—and returns the outcome via the output helper, all while employing Pydantic models to validate both inputs and outputs. Once the core loop functions satisfactorily in a local environment, containerize the module, specify the appropriate docker_parameters in the manifest, and push the image to your internal registry. Deploy the module to Sekoia.io, assign it a version, and start incorporating it into playbooks used by your SOC analysts. As confidence grows, expand the library with additional triggers and actions that share the same Docker image, capitalizing on shared utilities to reduce maintenance overhead. Keep an eye on community contributions and emerging best practices, as the SDK’s expanding ecosystem is likely to yield reusable building blocks for common tasks such as threat‑intel enrichment, automated containment, vulnerability scanning, and compliance reporting. By treating playbook development as a software engineering discipline—complete with version control, automated testing, and clear data contracts—you position your team to respond faster, adapt more readily to evolving threats, and demonstrate measurable improvements in key metrics like mean time to detect and mean time to respond.