Skip to content
Registry

rbac-proxy

v1.0.7

RBAC boundary proxy for the iii worker protocol — auth, gating, namespacing, middleware, and engine:: result filtering on its own port.

license: Apache-2.0authorizationmiddlewareproxyrbacsecurity

Install

bash
iii trigger compose::add worker=rbac-proxy@1.0.7

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

rbac-proxy

A standalone iii worker that puts the engine's role-based access control in front of the engine instead of inside it. It opens its own configurable WebSocket port, speaks the iii worker protocol verbatim, and transparently reverse-proxies every frame — functions and channels — to a trusted engine listener, while at the boundary it:

  • authenticates each connection (the operator's auth_function_id),
  • gates every invocation (vendored is_function_allowed: forbidden > allowed > infrastructure carve-out > expose_functions > deny),
  • gates trigger bindings to functions the session may actually invoke,
  • namespaces a session's registrations behind function_registration_prefix,
  • runs middleware and the three registration hooks, and
  • rewrites the results of the eight engine::* discovery functions so a caller only ever sees the surface it is allowed to invoke.

It is the console reverse-proxy pattern (src/proxy.rs: one outbound engine WebSocket per inbound connection) with an RBAC interceptor spliced into the pump and a second proxied route for /ws/channels/{id}.

The RBAC decision logic is vendored verbatim from the engine (engine/src/workers/worker/rbac_config.rs), so a connection through rbac-proxy is gated byte-for-byte as the same connection through an engine iii-worker-manager RBAC listener would be — the proxy is just a different, out-of-process home for the same contract (it can front a remote or managed engine, scale and harden independently, and shrink an auth bug's blast radius to the proxy alone).

Full design: tech-specs/2026-06-rbac-proxy-worker/.

Install

iii trigger compose::add worker=rbac-proxy

Requires a trusted engine listener with no rbac block (the proxy is the public door; the engine port stays internal) and the configuration worker (required boot dependency).

Run

rbac-proxy --url ws://127.0.0.1:49134
  • --url — the engine WebSocket URL for the proxy's control connection, and the default upstream for the data plane.
  • --config — optional one-time seed installed as the configuration entry's initial_value when none exists yet.
  • --manifest — print the publish manifest as JSON and exit.

Configuration

Config lives in the configuration worker under id rbac-proxy (no committed config.yaml; WorkerConfig::default() seeds first boot, with engine_url defaulting to --url). Equivalent YAML an operator would configuration::set:

host: 0.0.0.0
port: 49200                       # the public RBAC port
engine_url: ws://127.0.0.1:49134  # the trusted internal engine listener
expose_worker_internals: false    # strip pid/ip/metrics from engine::workers::* results
middleware_function_id: my-project::middleware-function
rbac:
  auth_function_id: my-project::auth-function
  on_function_registration_function_id: my-project::on-function-reg
  on_trigger_registration_function_id: my-project::on-trigger-reg
  on_trigger_type_registration_function_id: my-project::on-trigger-type-reg
  expose_functions:
    - match("api::*")        # wildcard, anchored both ends, * = any run of chars
    - match("*::public")
    - metadata:              # all keys AND'd; filters OR'd
        public: true

Hot reload: a host/port change rebinds the public listener (last-good on bind failure — the previous listener and config are kept); everything else (engine_url, rbac.*, middleware_function_id, expose_worker_internals) takes effect on the next connection.

Security. Only the proxy's RBAC port should face untrusted networks. Always set auth_function_id on a public proxy — with no auth function, expose_functions alone gates access and every connection is admitted.

Functions

  • rbac-proxy::status — read-only health/identity probe (bound host/port, the credential-redacted engine URL, whether RBAC is enabled, live connection count, version).
  • rbac-proxy::on-config-change, rbac-proxy::on-functions-available — internal trigger handlers (config hot reload and catalog-cache invalidation); never agent-callable (denied in iii-permissions.yaml).

Local development & testing

cargo test                  # engine-free unit tests + golden schema + manifest
UPDATE_GOLDENS=1 cargo test  # regenerate tests/golden/ after an intentional surface change

tests/integration.rs boots a real iii engine + the proxy and drives a downstream worker through the proxy port (exposed call, forbidden call, forbidden trigger binding, channel round-trip, filtered discovery). It self-skips when the iii binary is absent or the proxy does not come up (e.g. the configuration worker is not deployed).

Search the registry

Find workers, kits and executables, or jump to a page.