Accounts are used to authenticate users of server-side services.


In the root document, every application can define an account list:

{ "apps": [{ "account list": { "prefix": "candy/", "#r": randomHex(16) }, "name": "Candy Factory", "root": { "#r": randomHex(16) } }, { "account list": { "prefix": "club42/", "#r": randomHex(16) }, "name": "Club 42", "root": { "#r": randomHex(16) } }, { "account list": { "prefix": "UDP/", "#r": randomHex(16) }, "name": "Sensors", "root": { "#r": randomHex(16) } }, "..."] }

An account list can optionally be prefixed, in which case all accounts must start with this prefix.

The linked document contains a set of accounts:

{ "accounts": { "candy/margrit": { "svg-to-pdf": false, "key": randomHex(32), "sendmail": true }, "candy/paul": { "svg-to-pdf": true, "key": randomHex(32), "sendmail": true }, "candy/customer": { "key": "none", "origins": [""], "blobs": true }, "...": null } }

Keys and origins

An account should be protected by a key, and/or a list of origins.

Accounts with a key require requests to be signed with that key. They are suited for registered users, and effectively prevent that account from being used by anyone else. The key is a random 64-hexdigit sequence.

If no key is set, it must explicity be set to "none":

{"key": "none", "...": null}

Accounts with a list of origins (hostnames) can be accessed from these CORS origins only. They are suitable for the general public, e.g. to upload a blob, or submit a contact form. Note that this is a protection for websites only. A script can freely set (and therefore forge) the origin header of HTTP requests.

Nested account lists

An account list document can optionally link other account lists:

{ "account lists": [{ "prefix": "candy/hr/", "#r": randomHex(16) }, { "#r": randomHex(16) }, "..."], "accounts": {} }


Requests are signed by adding the following header fields:

POST /backend/...
Timestamp: TIMESTAMP
Signature: SIGNATURE
Signature calculation
HEX(SHA256HMAC(ACCOUNT ID | "\0" | HOST | "\0" | METHOD | "\0" | PATH | "\0" | TIMESTAMP | "\0" | HEX(SHA256(DATA)), KEY))
Account ID

TIMESTAMP is a Unix timestamp in milliseconds, written as decimal integer. The timestamp must be close to the actual time, and strictly increasing.

HOST is as provided in the request. METHOD is written in uppercase letters. PATH is the URI-decoded request path.

DATA is the raw PUT or POST data submitted with the request.

The signature is hex-encoded.


Using Backend.js, an account object is created as follows:

const backend = new Backend('');
const account = backend.account('your-account-id', '44705748... your-account-key');