API reference

Authenticator backup

The Authenticator phone app's encrypted backup: read it, save it at the next revision, delete it.

See Authenticator. The backup is one encrypted copy of a person's accounts at /v1/me/authenticator/vault, reachable only with the Authenticator app's own sign-in (a mobile token issued to the authenticator app): organization keys, Caity, the phone assistant and the other apps get 403.

The phone does the cryptography. Version 1: the key is PBKDF2-HMAC-SHA-256 of the passphrase (Unicode NFC) with the record's salt, 600,000 iterations and 32 bytes; ciphertext is base64 of a 12-byte nonce, the AES-256-GCM ciphertext of the account list (UTF-8 JSON) and the 16-byte tag, with authenticator-vault/v1/<salt> as associated data. The server keeps only version, salt and ciphertext, with the revision and times.

Each PUT names the revision it replaces (0 for the first backup). When another phone saved since, the answer is 409 with the backup there now, so the app can combine the two (same salt) or ask for a changed passphrase, and nothing is overwritten unseen.

GET /v1/me/authenticator/vault

Your Authenticator backup: version (the format), salt and ciphertext (base64, encrypted on the phone with a key from your passphrase), revision and times; null when there's none. From the Authenticator app's sign-in only.

Auth: user access token or platform agent key

Response 200

{
  vault: null | {
    version: number
    createdAt: number
    updatedAt: number
    ciphertext: string
    revision: number
    salt: string
  }
}

Errors

StatusMessage
403The authenticator backup opens only in the Authenticator app.

PUT /v1/me/authenticator/vault

Saves the backup (version 1, salt, ciphertext) if revision is still the current one (0 when there's none) and returns it at the next revision. Otherwise 409 with the backup there now (vault, or null): nothing is overwritten unseen. From the Authenticator app's sign-in only.

Auth: user access token or platform agent key

Request body (up to 260 KB)

FieldTypeRequiredNotes
version1Yes
saltstringYes24–88 characters; matches ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
ciphertextstringYes40–262,144 characters; matches ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
revisionintegerYes≥ 0

Also checked: Unknown fields are rejected.

Response 200

{
  vault: {
    version: number
    createdAt: number
    updatedAt: number
    ciphertext: string
    revision: number
    salt: string
  }
}

Errors

StatusMessage
403The authenticator backup opens only in the Authenticator app.
409The backup changed since this phone last saw it.
413The backup is too large.

DELETE /v1/me/authenticator/vault

Deletes the backup from your account; deleted: false when there wasn't one. The accounts on the phone stay.

Auth: user access token or platform agent key

Response 200

{
  ok: true
  deleted: boolean
}

Errors

StatusMessage
403The authenticator backup opens only in the Authenticator app.