AuthSocket WebSocket Protocol

AuthSocket wraps Socket.IO with BRC-103 mutual authentication. Every WebSocket connection undergoes a cryptographic handshake, then all application-level messages are automatically signed by the server and verified by the client (and vice versa). No shared secrets required—only identity public keys.

Interactive spec

At a glance

FieldValue
FormatAsyncAPI 3.0
Version1.0.0
Statusstable
Implementations@bsv/authsocket

What problem this solves

Authenticated real-time messaging over WebSocket. WebSockets lack built-in authentication; clients typically send bearer tokens which are single-factor and session-based. AuthSocket brings BRC-103 mutual authentication to WebSocket: both client and server prove identity via cryptographic signatures, and every message is signed, preventing impersonation and tampering.

Live message push without polling. MessageBox's HTTP interface requires polling. AuthSocket enables server-side push: when a new message arrives, the server emits it immediately to the connected client without waiting for the next poll.

Session-less design. Each WebSocket connection is independent. The server doesn't maintain session state between connections. Authentication happens once at connect time; all subsequent messages are verified via signature.

Protocol overview

Two-phase connection:

Phase 1 — BRC-103 Handshake (over low-level authMessage Socket.IO event)

  1. Client → Server socket.emit('authMessage', initialRequest)

    • Client's public key
    • Client's nonce
    • Client signature over nonce
  2. Server → Client socket.emit('authMessage', initialResponse)

    • Server's public key
    • Server's nonce (covering client's nonce)
    • Server signature

Phase 2 — Authenticated Application Events

After handshake, client and server exchange high-level events. All messages are wrapped in BRC-103 general type envelope and signed automatically:

  • Server → Client: socket.emit('messageReceived', { from, body, timestamp })
  • Client → Server: socket.emit('sendMessage', { to, body })
  • Any JSON-serializable event; signature transparent to application code

Key types / channels

ChannelDirectionMessage TypePurpose
authMessage (low-level)BidirectionalinitialRequest / initialResponseBRC-103 handshake
Application eventsBidirectionalJSON objectsAfter handshake; auto-signed

Standard application events:

  • messageReceived(message) — Server pushes message to client
  • sendMessage(payload) — Client sends message to server
  • joinRoom(roomName) — Client joins subscription room
  • leaveRoom(roomName) — Client leaves subscription room
  • Any custom event name

Example: Server setup

typescript
import http from 'http'
import { AuthSocketServer } from '@bsv/authsocket'
import { ServerWallet } from '@bsv/simple/server'

const server = http.createServer()
const wallet = await ServerWallet.create({
  privateKey: process.env.SERVER_PRIVATE_KEY!,
  network: 'main',
  storageUrl: 'https://store-us-1.bsvb.tech'
})

// 1. Wrap HTTP server with BRC-103 authentication
const io = new AuthSocketServer(server, {
  wallet,
  cors: { origin: '*' }
})

// 2. Listen for authenticated connections
io.on('connection', (socket) => {
  console.log('Authenticated socket:', socket.id)
  
  // 3. Handle application events (signature verified automatically)
  socket.on('sendMessage', (msg) => {
    console.log('Received from:', socket.id, msg)
    
    // 4. Emit to other clients (server signs automatically)
    io.emit('messageReceived', {
      from: socket.id,
      body: msg.body,
      timestamp: new Date().toISOString()
    })
  })
})

server.listen(3000)

Example: Client subscription

typescript
import { MessageBoxClient } from '@bsv/message-box-client'
import { WalletClient } from '@bsv/sdk'

const wallet = new WalletClient('auto', 'example.com')
const msgBox = new MessageBoxClient({ walletClient: wallet })
const recipient = '025706528f0f6894b2ba505007267ccff1133e004452a1f6b72ac716f246216366'

// Automatically handles BRC-103 handshake
await msgBox.listenForLiveMessages({
  messageBox: 'general_inbox',
  onMessage: (msg) => {
    console.log('Live message:', msg.body)
    // Message signature already verified server-side
  }
})

// Send message (client signs automatically)
await msgBox.sendLiveMessage({
  recipient,
  messageBox: 'general_inbox',
  body: 'Hello, live world!',
  skipEncryption: true
})

Conformance vectors

There is no standalone AuthSocket vector directory in the current conformance corpus. Related portable coverage lives in conformance/vectors/messaging/brc31/authrite-signature.json; AuthSocket-specific behavior is covered by the package tests and the AsyncAPI artifact linked below.

Implementations in ts-stack

PackageNotes
@bsv/authsocketServer-side Socket.IO wrapper; provides AuthSocketServer class
@bsv/message-box-clientClient-side integration; uses authsocket for live messaging
@bsv/sdkPeer and Transport abstractions underlying BRC-103
  • BRC-31 Auth — HTTP variant of the same mutual auth protocol
  • Message Box HTTP — Polling alternative (HTTP POST)
  • BRC-103 — Underlying peer authentication primitives

Spec artifact

authsocket-asyncapi.yaml