Authentication and Signatures
Vask uses Pusher-compatible signing for channel authorization, user authentication, webhooks, and HTTP API requests.
Use your Vask app_key anywhere a Pusher SDK asks for an app key. If a server SDK also asks for app_id, use the same app_key.
#Channel authorization
Private, presence, private cache, presence cache, encrypted, and encrypted cache channels require authorization.
The client SDK sends your application server:
socket_id=1234.5678
channel_name=private-dashboard.42For private channels, sign this string with HMAC-SHA256 using the app secret:
1234.5678:private-dashboard.42Return:
{
"auth": "app_key:hmac_signature"
}#Presence authorization
Presence channels add channel_data. The exact JSON string you return must be the exact JSON string you sign.
{
"user_id": "user-123",
"user_info": {
"name": "Ada"
}
}Sign:
1234.5678:presence-room.42:{"user_id":"user-123","user_info":{"name":"Ada"}}Return:
{
"auth": "app_key:hmac_signature",
"channel_data": "{\"user_id\":\"user-123\",\"user_info\":{\"name\":\"Ada\"}}"
}#User authentication
User authentication identifies the connection itself. It powers server-to-user events, watchlist events, and user connection termination.
The auth endpoint signs:
1234.5678::user::{"id":"user-123","name":"Ada"}Return:
{
"auth": "app_key:hmac_signature",
"user_data": "{\"id\":\"user-123\",\"name\":\"Ada\"}"
}The client then sends pusher:signin over the WebSocket connection.
#HTTP API authentication
Every request to https://api.vask.dev/apps/{app_key}/... must be signed.
Required query parameters:
| Parameter | Description |
|---|---|
auth_key |
Your Vask app_key. |
auth_timestamp |
Unix timestamp in seconds. |
auth_version |
Use 1.0. |
body_md5 |
MD5 hex digest of the request body for non-empty POST bodies. |
auth_signature |
HMAC-SHA256 hex digest of the string to sign. |
String to sign:
METHOD
/apps/{app_key}/events
auth_key=app_key&auth_timestamp=1715520000&auth_version=1.0&body_md5=...Node example:
import crypto from 'node:crypto';
function signRequest({ method, path, params, secret }) {
const query = Object.keys(params)
.sort()
.map((key) => `${key}=${params[key]}`)
.join('&');
return crypto
.createHmac('sha256', secret)
.update(`${method.toUpperCase()}\n${path}\n${query}`)
.digest('hex');
}#Webhook signatures
Webhook deliveries use the app secret to sign the raw request body.
X-Pusher-Key: app_key
X-Pusher-Signature: hmac_sha256(raw_body, app_secret)Do not parse and re-encode the body before verification.
#Common failures
| Symptom | Check |
|---|---|
401 from HTTP API |
Wrong secret, stale timestamp, missing body_md5, or signed path differs from request path. |
pusher:error on private subscribe |
Auth endpoint signed the wrong socket_id or channel_name. |
| Presence user missing | channel_data was not included, not valid JSON, or did not include user_id. |
| User termination does nothing | The target connection has not completed pusher:signin. |
#Related docs
Prefer raw markdown? View this page as markdown.