Gateway
gateway is Skippr Cloud’s HTTP and WebSocket API Gateway: you create Apis, routes, and integrations, attach auth, and bind domains. The same product serves Skippr’s own platform APIs — tables, queue, auth, and the rest are Apis on the platform edge today.
Status: Preview (partial) — platform HTTP edge is live (TLS, SigV4, JWT, routing to managed services). Tenant API catalog CRUD is live (CreateApi / Route / Integration / Authorizer Get·List·Delete / UpdateIntegration / AttachDomain / CreateDomainName). Platform hostnames use wildcard DNS *.gateway.{region}.cloud.skippr.io. Coarse per-IP and per-credential rate limits apply at the edge. FUNCTION / EVENTS_PUT execute is implemented in the gateway binary and marked coming soon in the compatibility matrix until live dogfood e2e is green. WebSocket (WSS, connection registry, PostToConnection) is implemented for single-node Preview (local delivery + NATS KV metadata; multi-node fan-out is out of Preview) and remains coming soon in the matrix until live WSS e2e. TLS today uses the platform cert (CERT_PATH / KEY_PATH); per-host SNI from GATEWAY_CERTS_DIR/{hostname}/ is not yet shipped.
What you get
- Apis — named APIs with
ProtocolTypeHTTPorWEBSOCKET(no stages —CreateStage/DeployStageare not part of the product) - Routes — HTTP: method + path. WebSocket: route keys (
CONNECT,DISCONNECT,DEFAULT, or custom keys) - Integrations — backends: functions Invoke (
FUNCTION), events PutEvents (EVENTS_PUT), or platform dogfood (CLOUD_SERVICE, HTTP only) - Authorizers — Cloud JWT, SigV4, attach an auth user pool, or public (
NONE) - Domains — platform hostname per Api; custom domain via dns + certs, or CNAME to the platform hostname
- WebSocket push —
PostToConnectionto send a frame to a live connection (coming soon) - Platform edge — sole HTTPS entry for all Cloud JSON APIs (live today)
Concepts
| Term | Meaning |
|---|---|
| Api | Your API — primary unit; HTTP or WEBSOCKET; owns routes |
| Route | HTTP: e.g. POST /orders. WebSocket: a route key such as CONNECT or sendMessage |
| Integration | Backend binding: FUNCTION, EVENTS_PUT, or CLOUD_SERVICE (HTTP dogfood only) |
| Authorizer | How a route authenticates callers |
| ConnectionId | Opaque id for a live WebSocket connection (assigned at connect) |
| Platform API hostname | {api_id}.gateway.eu-central-1.cloud.skippr.io |
Access
| Control plane | https://gateway.eu-central-1.cloud.skippr.io or https://api.cloud.skippr.io with X-Amz-Target: CloudGateway.* |
| Platform edge (live) | Per-service hostnames below; shared front https://api.cloud.skippr.io |
| Auth | SigV4 and/or Cloud JWT via Auth |
| Region | eu-central-1 (v1 default) |
You MUST NOT call JSON service ports directly. All HTTPS/JSON APIs go through the gateway with authentication. streams produce/consume uses the streams protocol on port 9092 — connect streams clients directly to streams.eu-central-1.cloud.skippr.io:9092 with OAUTHBEARER. Do not hairpin streams protocol wire through this gateway.
Platform service hostnames (live today)
These are platform Apis on the edge — same gateway product, bootstrapped for Skippr Cloud services:
| Service | Hostname |
|---|---|
| tables | tables.eu-central-1.cloud.skippr.io |
| streams | streams.eu-central-1.cloud.skippr.io (streams protocol port :9092; not SQS) |
| queue | queue.eu-central-1.cloud.skippr.io |
| events | events.eu-central-1.cloud.skippr.io |
| scheduler | scheduler.eu-central-1.cloud.skippr.io |
| secrets | secrets.eu-central-1.cloud.skippr.io |
| functions | functions.eu-central-1.cloud.skippr.io |
| machines | machines.eu-central-1.cloud.skippr.io |
| objects | objects.cloud.skippr.io |
| logs | logs.eu-central-1.cloud.skippr.io |
| elt | elt.eu-central-1.cloud.skippr.io |
| auth | auth.cloud.skippr.io |
| gateway / API front | api.cloud.skippr.io, gateway.eu-central-1.cloud.skippr.io |
Operations
| Operation | Notes |
|---|---|
GET /healthz on api.cloud.skippr.io | Live — unauthenticated; returns {"status":"ok"} |
| Platform edge routing (SigV4 / JWT) | Live — reach managed services via hostnames above |
CloudGateway.CreateApi | Live |
CloudGateway.CreateRoute | Live |
CloudGateway.CreateIntegration | Live |
CloudGateway.CreateAuthorizer | Live |
CloudGateway.GetAuthorizer / ListAuthorizers / DeleteAuthorizer | Live |
CloudGateway.UpdateIntegration | Live |
CloudGateway.AttachDomainName / CreateDomainName | Live |
FUNCTION / EVENTS_PUT execute | Coming soon (implemented; live e2e pending) |
| WebSocket connect / message routes | Coming soon (single-node runtime; live e2e pending) |
CloudGateway.PostToConnection | Coming soon |
CloudGateway.DisconnectConnection | Coming soon |
CloudGateway.GetConnection / ListConnections | Coming soon |
CreateApi
{
"Name": "orders-api",
"ProtocolType": "HTTP"
}For WebSocket APIs, set "ProtocolType": "WEBSOCKET" and optionally "RouteSelectionExpression": "$request.body.action".
Returns an ApiId and a platform hostname such as {api_id}.gateway.eu-central-1.cloud.skippr.io.
CreateRoute
| Field | Example |
|---|---|
ApiId | api-abc123 |
RouteKey | POST /v1/orders |
IntegrationId | int-xyz |
AuthorizerId | optional |
CreateIntegration
| Type | Config | Behaviour |
|---|---|---|
FUNCTION | FunctionName | Sync functions Invoke |
EVENTS_PUT | EventBusName (optional) | events PutEvents |
CLOUD_SERVICE | Platform dogfood only | Internal loopback to managed services |
Authorizers
| Type | Use |
|---|---|
JWT | Validate Cloud RS256 JWT (JWKS from auth) |
SIGV4 | AWS-compatible request signing |
USER_POOL | End-user JWT from an auth app user pool |
NONE | Public route |
WebSocket APIs (Preview — matrix coming soon)
WebSocket is a first-class gateway capability on the same Api catalog as HTTP. The single-node runtime (WSS upgrade, connection registry, local PostToConnection delivery, NATS KV metadata) is implemented; multi-node fan-out is out of Preview scope. Compatibility matrix ops stay coming soon until live dogfood WSS e2e is green.
How it differs from HTTP
| HTTP Api | WebSocket Api | |
|---|---|---|
| Entry | https://… request/response | wss://… long-lived connection |
| Routes | METHOD /path | Route keys (CONNECT, custom keys, …) |
| Server push | Not built-in | PostToConnection management API |
Connect to wss://{api_id}.gateway.eu-central-1.cloud.skippr.io/ (or your custom domain). There are no stages and no deploy step.
Built-in route keys
| Skippr route key | AWS analogue | When it runs |
|---|---|---|
CONNECT | $connect | Once after successful upgrade and auth |
DISCONNECT | $disconnect | When the connection closes (best-effort) |
DEFAULT | $default | When no message route matches |
| your keys | custom routes | Per inbound JSON message frame |
Message routes are selected by your Api’s route selection expression (for example $request.body.action) or a routeKey field in the frame JSON.
Authentication
Auth runs on the CONNECT route — the same authorizer types as HTTP. Failures before the upgrade completes return HTTP 401 or 403 (no WebSocket session is opened):
| Authorizer | On upgrade |
|---|---|
JWT / USER_POOL | Authorization: Bearer <token> or ?access_token= |
SIGV4 | SigV4-signed upgrade request |
NONE | Public connect (no tenant) |
Your tenant is taken from token claims at connect time and bound for the connection lifetime. You cannot override tenant via query parameters or message bodies.
Integrations on WebSocket routes
| Integration | Typical use |
|---|---|
FUNCTION | Handle connect, messages, or disconnect via functions Invoke. Message routes return a response frame to the client by default (sync). |
EVENTS_PUT | Publish connection events to events PutEvents (async from the client’s perspective). |
CLOUD_SERVICE loopback integrations are not available on WebSocket routes.
Management API (server push)
| Operation | Purpose |
|---|---|
CloudGateway.PostToConnection | Send a JSON text frame to one ConnectionId |
CloudGateway.DisconnectConnection | Force-close a connection |
CloudGateway.GetConnection | Look up connection metadata (tenant-scoped) |
PostToConnection example:
{
"ConnectionId": "conn-abc123",
"Data": "{\"type\":\"notification\",\"message\":\"hello\"}"
}Returns 410 Gone if the connection is already closed. Fan-out is one connection per call in v1 — call PostToConnection per recipient or publish to events and let workers push.
Limits (Preview targets)
When WebSocket ships, expect coarse defaults such as:
- 32 KiB max frame size (inbound and outbound)
- 10 minute idle timeout
- 24 hour max connection lifetime
- 1 000 open connections per tenant per region (soft limit)
Platform edge note
Today’s live platform hostnames (tables.*, queue.*, …) are HTTP only. WebSocket is for your tenant Apis. Console-style realtime push on platform hostnames is not part of Preview.
Do not route streams protocol traffic through the gateway — use streams on port :9092 directly.
Domains
| Mode | Flow |
|---|---|
| Platform hostname | Assigned on CreateApi — {api_id}.gateway.eu-central-1.cloud.skippr.io |
| Custom domain | DNS record → certificate → attach to Api |
| CNAME | Point your hostname at the platform API hostname |
Authentication (platform edge — live)
| Method | Header | When |
|---|---|---|
| SigV4 | Authorization: AWS4-HMAC-SHA256 … | AWS-compat clients, workload automation |
| JWT | Authorization: Bearer <token> | Native APIs, user sessions |
Obtain tokens and keys via Auth. Every authenticated request is evaluated with ABAC (Cedar policies).
Limits and errors
- Coarse per-IP and per-credential rate limits apply at the edge.
- Unsigned requests to protected routes return 401.
- Cross-tenant access is denied by platform defaults.
