Workflow Architecture
Workflows are the core abstraction in Osmedeus, defining automated security tasks through YAML configuration. This document covers the workflow system architecture, including fragments and the linting system.Workflow Kinds
Osmedeus supports three workflow kinds:| Kind | Purpose | Contains |
|---|---|---|
module | Single execution unit | Steps array |
flow | Orchestrate modules | Modules array |
fragment | Reusable step collection | Steps array |
Workflow Structure
Workflow Type
Step Type
Workflow Inheritance
Workflows support inheritance through theextends field, allowing child workflows to inherit and override parent configurations.
Inheritance Architecture
InheritanceResolver Type
Resolution Process
- Circular Detection: Track workflows being resolved to detect circular inheritance
- Parent Loading: Load parent by name (same directory) or path (relative/absolute)
- Recursive Resolution: If parent also extends, resolve recursively
- Kind Validation: Child and parent must have matching
kind(module/flow) - Merge: Apply child’s direct fields and override section
Override Modes
WorkflowOverride Type
StepsOverride Type
Merge Priority
Parent Resolution Order
- Same directory as child (name + .yaml/.yml)
- Relative path from child’s directory
- Workflows directory search by name
- Absolute path
Fragments
Fragments are reusable step collections that can be embedded in modules.Fragment Definition
Fragment Include
Modules can include fragments using theincludes field:
FragmentInclude Type
Fragment Resolution
- Loading: Fragments are loaded during workflow parsing
- Validation: Fragment kind must be
fragment - Parameter Binding: Include params merged with fragment defaults
- Step Expansion: Fragment steps are embedded at execution time
Fragment Step Type
Fragment Execution
When a fragment step is executed:- Resolve fragment from includes by alias
- Merge override params with include params
- Execute fragment steps in sequence
- Return combined results
Linting System
The workflow linter validates YAML workflows for correctness and best practices.Linting Architecture
Built-in Rules
| Rule | Severity | Description |
|---|---|---|
missing-required-field | warning | Required fields (name, kind, type) missing |
duplicate-step-name | warning | Multiple steps with same name |
empty-step | warning | Step has no executable content |
unused-variable | info | Variable exported but never used |
undefined-variable | warning | Variable referenced but not defined |
invalid-goto | warning | Decision goto references non-existent step |
invalid-depends-on | warning | depends_on references non-existent step |
circular-dependency | warning | Circular step dependencies detected |
LinterRule Interface
LintIssue Type
Running the Linter
CLI Usage
Output Formats
Pretty (default):Disabling Rules
Custom Rules
Implement theLinterRule interface:
Decision Routing
Steps support conditional branching:DecisionConfig Type
Workflow Execution Context
Best Practices
Workflow Design
- Use fragments for reusable step collections
- Keep modules focused - Single responsibility
- Use flows to orchestrate complex pipelines
- Leverage decision routing for adaptive workflows
- Define dependencies with
depends_onfor DAG execution
Performance
- Use parallel_commands for independent commands
- Use parallel_functions for independent function calls
- Set appropriate timeouts to prevent hanging
- Use foreach with appropriate thread counts
Validation
- Run linter before deploying workflows
- Use CI integration with
--check --format github - Enable all rules during development
- Use type annotations in params for validation
Error Handling
- Use on_error handlers for graceful failures
- Use pre_condition to skip steps safely
- Export meaningful error information
- Log appropriately for debugging