Documentation Index
Fetch the complete documentation index at: https://docs.osmedeus.org/llms.txt
Use this file to discover all available pages before exploring further.
Flows orchestrate multiple modules with dependencies and conditional execution.
Basic Flow
kind: flow
name: basic-recon
description: Basic reconnaissance flow
params:
- name: target
required: true
modules:
- name: subdomain-enum
path: modules/subdomain-enum.yaml
- name: http-probe
path: modules/http-probe.yaml
depends_on:
- subdomain-enum
- name: screenshot
path: modules/screenshot.yaml
depends_on:
- http-probe
Module Reference Fields
modules:
- name: module-name # Required: reference name
path: path/to/module.yaml # Required: module file path
depends_on: # Optional: dependency list
- other-module
condition: 'expression' # Optional: skip condition
params: # Optional: parameter overrides
key: value
name
Unique identifier for this module reference within the flow.
- name: subdomain-enum # Used in depends_on references
path
Path to the module YAML file (relative to workflow folder).
- name: nuclei
path: modules/nuclei-scan.yaml
depends_on
List of module names that must complete before this module runs.
- name: vuln-scan
path: modules/vuln.yaml
depends_on:
- subdomain-enum
- http-probe # Both must complete first
condition
JavaScript expression evaluated before module execution. Module is skipped if false.
- name: screenshot
path: modules/screenshot.yaml
depends_on: [http-probe]
condition: 'fileLength("{{Output}}/live-hosts.txt") > 0'
Common conditions:
# File has content
condition: 'fileLength("{{Output}}/data.txt") > 0'
# File exists
condition: 'fileExists("{{Output}}/targets.txt")'
# Parameter check
condition: '{{enable_vuln_scan}} == "true"'
params
Override module parameters.
- name: nuclei-fast
path: modules/nuclei-scan.yaml
params:
threads: "100"
severity: "critical,high"
Inline Modules
Modules can define steps directly instead of referencing an external YAML file. This is useful for simple, self-contained tasks that don’t warrant a separate file.
kind: flow
name: quick-recon
modules:
- name: quick-check
description: Inline health check
steps:
- name: ping
type: bash
command: ping -c 1 {{Target}}
- name: http-check
type: bash
command: curl -s -o /dev/null -w '%{http_code}' https://{{Target}}
exports:
status_code: "{{stdout}}"
- name: full-scan
path: modules/full-scan.yaml
depends_on: [quick-check]
condition: '{{status_code}} == "200"'
Inline Module Fields
| Field | Description |
|---|
name | Required. Module reference name |
steps | Inline steps (makes this an inline module) |
description | Description for the inline module |
runner | Runner type for inline module (host, docker, ssh) |
runner_config | Runner configuration for inline module |
When steps is defined, the module is treated as inline — no path is needed. Inline modules support the same step types and features as external module files.
Inline Module with Runner
modules:
- name: docker-scan
description: Run nuclei in Docker
runner: docker
runner_config:
image: projectdiscovery/nuclei:latest
volumes:
- "{{Output}}:/output"
steps:
- name: nuclei
type: bash
command: nuclei -u {{Target}} -o /output/nuclei.txt
Dependency Graph
Flows create a directed acyclic graph (DAG):
modules:
- name: A
path: modules/a.yaml
- name: B
path: modules/b.yaml
depends_on: [A]
- name: C
path: modules/c.yaml
depends_on: [A]
- name: D
path: modules/d.yaml
depends_on: [B, C]
Execution:
A # Step 1: A runs
/ \
B C # Step 2: B and C run in parallel
\ /
D # Step 3: D runs after B and C
Complex Flow Example
kind: flow
name: full-assessment
description: Complete security assessment
params:
- name: target
required: true
- name: enable_active
default: "false"
description: Enable active scanning
modules:
# Passive reconnaissance
- name: subdomain-enum
path: modules/subdomain-enum.yaml
- name: dns-enum
path: modules/dns-enum.yaml
# Both can run in parallel, both depend on nothing
# Execution: subdomain-enum and dns-enum run together
- name: http-probe
path: modules/http-probe.yaml
depends_on:
- subdomain-enum
- dns-enum
# Waits for both to complete
- name: screenshot
path: modules/screenshot.yaml
depends_on: [http-probe]
condition: 'fileLength("{{Output}}/live.txt") > 10'
- name: content-discovery
path: modules/content-discovery.yaml
depends_on: [http-probe]
# Active scanning (conditional)
- name: port-scan
path: modules/port-scan.yaml
depends_on: [subdomain-enum]
condition: '{{enable_active}} == "true"'
- name: vuln-scan
path: modules/vuln-scan.yaml
depends_on:
- http-probe
- port-scan
condition: '{{enable_active}} == "true" && fileExists("{{Output}}/live.txt")'
# Reporting
- name: generate-report
path: modules/report.yaml
depends_on:
- screenshot
- content-discovery
- vuln-scan
Running Flows
# Basic execution
osmedeus run -f full-assessment -t example.com
# With parameters
osmedeus run -f full-assessment -t example.com -p 'enable_active=true'
# Exclude specific modules
osmedeus run -f full-assessment -t example.com -x vuln-scan -x port-scan
# Dry run (preview)
osmedeus run -f full-assessment -t example.com --dry-run
Module Exclusion
Skip specific modules using exact match (-x) or substring match (-X):
# Exact match - exclude specific modules by name
osmedeus run -f full-assessment -t target -x screenshot -x port-scan
# Fuzzy match - exclude modules whose name contains the substring
osmedeus run -f full-assessment -t target -X nmap -X nuclei
| Flag | Description |
|---|
-x, --exclude <module> | Exclude module by exact name (repeatable) |
-X, --fuzzy-exclude <substr> | Exclude modules whose name contains substring (repeatable) |
Excluded modules are treated as completed (dependencies are satisfied).
Flow-Level vs Module-Level Params
# Flow definition
kind: flow
name: my-flow
params:
- name: target
required: true
- name: threads
default: "50" # Flow-level default
modules:
- name: scan
path: modules/scan.yaml
params:
threads: "{{threads}}" # Use flow param
wordlist: "/custom.txt" # Module-specific override
Resolution order:
- Module reference
params (highest priority)
- Flow-level
params
- Module’s own default params (lowest priority)
Error Handling
By default, if a module fails:
- Dependent modules are skipped
- Other independent branches continue
modules:
- name: A
path: modules/a.yaml
- name: B
path: modules/b.yaml
depends_on: [A]
# If A fails, B is skipped
- name: C
path: modules/c.yaml
# C runs regardless of A or B
Best Practices
-
Group related modules
# Passive recon group
- name: subdomain-enum
- name: dns-enum
# Active scan group
- name: port-scan
- name: vuln-scan
-
Use conditions for optional modules
- name: active-scan
condition: '{{enable_active}} == "true"'
-
Check file existence before processing
- name: process-results
condition: 'fileLength("{{Output}}/data.txt") > 0'
-
Parameterize module behavior
- name: nuclei
params:
threads: "{{threads}}"
severity: "{{severity}}"
-
Add a final reporting module
- name: report
depends_on: [all, other, modules]
Next Steps