Skip to main content

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:
KindPurposeContains
moduleSingle execution unitSteps array
flowOrchestrate modulesModules array
fragmentReusable step collectionSteps array

Workflow Structure

Workflow Type

Step Type

Workflow Inheritance

Workflows support inheritance through the extends field, allowing child workflows to inherit and override parent configurations.

Inheritance Architecture

InheritanceResolver Type

Resolution Process

  1. Circular Detection: Track workflows being resolved to detect circular inheritance
  2. Parent Loading: Load parent by name (same directory) or path (relative/absolute)
  3. Recursive Resolution: If parent also extends, resolve recursively
  4. Kind Validation: Child and parent must have matching kind (module/flow)
  5. Merge: Apply child’s direct fields and override section

Override Modes

WorkflowOverride Type

StepsOverride Type

Merge Priority

Parent Resolution Order

  1. Same directory as child (name + .yaml/.yml)
  2. Relative path from child’s directory
  3. Workflows directory search by name
  4. Absolute path

Fragments

Fragments are reusable step collections that can be embedded in modules.

Fragment Definition

Fragment Include

Modules can include fragments using the includes field:

FragmentInclude Type

Fragment Resolution

  1. Loading: Fragments are loaded during workflow parsing
  2. Validation: Fragment kind must be fragment
  3. Parameter Binding: Include params merged with fragment defaults
  4. Step Expansion: Fragment steps are embedded at execution time

Fragment Step Type

Fragment Execution

When a fragment step is executed:
  1. Resolve fragment from includes by alias
  2. Merge override params with include params
  3. Execute fragment steps in sequence
  4. Return combined results

Linting System

The workflow linter validates YAML workflows for correctness and best practices.

Linting Architecture

Built-in Rules

RuleSeverityDescription
missing-required-fieldwarningRequired fields (name, kind, type) missing
duplicate-step-namewarningMultiple steps with same name
empty-stepwarningStep has no executable content
unused-variableinfoVariable exported but never used
undefined-variablewarningVariable referenced but not defined
invalid-gotowarningDecision goto references non-existent step
invalid-depends-onwarningdepends_on references non-existent step
circular-dependencywarningCircular step dependencies detected

LinterRule Interface

LintIssue Type

Running the Linter

CLI Usage

Output Formats

Pretty (default):
JSON:
GitHub Actions:

Disabling Rules

Custom Rules

Implement the LinterRule interface:

Decision Routing

Steps support conditional branching:

DecisionConfig Type

Workflow Execution Context

Best Practices

Workflow Design

  1. Use fragments for reusable step collections
  2. Keep modules focused - Single responsibility
  3. Use flows to orchestrate complex pipelines
  4. Leverage decision routing for adaptive workflows
  5. Define dependencies with depends_on for DAG execution

Performance

  1. Use parallel_commands for independent commands
  2. Use parallel_functions for independent function calls
  3. Set appropriate timeouts to prevent hanging
  4. Use foreach with appropriate thread counts

Validation

  1. Run linter before deploying workflows
  2. Use CI integration with --check --format github
  3. Enable all rules during development
  4. Use type annotations in params for validation

Error Handling

  1. Use on_error handlers for graceful failures
  2. Use pre_condition to skip steps safely
  3. Export meaningful error information
  4. Log appropriately for debugging