Skip to content

Gateway

The gateway is the local HTTP/WebSocket edge around the companion runtime. It is useful for health checks, pairing, webhooks, A2A-style messages, companion surface routes, and admin APIs. It is not a public SaaS boundary.

Terminal window
cargo run -- gateway --host 127.0.0.1 --port 3000

For normal operation, prefer the daemon because it runs gateway, channels, scheduler, heartbeat, and runtime services together:

Terminal window
cargo run -- daemon --host 127.0.0.1 --port 3000

The safe default is local binding with pairing required:

[gateway]
host = "127.0.0.1"
port = 3000
require_pairing = true
allow_public_bind = false

If you need public reachability, put a trusted edge or tunnel in front of the runtime. Do not turn a local admin API into an unauthenticated public service.

Public routes include health, readiness, pairing, gateway OpenAPI, webhook, A2A, companion surface, and WebSocket entrypoints. When the whatsapp feature is enabled, /whatsapp is also registered for Meta webhook verification and delivery. Admin routes live under /admin/v1/* and require pairing plus explicit tenant scope, including tenant-scoped uploads at /admin/v1/uploads.

Authorization: Bearer <token>
X-Asterel-Tenant: <tenant-id>

The tenant header scopes local operator state. It is not a claim that Asterel is a hosted multi-tenant SaaS.

The gateway should normalize transport input and expose routes. It should not be the owner of memory, persona, session continuity, prompt policy, or response verification. Those belong to shared runtime/core services so Discord, gateway, and channel turns do not drift into separate products.