Skip to main content
Pin info to the side panel. Or add any other component.
Runners execute commands in different environments.

Runner Types

RunnerDescriptionUse Case
hostLocal machine executionDefault, fast, no isolation
dockerContainer executionIsolated, reproducible, tool packaging
sshRemote machine executionDistributed scanning, remote resources

Host Runner

Executes commands on the local machine using the shell.

Configuration

kind: module
name: local-scan
runner: host        # Default, can be omitted

steps:
  - name: scan
    type: bash
    command: nmap -sV {{target}}

Characteristics

  • Uses sh -c for command execution
  • Inherits environment from Osmedeus process
  • No isolation between steps
  • Fastest execution

Docker Runner

Executes commands inside Docker containers.

Module-Level Configuration

kind: module
name: docker-scan
runner: docker
runner_config:
  image: projectdiscovery/nuclei:latest
  volumes:
    - "{{Output}}:/output"
  environment:
    - "API_KEY={{api_key}}"
  persistent: false    # Default: ephemeral containers

steps:
  - name: scan
    type: bash
    command: nuclei -u {{target}} -o /output/nuclei.txt

Runner Config Options

OptionTypeDescription
imagestringDocker image (required)
volumes[]stringVolume mounts (host:container)
environment[]stringEnvironment variables
persistentboolKeep container running between steps
networkstringDocker network name
extra_args[]stringAdditional docker run arguments

Execution Modes

Ephemeral (default): Each step runs docker run --rm
runner_config:
  image: alpine:latest
  persistent: false    # New container per step
Persistent: Container stays running, steps use docker exec
runner_config:
  image: alpine:latest
  persistent: true     # Reuse container

Per-Step Docker (remote-bash)

Use Docker for specific steps without module-level runner:
kind: module
name: hybrid
runner: host

steps:
  - name: local-step
    type: bash
    command: echo "Running locally"

  - name: docker-step
    type: remote-bash
    step_runner: docker
    step_runner_config:
      image: alpine:latest
      volumes:
        - "{{Output}}:/output"
    command: cat /etc/os-release

SSH Runner

Executes commands on remote machines via SSH.

Module-Level Configuration

kind: module
name: remote-scan
runner: ssh
runner_config:
  host: scanner.example.com
  port: 22
  user: scanner
  key_file: ~/.ssh/scanner_key
  # OR
  password: secret     # Not recommended

steps:
  - name: scan
    type: bash
    command: nmap -sV {{target}}

Runner Config Options

OptionTypeDescription
hoststringSSH hostname (required)
portintSSH port (default: 22)
userstringSSH username (required)
key_filestringPath to private key
passwordstringSSH password (less secure)
known_hostsstringPath to known_hosts file

Per-Step SSH (remote-bash)

Use SSH for specific steps:
kind: module
name: hybrid
runner: host

steps:
  - name: local-prep
    type: bash
    command: echo {{target}} > /tmp/target.txt

  - name: remote-scan
    type: remote-bash
    step_runner: ssh
    step_runner_config:
      host: "{{ssh_host}}"
      port: 22
      user: "{{ssh_user}}"
      key_file: ~/.ssh/id_rsa
    command: nmap -sV {{target}}

File Transfer

Copy files from remote to local:
- name: remote-scan
  type: remote-bash
  step_runner: ssh
  step_runner_config:
    host: scanner.example.com
    user: scanner
    key_file: ~/.ssh/key
  command: nmap -sV {{target}} -oN /tmp/result.txt
  step_remote_file: /tmp/result.txt
  host_output_file: "{{Output}}/nmap-result.txt"

Runner Interface

All runners implement this interface:
type Runner interface {
    Execute(ctx context.Context, command string) (*CommandResult, error)
    Setup(ctx context.Context) error
    Cleanup(ctx context.Context) error
    Type() core.RunnerType
    IsRemote() bool
}

type CommandResult struct {
    Output   string
    ExitCode int
    Error    error
}

Lifecycle

1. Setup()    - Initialize runner (connect SSH, start container)
2. Execute()  - Run commands (called per step)
3. Cleanup()  - Tear down (disconnect, remove container)

Choosing a Runner

ScenarioRecommended Runner
Simple local scanshost
Tool isolationdocker
Reproducible buildsdocker
Remote server with toolsssh
Distributed scanningssh or distributed mode
Mixed environmentsremote-bash per step

Best Practices

Docker

  1. Use specific image tags
    image: projectdiscovery/nuclei:v2.9.0  # Good
    image: projectdiscovery/nuclei:latest  # Less predictable
    
  2. Mount only needed volumes
    volumes:
      - "{{Output}}:/output:rw"
      - "{{Data}}/templates:/templates:ro"
    
  3. Use persistent mode for many steps
    runner_config:
      persistent: true  # Faster for multi-step workflows
    

SSH

  1. Use key authentication
    key_file: ~/.ssh/scanner_key
    # Avoid: password: secret
    
  2. Parameterize host details
    runner_config:
      host: "{{ssh_host}}"
      user: "{{ssh_user}}"
    
  3. Check remote tool availability
    - name: check-tools
      type: bash
      command: which nmap nuclei httpx
    

remote-bash

  1. Use for hybrid workflows
    • Local file preparation
    • Remote heavy scanning
    • Local result processing
  2. Transfer results back
    step_remote_file: /remote/output.txt
    host_output_file: "{{Output}}/output.txt"
    

Next Steps