ryu-webhook-ingress 0.1.4

Webhook ingress: the swappable public-reachability seam that lets a loopback-bound Ryu Core receive third-party webhooks (Composio triggers, per-workflow webhooks). Owns the four ingress backends (managed RyuRelay outbound SSE push, Tailscale Funnel, cloudflared quick tunnel, BYO own-relay), the path-routed inbound dispatcher with fail-closed HMAC re-verification, replay-window + delivery dedup, and the ingress-URL registry. An extracted Core capability crate — in-process default (no IPC on any hot path); the kernel couplings (composio verify/run, workflow-secret lookup, mesh funnel, auth token, data dir) are inverted through the WebhookIngressHost trait so this crate has ZERO dependency on apps/core. Public webhook ROUTES stay kernel-ingress in Core and forward into this engine (program §5).
Documentation

ryu-webhook-ingress

The swappable public-reachability seam (unified-tool-gateway epic #479, P6a) that lets a loopback-bound Ryu Core receive third-party webhooks — Composio triggers (which are webhook-delivered, with no event-pull API) and per-workflow webhooks — by giving Core a publicly-reachable URL pointed at its existing handler.

Role in the decomposition

An extracted Core capability crate, compiled into apps/core as the in-process default (no IPC on any hot path). Exposing a tunnel + deciding which backend runs is what runsCore; there is no policy here. Public webhook routes stay kernel-ingress in Core and forward inbound deliveries into this engine.

Zero dependency on apps/core. The kernel couplings (Composio verify/run, workflow-secret lookup, mesh funnel, auth token, data dir) invert through the WebhookIngressHost trait, installed by Core at boot via set_global_host.

Nothing hardcoded — the backend swap seam

The backend is a swappable Ingress enum selected by the webhook.ingress.backend pref (IngressKind, kebab-case wire form), default RyuRelay:

  • RyuRelay — the managed default: outbound SSE push (no inbound port).
  • TailscaleFunnel — via ryu-mesh's ensure_funnel.
  • Cloudflared — a quick tunnel subprocess.
  • OwnRelay — BYO public base URL (RYU_WEBHOOK_INGRESS_URL env override, else the webhook.ingress.url pref).

Backend dispatch uses native async fn trait methods + a closed enum match — no async-trait/dyn (the host seam is the one dyn boundary).

Key surface

  • Ingress / IngressKind + backend sources (RyuRelaySource, TailscaleFunnelSource, CloudflaredSource, OwnRelaySource).
  • deliver_inbound / deliver_workflow_webhook — the path-routed inbound dispatcher with fail-closed HMAC re-verification, a replay window, and delivery dedup.
  • record_delivery / last_delivery / timestamp_fresh / workflow_webhook_path.

Consumed as

Compiled-into-Core crate; Core's public webhook routes forward into it.

Deps: tokio, reqwest, futures-util, serde/serde_json, anyhow, async-trait.