Docs
Apache APISIXHow-To GuidesAuthenticationSecure WebSocket Traffic
Version: 3.19.0

Secure WebSocket Traffic

WebSocket provides persistent, bidirectional communication over a single TCP connection. After the initial connection is established, the client and server can exchange messages without creating a new HTTP request for every interaction. This makes WebSocket suitable for live feeds, chat, collaborative applications, multiplayer games, and other workloads that require low-latency updates.

Each WebSocket connection begins as an HTTP upgrade request. The gateway must make its authentication decision during this handshake, before the connection becomes a long-lived communication channel. APISIX can apply an authentication plugin to the upgrade request and reject unauthorized clients before allowing the protocol switch.

This guide configures the key-auth plugin and uses websocat, a command-line client that can add a credential header to the handshake, to verify both rejected and authenticated connections. Browser WebSocket APIs do not allow applications to set arbitrary request headers, so browser applications should use an authentication method and credential transport that fit their client architecture. The same handshake can use another APISIX authentication plugin when it better matches the client and application.

Prerequisite(s)

Start a WebSocket Upstream

Set GATEWAY_CONTAINER to the running APISIX container. Create a dedicated network and connect the gateway to it:

export GATEWAY_CONTAINER=replace-with-apisix-container-name

docker network create gateway-websocket-net
docker network connect gateway-websocket-net "$GATEWAY_CONTAINER"

Start a pinned sample WebSocket server on the shared network:

docker run -d \
  --name websocket-server \
  --network gateway-websocket-net \
  jmalloc/echo-server:v0.3.7

The server exposes /.ws, which echoes each received message.

Create a Route

Create a route that enables WebSocket proxying and requires key-auth credentials:

curl "http://127.0.0.1:9180/apisix/admin/routes/websocket-auth" -X PUT \
  -d '{
    "uri": "/.ws",
    "enable_websocket": true,
    "plugins": {
      "key-auth": {}
    },
    "upstream": {
      "type": "roundrobin",
      "nodes": {
        "websocket-server:8080": 1
      }
    }
  }'

Create a Consumer

Create a consumer named john with a key-auth credential:

Create the consumer:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
  -d '{
    "username": "john"
  }'

Create the credential:

curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
  -d '{
    "id": "john-key-auth",
    "plugins": {
      "key-auth": {
        "key": "john-key"
      }
    }
  }'

Verify Authentication

Open the route without credentials:

websocat "ws://127.0.0.1:9080/.ws"

APISIX should reject the handshake with 401 Unauthorized.

Open the route with John's credential:

websocat "ws://127.0.0.1:9080/.ws" -H "apikey: john-key"

Send hello. The server should echo the message:

Request served by <container-id>
hello
hello

The successful upgrade and echoed message confirm that APISIX authenticated the handshake and proxies traffic in both directions.

Next Steps

You have configured APISIX to authenticate WebSocket upgrade requests. To control the number of concurrent connections, see Rate Limit WebSocket Connections.