Encryption
Search2o encrypts sensitive information before it is stored. You can switch to end-to-end encryption, where only your enterprise holds the key.
Default: a key managed by Search2o
With encryptionSource set to cloud, Search2o keeps one key per account in a key management service. An agent server fetches the key over TLS when it needs it and keeps it in memory. The agent server encrypts and decrypts; the cloud stores ciphertext and never decrypts your state. Nothing has to be set up, which is why this is the default. Search2o holds the key, so Search2o, and Google as the infrastructure provider, can in principle read what the key protects.
End-to-end: a key you hold
With encryptionSource set to client, the key never leaves your enterprise, and nobody outside it can read the state.
- Write an async Python function that takes a key name and returns the key for that name, as 16, 24 or 32 bytes. The function may read a file, an environment variable or a key management service; anything reachable from the agent server works.
- Name the function as the
encryptionKeyhook, by its dotted path, for examplemycompany.keys.get_key. Install it on every agent server. Each agent server imports it at startup and refuses to run agents until a failed import is fixed. - List the keys in
keys, each with a name and a creation time. The last key in the list is the current key. A name may contain letters, digits and_ - . : /, and must start and end with a letter or digit, so an AWS key ARN or alias and a GCP KMS key path are valid names.
The page refuses to save client until the hook is set, and saving calls the hook once with the current key's name. The save is refused when the hook fails or returns anything but a key of those sizes. From then on the agent server calls your function for every key it needs. The settings are listed below.
Key rotation
Every encrypted value records the name of the key that encrypted it, so several keys can be in use at once. With client-held keys, rotation is adding a new key at the end of the list. The new key encrypts everything from then on. The older keys stay in the list, so that state encrypted under them can still be read; nothing already stored is re-encrypted. An old key is needed for as long as anything encrypted under it is still alive: the 7-day retention of a conversation (a pinned conversation is kept indefinitely, and the paid service has no such limit), and a year after its last use in a query for a long-term memory (or until the agent that stored it is deleted).
With the default setting, an administrator rotates the Search2o-managed key from the License page. Rotation issues a new key for the account, and everything already encrypted stays readable; nothing is re-encrypted. An agent server begins using the new key only when it is restarted. Rotation does not protect data already written under a stolen key; it limits future exposure. Rotation is available at most once every 90 days. If a key is known to be exposed, contact support.
Switching to end-to-end encryption
Switch before the account holds important data. State encrypted under the cloud-managed key stays readable after the switch, and new state is encrypted under your key.
What is encrypted
See Data privacy for the full list. Conversation state can also stay in your enterprise altogether, stored by your own code through the conversation state hooks. The agent server then encrypts nothing on the way out, and encrypting what you store is your choice. The cipher is AES-GCM, and transport between the agent server and the cloud is always TLS.
Settings
The Encryption part is edited in the UI under Operations › Secrets & encryption.
| Field | Type | Default | Description |
|---|---|---|---|
encryptionSource | "client" | "cloud" | "cloud" | By default Search2o manages a key for this account. Override this to use end-to-end encryption, which needs the encryptionKey hook. |
keys | list of EncryptionKey | The keys in use. The last one is current. Keep every key that stored data still uses: conversation state for the account's conversation retention period, pinned conversations for as long as they are kept, and memories for a year after their last use. |
A key
| Field | Type | Default | Description |
|---|---|---|---|
keyNamerequired | string | The name your encryptionKey hook looks the key up by, such as my-key, alias/my-key or a key ARN. Letters, digits and _ . - : /, starting and ending with a letter or digit, up to 256 characters. | |
createdAtrequired | integer | When the key was created, in epoch milliseconds. |

