WorkerModule is mandatory and always loaded. When explicitly configured in the modules: section, the first entry’s port sets the main engine WebSocket port. Additional entries start separate listeners — optionally with an rbac block for role-based access control. Multiple WorkerModule entries are supported.
Architecture
Workers connect via WebSocket, send a registration message with metadata (runtime, version, OS), and then exchange messages with the engine for the lifetime of the connection. On disconnect, the worker and any session-scoped triggers are cleaned up automatically.Sample Configuration
iii-config.yaml
Configuration
Top-level fields on theconfig object:
The port to listen on. For the first
WorkerModule entry this sets the main engine WebSocket port. Additional entries start separate listeners. Defaults to 49134.The host to bind to. Defaults to
0.0.0.0.Function ID to invoke before every function call from a worker on this port. Receives a
MiddlewareFunctionInput with the target function ID, payload, action, and auth context. The middleware is responsible for calling the target function and returning the result.RBAC configuration block. When present, the listener applies role-based access control to all connections. See RBAC below.
Middleware
Whenmiddleware_function_id is configured, every worker invocation on that port is routed through the middleware instead of calling the target function directly. Middleware can be used on any port, with or without RBAC.
MiddlewareFunctionInput
The middleware function receives: The middleware is responsible for calling the target function (e.g. viatrigger()) and returning the result. This gives you full control to modify, validate, or audit requests.
RBAC
When therbac block is present in a WorkerModule entry, that listener enforces role-based access control: authentication on connect, function-level authorization, and trigger registration controls.
For step-by-step instructions on enabling RBAC, writing auth and middleware functions, and connecting workers, see Worker RBAC.
RBAC Architecture
On connection to an RBAC port, the optional auth function is called with the request headers, query parameters, and client IP address. Once authenticated, workers can invoke exposed functions and register triggers subject to RBAC rules.RBAC Configuration
Function ID to invoke for authentication when a worker connects. Receives an
AuthInput with headers, query parameters, and IP address. Must return an AuthResult object. If the function fails or returns no result, the connection is rejected.List of filters that determine which functions are accessible to workers on the RBAC port. A function is accessible if it matches any filter. Two filter types are supported:
- match(“pattern”) — Wildcard pattern on the function ID.
*matches any characters. - metadata — Key-value conditions on function metadata.
Function ID to invoke when a worker attempts to register a trigger. Receives the trigger details and auth context. Must return
true to allow the registration.Function ID to invoke when a worker attempts to register a trigger type. Receives the trigger type details and auth context. Must return
true to allow the registration.Function Filters
Wildcard Match
Match functions by their ID using* as a wildcard:
Metadata Match
Match functions by their registered metadata. Values can be exact or usematch() for wildcard patterns:
expose_functions use OR logic — a function is exposed if any filter matches.
Authentication
Whenauth_function_id is configured, the function is called on every new WebSocket connection before the worker can invoke any functions.
Auth Input
The auth function receives:Auth Result
The auth function must return:Access Resolution Order
- If the function is in
forbidden_functions— denied - If the function is in
allowed_functions— allowed - If the function is
engine::channels::create— allowed (always whitelisted for channel support) - If any
expose_functionsfilter matches — allowed - Otherwise — denied
Trigger Registration
Workers on an RBAC port can register trigger types and triggers when permitted by the auth result. Trigger type registration requires both conditions:allow_trigger_type_registrationistruein the auth result- If
on_trigger_type_registration_function_idis configured, the hook returnstrue
- The trigger’s
trigger_typeis inallowed_trigger_typesfrom the auth result - If
on_trigger_registration_function_idis configured, the hook returnstrue
Channel Support
Channels work on everyWorkerModule port. The module mounts the channel WebSocket endpoint at /ws/channels/{channel_id} on the same port.
SDK workers can use createChannel() without any changes. On RBAC ports, the engine::channels::create function is automatically whitelisted to enable channel creation. Channel data transfer uses the standard channel WebSocket endpoint, which validates access via the access_key capability token.
Protocol
The Worker module uses the standard iii engine WebSocket protocol. SDK workers connect withregisterWorker() and everything works out of the box.
Worker to Server
| Type | Fields | Description |
|---|---|---|
registerworker | runtime, version, name, os, telemetry, pid | Register the worker and send metadata. |
registerfunction | function_id, metadata | Register a function. Not allowed on RBAC ports. |
unregisterfunction | function_id | Unregister a function. Not allowed on RBAC ports. |
invokefunction | invocation_id, function_id, data | Invoke a function. RBAC checks apply on RBAC ports. |
registertriggertype | id, description | Register a new trigger type. On RBAC ports, requires allow_trigger_type_registration. |
registertrigger | id, trigger_type, function_id, config | Register a trigger. On RBAC ports, requires the type to be in allowed_trigger_types. |
unregistertrigger | id | Unregister a trigger owned by this session. |
ping | — | Keepalive ping. |
Server to Worker
| Type | Fields | Description |
|---|---|---|
workerregistered | worker_id | Sent after successful connection and auth. The worker_id serves as the session ID. |
invokefunction | invocation_id, function_id, data | Engine invoking a function on the worker. |
invocationresult | invocation_id, function_id, result?, error? | Result of an invokefunction request. |
pong | — | Response to ping. |
{"type":"error","error":{...}}) and closes the connection.
Security Considerations
- The RBAC port should be the only port exposed to external networks. The main engine port should remain internal.
- Always configure
auth_function_idin production to prevent unauthenticated access on RBAC ports. - Use
expose_functionsto limit the blast radius. Prefer explicit patterns over broad wildcards likematch("*"). - The middleware function is the right place for request validation, rate limiting, and audit logging.
forbidden_functionsfrom the auth result takes precedence over all other allow rules, providing a hard deny mechanism per worker.- Trigger registrations are scoped to the session and cleaned up on disconnect.