iii-engine-config
Configure a managed iii engine through worker-compose.yaml or a directly supervised engine through config.yaml. Use for engine ports, RBAC listeners, streams, sandboxes, and configuration storage.
By iii-hq · 2,514 installs
npx skills add iii-hq/iii --skill iii-engine-config
Source repository · Upstream listing
Engine Config
iii has two engine configuration modes. Do not mix them.
Managed Compose engine
The presence of engine: means that Compose owns the engine process. Engine worker values are
direct mappings; there is no nested config: field.
Start it with:
engine.url defaults to ws://127.0.0.1:49134 and uses Compose's ${VAR: default} expansion.
engine.workers stays opaque until the engine reads the generated YAML, so its values use
${VAR:default} and retain numeric types. Compose materializes an owner only config under
<project dir /.iii/compose/<daemon namespace / and removes it after clean shutdown. With
III COMPOSE STATE DIR , it uses <state root /<project slug /<daemon namespace / . Changing engine:
requires restarting Compose. Do not combine a managed file with explicit engine .
Allowed engine worker base names are:
configuration
iii worker manager
iii http functions
iii stream
iii sandbox
Use instance for another instance of an allowed worker. iii engine functions ,
iii telemetry , and iii observability are injected automatically and must not be declared.
HTTP, cron, queue, state, pubsub, bridge, application, and custom workers belong under
containers: . Add registry packages with:
Observers
Since 0.25 the engine reads an optional top level observers: section ( iii observe explains the
model). Every key is optional; these are the defaults:
In config.yaml it sits next to workers: . In a managed Compose file it goes under
engine.observers and is passed through as written.
Unknown keys and zero counts or depth are rejected at load; zero timeouts only warn. Changes need
an engine restart.
observers.local dispatch: false turns off in process calls for every worker.
Inspect live observers with engine::observers::list({ function id?, namespace?, worker? }) and
engine::observers::get({ id }) (results are filtered to functions the caller may invoke).
engine::observers::dispose({ id }) is allowed for the observing worker and unrestricted callers.
Metrics: iii.observer.activations.total{function id,delivery} ,
iii.observer.dropped.total{function id,reason} , iii.observers{state} ,
iii.observer.reports.total{function id} ,
iii.observer.activation.failures.total{function id,reason} ; locally dispatched calls are counted
in iii.invocations.total with dispatch="local" .
RBAC with rbac proxy
Keep the engine port internal and put the rbac proxy worker in front of it when
untrusted workers, browsers, or agents need to connect:
rbac proxy opens its own WebSocket port, speaks the worker protocol verbatim, and at the boundary
authenticates each connection ( rbac.auth function id ), gates every invocation and trigger binding
( rbac.expose functions , plus allowed functions / forbidden functions from the auth result),
namespaces a session's registrations ( function registration prefix ), runs
middleware function id and the registration hooks, and filters engine:: discovery results to
what the caller may invoke. Its settings live in the configuration worker under id rbac proxy :
RBAC is mandatory on untrusted networks: only the proxy's port may face one, never the engine port,
and a public proxy must always set auth function id . Full schema: https://workers.iii.dev/workers/rbac proxy.
Observers under RBAC (0.25 engine): creating one requires that the session may invoke both the
observed function and the target, or it fails with FORBIDDEN . The engine's rbac: settings
accept on observer registration function id , a hook with the same contract as
on trigger registration function id : an object answer may rewrite function id ,
target function id , args , filters , and metadata ; any other answer denies with FORBIDDEN .
Sessions with a middleware function id get no local dispatch, so the middleware always runs.
Check the rbac proxy worker's docs for the version that forwards the observe messages.
Directly supervised engine
Keep list shaped config.yaml only when systemd, Kubernetes, or another supervisor owns the
engine:
Start the engine and external Compose daemon separately:
The external Compose file must omit engine: . III URL may replace engine . Direct config
expansion uses ${VAR:default} and accepts only the same five engine owned worker types. Any
project worker stops startup/reload with UNSUPPORTED CONFIG WORKERS .
Security and operations
Bind the engine port to 127.0.0.1 ; expose only the rbac proxy port.
Set rbac.auth function id on every public proxy and keep expose functions narrow.
Keep secrets in environment backed configuration; do not commit literal credentials.
Preserve configuration, stream, state, and queue storage paths during migrations.
Use compose::status for process ownership and engine::workers::list for live connections.
Use iii ps to find iii processes on the machine, including orphaned workers, and iii kill orphans , port or compose to stop them.
compose::add never edits engine: or restarts the engine.
When to Use
Use this skill for managed engine: maps, direct config.yaml , engine owned workers, ports,
adapters, RBAC via rbac proxy , or engine lifecycle selection.
Use it when migrating engine worker blocks into Compose.
Boundaries
Project worker lifecycle belongs to Compose, not config.yaml or iii worker .
For function and trigger code, use iii core primitives ; for observer code and filters, use
iii observe .
For worker specific HTTP, queue, cron, state, or pubsub behavior, use that worker's docs.