Getting Started
File Location
Components live inworker/src/components/<category>/:
Category Source of Truth
Component categories are defined once inpackages/shared/src/component-categories.ts.
- Backend categorization and API metadata read from this shared registry.
- Frontend schema validation and category styling also read from the same registry.
ID Naming Convention
Runner Types
Inline Component Example
Docker Component Example
ExecutionContext
Thecontext passed to execute() provides services and utilities:
Component Definition
A component is defined usingdefineComponent and must specify its inputs, outputs, and optional parameters.
Inputs vs. Parameters
Understanding the difference between Inputs and Parameters is critical for building good components.Defining Inputs (Ports)
Inputs represent the data that flows into your component from other parts of the workflow. They appear as connection handles on the left side of the node.valuePriority values:
connection-first: Use the value from the port connection if it exists, otherwise use the manual override.manual-first: Always use the manual override if a value is provided, even if a port is connected.
Defining Parameters
Parameters are configuration settings for the component that are set when the user is designing the workflow. They do not accept connections from other nodes; they are always static values (or manual strings).Parameter Editors
Theeditor field in param() determines how the field is rendered in the UI sidebar:
text: Standard text input.textarea: Multi-line text area.number: Numeric input with optional min/max.boolean: Checkbox/switch.select: Dropdown menu (requiresoptions).multi-select: Multi-selection dropdown.json: Code editor for JSON objects.secret: Masked password-style input.variable-list: Specialized editor for logic-script variables.
Visibility Rules
You can usevisibleWhen to show or hide parameters based on the values of other parameters:
Connection Types
When defining aport, you can specify its connectionType for compatibility checks in the canvas.
text, number, boolean, secret, json, file, any.
Lists: { kind: 'list', element: ConnectionType }.
Objects with contracts: { kind: 'primitive', name: 'json', contract: 'aws-credentials' }.
Entry Point Runtime Input Types
The Entry Point component supports dynamic runtime inputs that users provide when triggering workflows:
Example: Secret runtime input
- The UI shows a password field for the secret
- The value flows through as a
port.secret()output - Downstream components receive the secret string value
Dynamic Ports (resolvePorts)
Components can dynamically generate input/output ports based on parameter values:Retry Policy
Components can specify custom retry behavior (maps to Temporal activity retry):Error Handling
Use SDK error types for proper retry behavior:Analytics Output Port (Results)
Security components should include aresults output port for analytics integration. This port outputs structured findings that can be indexed into OpenSearch via the Analytics Sink.
Schema Requirements
Theresults port must output list<json> (array of records):
Required Fields
Each finding in the results array must include:
Additional fields from the scanner output should be spread into the finding object.
Finding Hash
Thefinding_hash is a stable identifier that enables deduplication across workflow runs. It should be generated from the key identifying fields of each finding.
Purpose:
- Track if a finding is new or recurring across scans
- Deduplicate findings in dashboards
- Calculate first-seen and last-seen timestamps
- Identify which findings have been resolved (no longer appearing)
Choose fields that uniquely identify a finding but remain stable across runs (avoid timestamps, random IDs, etc.).
Example Implementation
How It Works
- Component outputs
results: Each scanner outputs its findings withscannerandasset_keyfields - Connect to Analytics Sink: In the workflow canvas, connect the
resultsport to Analytics Sink’sdatainput - Indexed to OpenSearch: Each item in the array becomes a separate document with:
- Finding data at root level (nested objects serialized to JSON strings)
- Workflow context under
shipsec.*namespace - Consistent
@timestampfor all findings in the batch
Document Structure in OpenSearch
shipsec Context Fields
The Analytics Sink automatically adds workflow context under the shipsec namespace:
Example Queries
Nested objects in findings are automatically serialized to JSON strings to prevent OpenSearch field explosion (1000 field limit).
Docker Component Requirements
Shell Wrapper Pattern (Required)
All Docker-based components MUST use a shell wrapper for PTY compatibility:Why Shell Wrappers?
Pattern Decision Tree
Distroless Images (Default Entrypoint Pattern)
Many ProjectDiscovery images (subfinder, dnsx, naabu, amass, notify) are distroless and do not contain/bin/sh. For these images, omit the entrypoint field entirely and let Docker use the image’s default entrypoint:
execute() function, append tool arguments directly to command:
Distroless Go binaries (like ProjectDiscovery tools) handle PTY signals correctly.
Verified with
docker run --rm -t image args... — output streams and exits cleanly.File System Access
For detailed patterns and security guarantees, see Isolated Volumes.Quick Example
UI-Only Components
Components that are purely for UI purposes (documentation, notes):Testing
Unit Tests
Located alongside component:worker/src/components/<category>/__tests__/<component>.test.ts
bun --cwd worker test
Integration Tests (Docker)
Same folder with-integration.test.ts. Uses real Docker containers.
ENABLE_DOCKER_TESTS=true bun --cwd worker test
Testing Checklist
- Used
entrypoint: 'sh'withcommand: ['-c', 'tool "$@"', '--'] - Tested with
docker run --rm -t(PTY mode) - Container exits cleanly without hanging
- No stdin-dependent operations
- Tool arguments appended after
'--'in command array - Workflow run completes successfully
PTY Testing
E2E Tests (Full Stack)
E2E tests validate your component works with the entire platform: Backend API, Worker, Temporal, and infrastructure. Located ine2e-tests/. These tests create real workflows via the API and execute them.
Prerequisites:
E2E tests are not run in CI yet. They require the full local environment (
just dev) and are intended for manual validation during development.Complete Example
Questions?
- File access patterns: See Isolated Volumes
- SDK source:
packages/component-sdk/src/ - Example components:
worker/src/components/security/ - Bug reports: GitHub Issues