Skip to main content
Routes map a domain and published port into a room. Use them when you want a stable URL for something running inside a room, such as a web app, webhook endpoint, or HTTP integration. This is the normal way to publish an HTTP service from a room. A common pattern is: an agent or service creates a web app in the room, serves it on a published port, and then a route gives that app a stable URL. Routes can front either a fully public site or a private app protected by MeshAgent. For browser apps, MeshAgent can act as an identity-aware proxy in front of your service: it authenticates the user, checks that they are allowed into the room, and only then forwards the request to your app. For deployment basics, see Deploy Services with MeshAgent. Routes are managed from the MeshAgent CLI.

How routes work

  • A service in the room listens on an HTTP port.
  • That port is marked as published in the service config.
  • The route maps a domain to that room and published port.
  • When a request arrives, MeshAgent resolves the room and port, applies the port’s security rules, and then proxies the request to the service.

Create a route

Use a MeshAgent-managed domain such as *.meshagent.app:
  1. Deploy a service that exposes an HTTP endpoint and marks its port as published.
  2. Create a route:
meshagent route create --room my-room --port 5002 --domain my-app.meshagent.app
  1. The route is ready as soon as it is created.

Mark the port as published

In your service config, the HTTP port must be marked as published:
ports:
  - num: 5002
    type: http
    published: true

Public and private published ports

published: true makes a port routable from a route. public controls whether that routed URL is open to the internet or protected by MeshAgent:
  • public: true: MeshAgent forwards requests without requiring room authentication.
  • public: false: MeshAgent requires the caller to authenticate before the request can reach the app.
  • If you omit public, the port is treated as private.
For API clients and server-to-server callers, a private published port expects a participant token:
Authorization: Bearer <participant-token>
That token must be valid for the room. If the caller does not have access to the room, MeshAgent rejects the request before it reaches your app.

Integrated security for browser apps

For browser-based apps, use cookie validation so MeshAgent behaves like an identity-aware proxy in front of your route. This is the easiest way to publish a private app without making the app itself handle MeshAgent tokens directly.
ports:
  - num: 5002
    type: http
    published: true
    public: false
    liveness: /healthz
    annotations:
      meshagent.request.validation.method: cookie
You can set meshagent.request.validation.method: cookie on the port or on a specific endpoint. Endpoint annotations override port annotations. With that configuration, the request flow looks like this:
  1. A user visits the routed URL.
  2. If they do not already have a valid MeshAgent IAP session for that route, MeshAgent redirects the browser to sign in.
  3. After sign-in, MeshAgent stores a secure, HTTP-only session cookie and retries the request through the route.
  4. On each request, MeshAgent validates that the session still maps to a participant token for the target room.
  5. If the user is not allowed in the room, the request is rejected before it reaches your app.
This gives you a stable URL with MeshAgent-managed authentication and room-level authorization in front of the service. For normal browser navigation, unauthenticated GET requests are redirected into the login flow automatically. Non-GET requests without a valid session are rejected until the browser has signed in.

Headers your app receives

When a request passes through cookie-based IAP, MeshAgent removes the internal __meshagent_iap cookie before forwarding the request to your app and adds trusted identity headers:
HeaderMeaning
X-MESHAGENT-USERThe participant token name, typically the signed-in user’s email or display identity.
X-MESHAGENT-API-SCOPEThe participant token API permissions, serialized as JSON. If the token has no API grant, this is {}.
These headers are intended for the destination app to consume. MeshAgent also strips any client-supplied X-MESHAGENT-USER or X-MESHAGENT-API-SCOPE headers before forwarding the request, so callers cannot spoof them without actually going through MeshAgent IAP.

Queue-backed routes and room-secret validation

Routes are not limited to proxying traffic into an HTTP app. They can also turn incoming HTTP requests into queue messages for agents or workers inside the room. This is useful for webhook ingestion patterns where you want:
  • a stable public URL
  • signature validation at the edge
  • no always-on HTTP app inside the room
  • an internal queue that workers can process asynchronously
When meshagent.request.queue is configured on the matched port or endpoint, MeshAgent enqueues the request body instead of proxying the request to a destination app.
ports:
  - num: 5002
    type: http
    published: true
    public: false
    annotations:
      meshagent.request.queue: inbound-webhooks
      meshagent.request.processor: webhook-gateway
      meshagent.request.validation.method: stripe
      meshagent.request.validation.secret: stripe-webhook-secret
With that configuration:
  1. A request arrives at the route.
  2. MeshAgent validates the request using the configured validation method.
  3. MeshAgent reads the validation secret from the room as the configured processor identity.
  4. If validation succeeds, MeshAgent publishes the request body to the queue.
  5. MeshAgent returns 202 Accepted.
Today the queued message payload is:
{"body":"<raw request body text>"}

Required annotations

AnnotationPurpose
meshagent.request.queueQueue name to publish into.
meshagent.request.processorIn-room identity MeshAgent uses when reading the secret and publishing the work.
meshagent.request.validation.methodRequest validation method.
meshagent.request.validation.secretRoom secret id used for signature verification.
You can place these annotations on the port or on a specific endpoint. Endpoint annotations override port annotations.

Secret-backed validation

The validation secret is not copied into the route itself. Instead, MeshAgent reads it from room secrets at request time and uses it to verify the incoming webhook or signed request before anything is placed on the queue. This keeps the shared secret inside the room security boundary while still letting you publish an external URL. Supported validation methods currently include:
  • github
  • salesforce
  • sentry
  • slack
  • shopify
  • stripe
  • twilio
  • zendesk

What to store in the room secret

Store the provider’s original shared secret value in the room secret. Do not store:
  • the incoming signature header value
  • a computed HMAC or digest
  • a JSON wrapper object unless the provider explicitly gives you a plain secret inside it
Use the raw secret string or key that the provider tells you to use for request verification.
MethodSecret value to store in the roomProvider docs
githubThe webhook secret token you configured for that GitHub webhook.GitHub: Validating webhook deliveries
slackYour Slack app’s signing secret.Slack: Verifying requests from Slack
stripeThe webhook endpoint’s signing secret. This is not a Stripe API key.Stripe: Receive events with an HTTPS server
shopifyFor Shopify app webhooks, your app client secret.Shopify: Deliver webhooks through HTTPS, Shopify: About client credentials
twilioYour Twilio Auth Token used for request validation.Twilio: Security, Twilio: REST API Auth Token
zendeskThe webhook signing secret key from the Zendesk webhook configuration.Zendesk: Verifying webhook authenticity
sentryThe Sentry service hook secret value for that hook.Sentry: Register a New Service Hook, Sentry: Retrieve a Service Hook
salesforceThe signing key or shared secret for the Salesforce webhook product that is sending the request. Common cases are Marketing Cloud ENS callback signature keys and Data Cloud generated signing keys.Salesforce Marketing Cloud ENS: Notification Signing, Salesforce Data Cloud: Generate a Secret Key for Signature Validation, Salesforce Data Cloud: Payload Signature
Queue-backed validated routes must remain non-public. They are intended for authenticated or signature-validated ingress handled by MeshAgent, not open anonymous forwarding.

Liveness and startup behavior

liveness is the HTTP path MeshAgent uses to decide when a published port is actually ready to serve traffic.
ports:
  - num: 5002
    type: http
    published: true
    liveness: /healthz
When a request hits a route and MeshAgent cannot connect to the target port yet, it checks the liveness URL and waits for it to return 2xx. Once the service is live, MeshAgent retries the original request. This matters during startup, cold starts, and restarts:
  • With a liveness URL, MeshAgent can wait for the app to finish booting instead of immediately failing the first request.
  • Without a liveness URL, an early request is more likely to fail with a bad gateway while the process is still starting.
You should give published HTTP ports a liveness URL that is:
  • Cheap to evaluate.
  • Available without external user auth.
  • Wired to real readiness, not just process start.
A good pattern is /healthz or /ready returning 200 only after the app is ready to serve the same traffic the route will send.

Manage routes

meshagent route list
meshagent route show my-app.meshagent.app
meshagent route update my-app.meshagent.app --port 5003
meshagent route delete my-app.meshagent.app
To create or update a route, you need permission to administer the target room.