Encryption

Privacy is a key feature of FreeToken. With a couple configuration options, you can ensure that all your data is encrypted at rest on the FreeToken servers.

What's Encrypted?

All data is encrypted on device before being sent to the server. We never know your keys and have no access to your data. This means that even if the server were compromised, your data would remain secure.

This includes:

  • Messages
  • Documents

Encryption is handled seemlessly before all data comes and goes from your application.

Generating Encryption Keys

FreeToken supports two different encryption scopes, one for user-specific data and one for public data.

The user-specific key is used for Message and Private Document Store Documents. The public key is used for public Documents.

You can use one or the other, or both, depending on your needs. For example, you may not want to encrypt public documents, but only want to encrypt messages and private documents. Or you may want to encrypt everything. It's up to you.

User Private Key Generation

// Warning: This is the only time you will see this key. Store it securely.
let userPrivateKey: String = client.enableEncryption(scope: .userPrivate)

Public Key Generation

// Warning: This is the only time you will see this key. Store it securely.
let publicKey: String = client.enableEncryption(scope: .sharedPublic)

Enabling the Built-in Encryption

By default, FreeToken does not encrypt data because we want to give you the 🔑 first! Persistence of keys is a tricky problem, and we wanted to ensure you have control over your encryption keys before we start encrypting your user's data.

Enabling for the First Time

When you first configure the FreeToken client on a user's device, you can enable encryption by calling the enableEncryption method. This will generate the keys and store them securely on the device.

// Enable encryption for all user speicific data with it's own key
let userPrivateKey: String = FreeToken.shared.enableEncryption(scope: .userPrivate)

// This key is not user specific, so it may be included in your app's codebase.
let publicKey: String = FreeToken.shared.enableEncryption(scope: .sharedPublic) 

// Configure the client with the generated keys
try FreeToken.shared.configure(
  appToken: "app-token",
  sharedPublicEncryptionKey: userPrivateKey,
  userPrivateEncryptionKey: publicKey)

Using Previously Generated Keys

// Previously generated and stored keys:
let userPrivateKey: String = "..."
let publicKey: String = "..." 

// Configure the keys during client configuration
try FreeToken.shared.configure(
  appToken: "app-token",
  sharedPublicEncryptionKey: userPrivateKey,
  userPrivateEncryptionKey: publicKey)

Enabling your own Encryption Scheme

If you prefer to use your own encryption scheme, you can implement it by providing the necessary closure to encrypt and decrypt data. This allows you to use any encryption method you choose, as long as it takes a String as input and a String as output.

FreeToken.shared.enableCustomEncryption(
  encrypt: { unencryptedString in
    // Your custom encryption logic here

    return encryptedData
  },
  decrypt: { encryptedString in
    // Your custom decryption logic here
    return decryptedData
  }
)

After you define these callbacks, all data sent to and received from the server will be encrypted and decrypted using your custom logic.

Encryption Algorithm

For our built-in encryption, we use 256-bit AES GCM for symmetric encryption. This is a widely accepted standard for secure encryption and is used by many applications and services.

If that isn't sufficient for your needs, you can implement your own encryption scheme with the instructions below.

What's not encrypted?

Data that is sent to third-party services is not encrypted.

  • Web search data - Queries sent to search engines is not encrypted. This includes any search queries made by AI.

  • Cloud inference - We use third-parties to run AI inference in the cloud. We only support providers that do not use your data for training their models, and the data is sent over HTTPS connection.

  • Telemetry - We collect telemetry data an allow you to use this for debugging and monitoring purposes in the web console. This data is not encrypted on the client, but includes no personally identifiable information (PII).

⚠️ Caution

If the exact encryption keys are not sent back into the client during the next configure call, you will lose access to your data. We never have your keys on our servers and therefore we can't recover data.

If encryption is not configured during client configuration, your data will be stored in plain text on the server - but will be passed over HTTPS in transit.