Cryptography Whitepaper
Cryptography Whitepaper
End-to-End Encryption 4
Key Generation and Registration 4
Key Distribution and Trust 4
Message Encryption 5
Group Messaging 6
Key Backup 6
Cryptography Details 8
Key Lengths 9
Random Number Generation 9
Forward Secrecy 10
Repudiability10
Padding10
Replay Prevention 10
Key Storage 11
iOS11
Android12
Push Notifications 12
iOS12
Android12
ID Revocation 14
An Example 14
Profile Pictures 14
Web Client 15
Architecture15
Connection Buildup 15
WebRTC Signaling 16
WebRTC Connection Buildup 16
Threema Calls 18
Signaling18
Call Encryption 18
Audio Encoding 18
Video Encoding 18
Privacy / IP exposure 18
Threema Safe 19
Overview19
Backup format 19
Encryption19
Upload/Storage20
Backup intervals 20
Restore/Decryption20
Running a custom Threema Safe server 21
Security Recommendations 22
• End-to-end encryption layer: this layer is between the sender and the recipient.
• Transport layer: each end-to-end encrypted message is encrypted again for transport between the cli-
ent and the server, in order to protect the header information.
These layers and other important aspects of the cryptography in Threema are described in detail in the following
chapters. The crucial part is that the end-to-end encryption layer passes through the server uninterrupted; the
server cannot remove the inner encryption layer.
End-to-end
encryption layer
Sender Recipient
Server
Transport layer Transport layer
The public key of each user is stored on the directory server, along with its permanently assigned Threema ID.
Any user may obtain the public key for a given Threema ID by querying the directory server. The following input
values can be used for this query:
The Threema app maintains a “verification level” indicator for each contact that it has stored. The following three
levels are possible:
• Red (level 1): The public key has been obtained from the server because a message has been
received from this contact for the first time, or the ID has been entered manually. No matching contact was
found in the user’s address book (by phone number or email), and therefore the user cannot be sure that
the person is who they claim to be in their messages.
• Orange (level 2): The ID has been matched with a contact in the user’s address book (by phone
number or email). Since the server verifies phone numbers and email addresses, the user can be reason-
ably sure that the person is who they claim to be.
• Green (level 3): The user has personally verified the ID and public key of the contact by scan-
ning their 2D code. Assuming the contact’s device has not been hijacked, the user can be very sure that
messages from this contact were really written by the person that they indicate.
To upgrade a contact from the red or orange to the green level, the user must scan that contact’s public QR code.
This QR code is displayed in the “My ID” section of the app, and uses the following format:
3mid:<identity>,<publicKeyHex>
where <identity> is the 8-character Threema ID, and <publicKeyHex> is the hexadecimal (lowercase) represen-
tation of the user’s 32 byte public key. The app verifies that the scanned public key matches the one that was
returned by the directory server.
1 including entropy generated by user interaction; see section “Random Number Generation” for details
Message Encryption
Threema uses the “Box” model of the NaCl Networking and Cryptography Library to encrypt and authenticate
messages. For the purpose of this description, assume that Alice wants to send a message to Bob. Encryption of
the message using NaCl works as follows:
Preconditions
1. Alice and Bob have each generated a key pair consisting of a public and a private key.
2. Alice has obtained the public key from Bob over an authenticated channel.
By reversing the above steps and using his own private key and Alice’s public key, Bob can decrypt the message
and verify its authenticity.
Bob's
public key
ECDH Shared
HSalsa20 secret
(Curve25519)
Alice's
private key
Random Nonce
Generator
MAC
Ciphertext
Nonce
Key Backup
The user can back up their private key so that they are able to move their Threema ID to another device, or to
restore it in case of loss/damage to the device. The app automatically reminds the user to do so, as without a
backup, there is no way to recover a lost private key.
To generate a backup, the user must first choose a password (min. 8 characters).
The backup data is then generated as follows:
1. Calculate the SHA-256 hash of the following binary string:
<identity><private key>
where <identity> is the 8 character Threema ID, and <private key> is the 32 byte private key.
Keep only the first two bytes of the resulting hash. It is used during restoration to verify with reasonable
confidence that the provided password was correct.
2. Choose a random 64 bit salt.
3. Derive a 256-bit encryption key from the given password and the random salt using PBKDF2 with
HMAC-SHA256 and 100000 iterations:
keyenc = PBKDF2(HMAC-SHA256, password, salt, 100000, 32)
4. Use the XSalsa20 stream cipher with keyenc and an all-zero nonce to encrypt a binary string of the follow-
ing format:
<identity><private key><hash>
where <hash> is the two byte truncated hash calculated in step 1. Note that this can be done using the
crypto_stream function of NaCl.
5. Prepend the salt to the encrypted string.
6. Base32 encode the result.
7. Split the Base32 encoded string into groups of four characters and separate the groups with dashes.
The result will look like this:
XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-
XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX
The encrypted backup data consists of 80 characters (A-Z, 2-7). It is also displayed in QR code form so that the
user can more easily transfer it to another device.
Chat server
custom
HTTPS
Directory server
HTTPS
Media server
Requests are authenticated with a challenge/response protocol based on the user’s Threema ID and key pair.
HTTPS (HTTP with TLS) is used as the transport protocol. Strong TLS cipher suites with forward secrecy (EC-
DHE/DHE) and TLS v1.2 are supported. In order to preclude man-in-the-middle (MITM) attacks even if the sys-
tem’s trusted CA store has been tampered with, or if a trusted CA has illegally issued a certificate for a Threema
domain name, the app uses public-key pinning with hardcoded pins to only accept specific, Threema-owned
server certificates.
The media servers use the same TLS configuration (cipher suites with forward secrecy, TLS v1.2) as the directory
servers, and the app uses public-key pinning when accessing them.
Cryptography Details
As mentioned earlier, Threema uses the NaCl Networking and Cryptography Library for both the end-to-end
encryption, and to secure the chat protocol at the transport level. This library uses a collection of algorithms to
provide a simplified interface for protecting a message using what the authors call “public-key authenticated
encryption” against eavesdropping, spoofing and tampering. By default, and as implemented in Threema, it uses
the following algorithms:
• Key derivation: Elliptic Curve Diffie-Hellman (ECDH) over the curve Curve25519
• Symmetric encryption: XSalsa20
• Authentication and integrity protection: Poly1305-AES
It is worth mentioning that the ECC curve used by NaCl (and thus by Threema) is not one of the NIST-recom-
mended curves that have been suspected of containing deliberately selected weakening constants in their
specification.
For more details, see Cryptography in NaCl.
The following implementations of the cryptographic algorithms are used:
Nonces and salts must never repeat, but they are not required to be hard to guess.
To obtain random numbers, Threema uses the system-provided random number generator (RNG) intended for
cryptographically-secure purposes provided by the device’s operating system. The exact implementation varies
among operating systems:
Note that Threema does not use the flawed Dual_EC_DRBG random number generator.
2 To avoid the flawed SecureRandom implementation in some Android versions, Threema uses its own
implementation that directly accesses /dev/random (which is not affected by the SecureRandom implementation
bug).
Forward Secrecy
Due to the inherently asynchronous nature of mobile messengers, providing reliable Forward Secrecy on the
end-to-end layer is difficult. Key negotiation for a new chat session would require the other party to be online
before the first message can be sent. Experimental schemes like caching pre-generated temporary keys from the
clients on the servers increase the server and protocol complexity, leading to lower reliability and more potential
for mistakes that impact security. The user experience can also be diminished by events that are not under the
control of the sender, for example when the recipient loses their phone’s data, and along with it the ephemeral
keys. Due to these and the following considerations, Threema has implemented Forward Secrecy on the trans-
port layer only:
• Reliability is very important to ensure that users do not feel negatively impacted by the cryptography.
• The risk of eavesdropping on any path through the Internet between the sender and the server, or be-
tween the server and the recipient, is orders of magnitude greater than the risk of eavesdropping on the
server itself.
With Threema’s implementation, an attacker who has captured and stored the network traffic between a client
and a Threema server will not be able to decrypt it even if he learns the private key of the server or the client
afterwards.
Repudiability
In general, cryptographically signed messages also provide non-repudiation; i.e. the sender cannot deny having
sent the message after it has been received. The NaCl library’s box model uses so-called public-key authentica-
tors instead, which guarantee repudiability (see http://nacl.cr.yp.to/box.html, “Security model”). Any recipient can
forge a message that will look just like it was actually generated by the purported sender, so the recipient cannot
convince a third party that the message was really generated by the sender and not forged by the recipient.
However, the recipient is still protected against forgeries by third parties. The reason is that in order to perform
such a forgery, the private key of the recipient is needed. Since the recipient himself will know whether or not he
has used his own private key for such a forgery, he can be sure that no third party could have forged the message.
Padding
In order to thwart attempts to guess the content of short messages by looking at the amount of data, Threema
adds a random amount of PKCS#7 padding to each message before end-to-end encryption.
Replay Prevention
The Threema app remembers the nonce of every message that has been sent in the past, and rejects messages
with duplicate nonces. Since the server cannot successfully modify the nonce of a message without knowing the
private key of one of the parties involved in the communication, this prevents a malicious server from replaying/
duplicating previously sent messages.
iOS
On iOS, Threema stores local data in a Core Data database, which is backed by files in the app’s private data
directory. The iOS sandbox model ensures that no other apps can access this data directory. All files stored by
Threema are protected using the iOS Data Protection feature using the Data Protection class NSFileProtection-
CompleteUntilFirstUserAuthentication (see iOS Security Guide, page 13). The encryption key used to protect the
files is derived from the device’s UID key and the user’s passcode. A longer passcode will provide better security
(on devices equipped with a Touch ID sensor, longer passcodes can be used without a loss of comfort as the
passcode only needs to be entered after a reboot).
Note that the private key for the Threema ID is stored separately in the iOS Keychain.
Android
On Android, Threema stores local data in an SQLite database within the app’s private data directory. Android
ensures that no other apps can access this data directory (as long as the device is not rooted). The database
itself is protected by SQLCipher with AES-256, and any media files (which are stored separately in the app’s
private directory within the file system) are also encrypted using AES. The key is randomly generated when the
database is first created, and can be protected with a user-supplied passphrase (which is of course necessary
if the user wishes to take advantage of this encryption). The passphrase is never written to permanent storage
and therefore needs to be entered whenever the app process restarts (e.g. after a low-memory situation, or after
the device has rebooted). Alternatively, the user may enable full-device encryption if supported by the device and
Android version.
Key Storage
On the user’s mobile device, the private key is stored in such a way as to prevent access by other apps on the
same device, or by unauthorized users. The procedure differs between platforms.
iOS
• The private key is stored in the iOS Keychain with the attribute kSecAttrAccessibleAfterFirstUnlock-
ThisDeviceOnly.
• Only the Threema app can access this keychain entry.
• While the entire iOS keychain is included in backups via iTunes or iCloud, the kSecAttrAccessibleAfter-
FirstUnlockThisDeviceOnly attribute causes the keychain entry of Threema to be encrypted with a de-
vice-specific key (“UID key”) that cannot be read directly and is not known to Apple. Therefore, the key-
chain entry is only usable if the iTunes/iCloud backup is restored to the same device.
○○ See iOS Security Guide, page 14
• When the Threema app is deleted and reinstalled, the keychain entry persists and the Threema ID is not
lost.
Push Notifications
Threema uses the standard push notification service provided by the operating system. This is necessary to
ensure reliable delivery of push notifications, as mobile operating systems place high importance on conserving
battery power, and thus severely restrict background operation of apps (such as would be needed to maintain
a separate, app-specific persistent connection for push notifications). Channelizing push notifications through
the operating system’s standard mechanism thus helps conserve battery power, and on iOS, it is the only means
possible and accepted in the App Store.
iOS
The Threema-specific APNS payload consists of a JSON/Base64 encoded NaCl “crypto_secretbox” ciphertext
and corresponding nonce. The symmetric key used by the Threema chat server to encrypt this payload is chosen
at random by the client, and securely transmitted to the server beforehand using the chat protocol described
above. The symmetric key is not known to Apple. When a push notification arrives, the Threema app decrypts the
APNS payload using the symmetric key, and thus recovers the Threema ID and nickname of the sender of the
corresponding message, as well as the message ID. With this information, the app can obtain the actual encrypt-
ed message by connecting to the chat server, and then decrypt the message and display a preview (if enabled)
and the sender’s contact name in the local notification.
Android
The GCM payload is empty; that is, the GCM message only serves to wake up the Threema app in the back-
ground. It then connects to the chat server to retrieve any pending messages, decrypts them, and shows local
notifications for them.
• HMAC-SHA256 hash of each email address found in the phone’s address book
○○ Key: 0x30a5500fed9701fa6defdb610841900febb8e430881f7ad816826264ec09bad7
• HMAC-SHA256 hash of the E.164 normalized form of each phone number found in the phone’s address
book
○○ Key: 0x85adf8226953f3d96cfd5d09bf29555eb955fcd8aa5ec4f9fcd869e258370723
The directory server then compares the list of hashes from the user with the known email/phone hashes of
Threema IDs that have been linked with an email address and/or phone number. Any matches are returned by
the server as a tuple (Threema ID, hash). Only those hashes that have already been submitted by the user are
returned (i.e. if the user submits an email hash which then matches a Threema ID, the server will only return the
email hash of that ID and not the linked phone number’s hash, even if one exists). After returning the matches to
the client, the directory server discards the submitted hashes.
Linking
If a user chooses to link their Threema ID to an email address or a phone number, the directory server verifies that
the user actually owns the email address or phone number in question.
• For email addresses, a verification email with a hyperlink is sent to the user. The user must open the hy-
perlink and confirm in the browser before the ID link is established.
• For phone numbers, the directory server sends an SMS message with a random 6 digit code. The user
must enter that code in the app, which sends it back to the server to verify the phone number.
○○ If the user cannot receive the SMS message, he/she may choose to receive an automated phone call
in which the code is read out.
An Example
A user has set an eight character revocation password with a combination of characters consisting of the lower-
case latin alphabet (a-z) and digits. This results in 368 ≅ 241.36 combinations.
Therefore, a given key can correspond with over 600 different passwords of this length and character set. On
the other hand, the probability of randomly choosing the correct hash value without knowing anything about the
password is 2-32 ≅ 0.000000023%. Assuming that a user gets three attempts per day, the probability of finding
the correct hash value within 10 years is ≅ 0.000255%.
Profile Pictures
It is possible for a user to select a photo to be used as his/her “profile picture”. The user can choose within the
app whether he/she wants to share the profile picture with all their contacts, with only those contacts selected
from a list, or with nobody. If he/she chose to share the profile picture and sends a message to one of the des-
ignated recipients, the newly set profile picture is encrypted with a random symmetric key within the app, and
then uploaded to the media server like a regular image message (see “Media Access Protocol” on page 8).
A reference to the encrypted picture on the media server, along with the symmetric key, is subsequently sent as
an end-to-end encrypted message in the background whenever the user sends a regular message to one of the
designated contacts who has not received the current profile picture yet. As the media server deletes files after
two weeks, the profile picture is uploaded again once a week (if necessary), using a new symmetric key each time.
Architecture
SaltyRTC Server Handshake
(WebSocket over TLS)
The web client and the app form a client-server relationship. All data about new events and old conversations is
exchanged directly between the two through an end-to-end encrypted channel.
When the web client is started, it requests the initial data (conversations, contacts, avatars, etc.) from the app.
The app responds with the requested data.
To send a message to a contact, the web client dispatches a message request to the app, which will then send
the message to the recipient. When a new message arrives, the app notifies the web client. No messages are
exchanged directly between the web client and the Threema chat server. The user’s private key never leaves the
device.
Connection Buildup
The full connection buildup happens in three stages.
The transfer of data between browser and app differs between Android and iOS, due to platform constraints:
2.1 Android
After the client handshake is successful and both peers know each other’s public session key, they initiate a We-
bRTC PeerConnection. The necessary signaling information to build up the connection (like offer, answer and ICE
candidate messages) are exchanged via the WebSocket connection, encrypted with the session keys.
As soon as the WebRTC PeerConnection is established, the two peers initiate the handover of the signaling
channel. Future signaling messages (like additional ICE candidates when the network configuration changes)
are exchanged over a secure signaling data channel. Once the handover is complete, the WebSocket connection
to the server is closed.
The two peers now open a second WebRTC data channel in order to exchange application data. All packets
transferred through that data channel are encrypted using the session keys.
2.2 iOS
After the client handshake is successful and both peers know each other’s public session key, they can immedi-
ately start exchanging application data over the established WebSocket signaling connection. All packets trans-
ferred through that channel are encrypted using the session keys.
WebRTC Signaling
The direct communication channel between the app and the Android web client is established using a
WebRTC PeerConnection. In order to establish such a peer-to-peer connection, a signaling channel is inevitable.
Common signaling server implementations often use WebSockets without any end-to-end encryption (often
even without transport encryption), meaning that the server can read all (potentially sensitive) network informa-
tion of the peers connecting. There is also the risk of a server manipulating the data being transmitted, opening
up possibilities of MITM attacks.
In order to mitigate this risk as well as minimizing metadata exposure in general, we participated in the design
and implementation of the SaltyRTC protocol, which offers end-to-end encryption of signaling data and does not
require the clients to trust the server at all.
Push Service
On Android devices, if Google Play Services are installed on the device of the user, the FCM push token (an
opaque string provided by Google) is transferred to the web client together with the initial data.
On iOS devices, the APNs push token (an opaque string provided by Apple) is transferred to the web client to-
gether with the initial data.
If the user requests to persist a session, the token is then stored in the local browser storage together with the
trusted keys, encrypted with a key derived from the user-provided password.
When reconnecting a web client session (e.g. when the user requests to restore a previous session, or when
automatically reconnecting due to connection loss) and if a push token is available, the browser sends this token
via HTTPS to a push relay server provided by Threema, together with the SHA256 hash of the public permanent
key of the initiator. The push relay server then sends the hash to the app as a FCM/APNs push notification. When
the app receives such a notification, it first checks whether the web client is enabled. If it is enabled and if a web
client session with the specified public key exists, that session is started and connects to the SaltyRTC server for
the handshake and reconnection procedure.
Open Source
All components of the web client (except the code in the Threema app itself) are published under open source
licenses:
Web client: https://github.com/threema-ch/threema-web
SaltyRTC server: https://github.com/saltyrtc/saltyrtc-server-python
Push relay: https://github.com/threema-ch/push-relay
The URL and public permanent key of the SaltyRTC server to be used are transferred through the QR code and
stored together with the session information. This allows the user to entirely bypass the web server and SaltyRTC
server operated by Threema, if desired. Instructions on how to set up a self-hosted Threema Web instance can
be found in the Threema Web repository.
The push relay cannot practically be run by an end user, since the FCM API key and the APNs certificates are not
public, but the source code is provided on GitHub for review purposes.
Signaling
Signaling data is sent through Threema messages, thus providing the same end-to-end security and trust level
as a regular Threema conversation. If you have verified your contact, you can also trust your phone calls with that
contact.
Call Encryption
The audio stream is encrypted with the SRTP protocol, with DTLS-SRTP being used for the key exchange. The
certificates used for the DTLS session are cryptographically linked to the keys used for Threema’s end-to-end
encryption by means of including the certificate fingerprints in signaling messages. DTLS version 1.2 is enforced.
The DTLS ciphersuites offered by the Threema app are (in that order):
• TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
• TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
• TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
The SRTP ciphersuites offered by the Threema app are (in that order):
• SRTP_AEAD_AES_256_GCM (0x0008)
• SRTP_AEAD_AES_128_GCM (0x0007)
• SRTP_AES128_CM_HMAC_SHA1_80 (0x0001)
RTP header extensions are only used if offered in an encrypted form.
Audio Encoding
Audio data is encoded using the state-of-the-art Opus codec at 48 kHz. To avoid potential privacy and security
issues associated with variable bitrate audio codecs3, Threema Calls always enforce constant bitrate to encode
the audio stream.
Video Encoding
Video data is encoded by VP9, VP8 or H.264.
Privacy / IP exposure
WebRTC connections can be established in two ways: Either a direct connection between the two devices is
used (using STUN to help with NAT traversal), or one or both sides use a TURN server to relay the encrypted
packets.
Relaying has the advantage of hiding the public IP address from the call partner, thus providing added privacy
when the peer is not trusted. On the other hand it exposes some metadata towards the TURN server, and the
connection quality (especially latency) may be worse than in a direct call. By default, Threema enforces relaying
through TURN for all unverified contacts (with a single red dot as verification status). Optionally, users can en-
force relaying for all calls through the “Always relay calls” option in the “Privacy” settings.
• Threema ID
• Private key
• Profile information
○○ Nickname
○○ Profile photo
○○ Linked email address and phone number
• Contact list
○○ Contact Threema ID
○○ Public key
○○ Name
○○ Verification level
• Group definitions
○○ Group ID
○○ Creator
○○ Group name
○○ List of members
• Distribution lists
○○ Name
○○ List of members
• App settings
Messages and media data are not part of a Threema Safe backup.
The rationale behind Threema Safe is to give users a secure backup option that allows them to restore their
Threema ID and important related data, or to move it to another device, using nothing but the knowledge of their
Threema ID and the Threema Safe password that they have chosen.
The use of Threema Safe is optional; the user can choose to enable or disable it at any time. By default, encrypt-
ed backups are stored on Threema servers, but the user can use their own server as a backup store instead. A
Threema Safe backup server cannot tell which backup belongs to which Threema user by looking at the upload-
ed data.
Backup format
The Threema app compiles the information mentioned in the previous section as a JSON document (binary val-
ues like the private key or profile photo are encoded in Base64). This JSON document is then compressed with
gzip and encrypted as follows. The resulting encrypted backup typically has a size of only a few dozen kilobytes
(depending mostly on the profile photo size, number of contacts and groups).
Encryption
In order to set up Threema Safe, the user must choose a password consisting of at least 8 characters. The app
checks whether the password is on a list of the most frequently used passwords, and warns the user if that is
the case.
• threemaSafeBackupId = threemaSafeMasterKey[0..31]
• threemaSafeEncryptionKey = threemaSafeMasterKey[32..63]
The Threema Safe backup data in the form of a UTF-8 encoded JSON string (plaintext) is then encrypted
as follows:
1. Compress using gzip: gzippedPlaintext = gzip(plaintext)
2. Generate random 24 byte nonce: nonce = randombytes(24)
3. threemaSafeEncryptedBackup = nonce ||
crypto_secretbox(gzippedPlaintext, threemaSafeEncryptionKey, nonce)
|| = concatenation
The crypto_secretbox operation is described in the NaCl documentation.
Upload/Storage
The encrypted data (threemaSafeEncryptedBackup) is uploaded to, or downloaded from, the
Threema Safe server using simple WebDAV-compatible HTTPS requests (see below for details). The
threemaSafeBackupId in lowercase hex encoding is used as a filename. If the user disables Threema Safe,
a DELETE request is issued by the app.
Backup intervals
When Threema Safe is enabled and a backup password is set, the Threema app generates a backup once per
day when the app is in use. If the backup data has changed since the last upload, or if more than half of the serv-
er-specified backup retention time has passed, then the backup is uploaded to the server, replacing any existing
backup with the same ID that may already exist on the server.
Restore/Decryption
1. User enters their Threema ID and password in the setup screen.
2. Derive the master key as described above.
3. Fetch threemaSafeEncryptedBackup from the server using the threemaSafeBackupId.
4. nonce = threemaSafeEncryptedBackup[0..23]
5. gzippedPlaintext =
crypto_secretbox_open(threemaSafeEncryptedBackup[24..],
nonce, threemaSafeEncryptionKey)
The crypto_secretbox operation is described in the NaCl documentation.
6. plaintext = gunzip(gzippedPlaintext)
The decrypted and decompressed JSON document (plaintext) is then used to restore the Threema ID and
other information.
Response Codes
Code Description
Create/Update Backup
PUT backups/<threemaSafeBackupId>
Content-Type: application/octet-stream
The threemaSafeEncryptedBackup is sent along unmodified in the PUT body.
Validation
Response Codes
Code Description
Validation
Response Codes
Code Description
Security Recommendations
The following recommendations are not required for automated backups to work, but they improve security. Im-
plementing these recommendations is especially important when offering a public service.
Throttling
To avoid misuse, throttling/rate limiting SHOULD be enforced in the server. It is up to the implementer whether to
limit requests based on the peer’s IP address, or the requested threemaSafeBackupId. If the limit has been
reached, requests MUST be responded to with a HTTP 429 (Too Many Requests) status code.
If the server software itself does not support rate limiting, this can be implemented by using a Proxy like
Nginx or HAProxy.
Data Retention
Backups SHOULD be automatically deleted after a certain amount of time, as specified in the “retentionDays”
configuration key.