Skip to content

Gateway Provider Readiness

Gateway providers in this document are Cloud Channel Gateway adapters. They never own OpenCode execution, sessions, workflow scheduling, or Cloud control-plane state. Every provider normalizes channel input into Cloud channel APIs and renders Cloud session events back to the channel.

Standalone Team Gateway may reuse provider packages later, but its private runtime/control-plane ownership is a separate product mode and not part of this Cloud Channel Gateway readiness matrix.

The typed source of truth is apps/gateway/src/provider-readiness.ts. The Gateway test suite verifies that this page, the matrix, and actual provider capabilities stay aligned.

Provider Identity Contract

Gateway provider configuration separates provider kind from provider instance:

  • kind is the adapter implementation, such as telegram, slack, email, or webhook.
  • id is the configured provider instance, such as telegram-main, telegram-support, slack-work, or webhook-ci.
  • channelBindingId is the Cloud control-plane binding that maps the provider instance to a headless agent and delivery route.

Kind-only ids such as telegram remain supported for existing self-hosted configs. New production configs should use explicit instance ids so multiple providers of the same kind can coexist without sharing cursors, health, deliveries, or channel-thread bindings. Legacy downstream ids such as acme-telegram are accepted for compatibility, but kind-prefixed ids are the recommended convention for new deployments.

Every provider exposes id, kind, and capabilities, and may expose runtime health. Provider readiness and diagnostics use the instance id for routing and the kind for capability/policy decisions.

Provider Readiness Matrix

Provider Tier Status Modes Auth / signing Approvals Files Contract tests
telegram Tier 1 Launch polling, webhook Bot token; webhook secret when webhook mode is enabled Inline buttons plus token fallback Upload/download packages/gateway-provider-telegram/src/telegram-provider.test.ts, packages/gateway-provider-telegram/src/telegram-retry.test.ts, apps/gateway/src/daemon.test.ts
slack Tier 1 Launch webhook Bot token and Slack signing secret Inline buttons plus token fallback Upload/download packages/gateway-provider-slack/src/slack-provider.test.ts, apps/gateway/src/daemon.test.ts
email Tier 1 Launch webhook Inbound shared secret plus stable messageId/id replay key; SMTP credentials where required Token fallback Inbound uploads capped by Gateway request-body limit; outbound artifact links packages/gateway-provider-email/src/email-provider.test.ts, apps/gateway/src/event-renderer.test.ts
webhook Tier 2 Utility webhook HMAC/timestamp shared secret for ingress and outbound delivery Inline buttons if bridge supports them; token fallback otherwise Inline inbound files capped by Gateway request-body limit; outbound links packages/gateway-provider-webhook/src/webhook-provider.test.ts, apps/gateway/src/daemon.test.ts
cli Tier 2 Utility stdio Trusted local process boundary; no public HTTP ingress Token fallback Inbound metadata; outbound links packages/gateway-provider-cli/src/cli-provider.test.ts, scripts/gateway-cloud-smoke.mjs
discord Tier 3 Later hardening (Discord Bridge) signed bridge webhook Bridge shared secret Inline buttons plus token fallback Bridge uploads/downloads capped by Gateway request-body limit packages/gateway-provider-discord/src/discord-provider.test.ts, packages/gateway-provider-webhook/src/webhook-provider.test.ts
whatsapp Tier 3 Later hardening (WhatsApp Bridge) signed bridge webhook Bridge shared secret Inline buttons plus token fallback Bridge uploads/downloads capped by Gateway request-body limit packages/gateway-provider-whatsapp/src/whatsapp-provider.test.ts, packages/gateway-provider-webhook/src/webhook-provider.test.ts
signal Tier 3 Later hardening (Signal Bridge) signed bridge webhook Bridge shared secret Token fallback Bridge uploads/downloads capped by Gateway request-body limit packages/gateway-provider-signal/src/signal-provider.test.ts, packages/gateway-provider-webhook/src/webhook-provider.test.ts
fake Tier demo Demo only local fake webhook Explicit OPEN_COWORK_GATEWAY_ENABLE_FAKE_PROVIDER=true; loopback by default Inline buttons plus token fallback In-memory test files capped by Gateway request-body limit packages/gateway-testing/src/fake-channel.test.ts, apps/gateway/src/daemon.test.ts, scripts/gateway-cloud-smoke.mjs

Tier Policy

Tier 1 providers are the launch target. They must have local provider contract tests, Gateway daemon wiring tests, signed ingress where public, approval round-trips, file behavior where advertised, and documented live-provider smoke instructions.

Tier 2 providers are local or integration utilities. They are production-safe only inside their intended boundary: signed webhook bridges for webhook, and trusted local process boundaries for cli.

Tier 3 providers are bridge-backed adapters for later live-provider hardening. They are useful for downstream experiments, but public launch does not depend on them until a live provider recipe and smoke path are promoted.

Discord, WhatsApp, and Signal are bridge-mode providers, not native platform webhook endpoints. A trusted relay must verify the native platform signature or channel-specific auth first, normalize the payload, and then re-sign it with the Open Cowork bridge shared secret. Do not point Discord Interactions, Meta WhatsApp webhooks, or an unauthenticated Signal bridge directly at Gateway; use the Tier 1 providers or the generic signed webhook provider for public ingress until native adapters are promoted.

The fake provider is not a real channel. It exists for local demos and CI smokes only. Public exposure is blocked unless a deployer explicitly opts into the demo override.

Capability Expectations

  • Inline approvals must use provider-native buttons when inlineButtons is true.
  • Channels without buttons must render /approve, /deny, /answer, or /reject token fallback commands.
  • Channels with message editing may update streaming assistant output in place.
  • Channels without message editing must chunk or buffer output.
  • Files are only sent as provider files when the provider advertises download support and the artifact fits provider limits.
  • Otherwise, artifacts render as Cloud artifact links.
  • Typing indicators are best-effort and must never block prompt execution.

Security Expectations

  • Public webhook providers must fail closed without signing/HMAC/shared-secret verification.
  • Gateway and Standalone Gateway webhook HTTP surfaces apply source-scoped request throttles with Retry-After before provider dispatch.
  • Generic webhook outbound delivery is signed with timestamped HMAC headers by default; legacy shared-secret headers are local compatibility only.
  • Gateway service-token authority is separate from inbound actor authority. Cloud resolves the channel actor and enforces approval authority.
  • Production providers must map incoming messages, commands, and interactions to stable provider event ids before Gateway prompts Cloud. Replaying the same signed provider event after a Gateway restart must hit the Cloud provider-event claim and produce no second prompt.
  • Provider sends must preserve the Cloud delivery id as the provider delivery id when the provider API allows it. Webhook and bridge providers must also send that value as deliveryId, idempotencyKey, and x-open-cowork-gateway-delivery-id.
  • Diagnostics, logs, provider health, delivery summaries, and metrics must not expose raw provider tokens, webhook secrets, API tokens, local paths, or signed artifact URLs.
  • Local/demo providers must remain loopback-only by default.

Live Smoke Instructions

Use pnpm deploy:gateway:smoke against a real Cloud URL when validating a deployed appliance. The smoke creates an ephemeral gateway-scoped token, proves prompt-to-session continuation, exercises approval fallback, creates an async delivery, verifies delivery acknowledgement, and revokes the token.

Provider-specific live checks:

  • Telegram: start with polling for private installs; webhook mode requires an HTTPS public URL and webhook secret.
  • Slack: configure Events and Interactivity to POST to /webhooks/slack; verify signed events and button callbacks.
  • Email: send an inbound webhook/mail fixture and verify the threaded reply.
  • Webhook: send signed bridge payloads and verify unsigned, stale, and replayed requests fail.
  • CLI: use only for trusted local smoke and never expose it over public HTTP.