veil

The Veil chat API

Read and write the chat at veil.rip/chat/ with the key of a card, and check who signed each message.

The chat is not open yet. This page describes the API it will serve at https://veil.rip/chat/api/, on the same origin as the directory, so a browser that holds a card’s device key is already signed in. A chat user is the card: its name, picture, badges and verified accounts come from the card, and the chat writes nothing to the log.

Sign a request#

text
veil-chat:request:v1
POST /chat/api/servers
<exact UTF-8 JSON body with ts and nonce>

Send the card’s device key in X-Veil-Key (hex) and the Ed25519 signature in X-Veil-Signature (base64). The body carries ts, an ISO 8601 UTC time within two minutes of the server’s clock, and nonce, 16 or more random bytes in base64url, used once. A GET or a DELETE puts ts and nonce in the query and signs an empty body. The chat checks that the key is an active device key of a card with GET /v1/keys/{key}. The signed bytes end with a new line after the body, which is not sent (a GET signs an empty body and then the new line): a signature block never ends that way, so none can pass for a request.

Sign a message#

text
veil-chat:message:v1
channel:<id>
<ts>
<nonce>
<text>

The author signs each message with the same key, for one channel, thread or board. The chat stores the signed bytes and the signature as they came and serves them with the message, with card and key. To check a message, decode signedBytes from base64, verify the signature with key, and check with GET /v1/keys/{key}/active-at?t=<unix seconds> that the key was an active key of that card at its time. A message from a key revoked later still verifies at its own date.

The reference#

Every endpoint, event and error code of the chat is in chat/docs/api-chat.md in the Veil sources: servers, channels, roles with the permission bits of the old chat, invites, messages, mentions, unread counts, threads, boards, the staff’s moderation and the WebSocket at wss://veil.rip/chat/ws.