ODAI encrypts all sensitive tokens and credentials before storing them in Firestore. Encryption is handled by Google Cloud Key Management Service (KMS) using user-specific keys, so no two users’ data can be decrypted with the same key.
What is encrypted
The following data is encrypted at rest before being written to Firestore:
| Data | Firestore collection |
|---|
| Google OAuth tokens (access token, refresh token, client credentials) | google_tokens |
| Plaid access tokens | plaid_tokens |
| Plaid item IDs | plaid_tokens |
| Evernote OAuth tokens | evernote_tokens |
Non-sensitive data — such as user profile fields, chat history, integration status flags, and account metadata like bank names and masked account numbers — is stored in plaintext.
Encryption model
ODAI uses symmetric encryption via Google Cloud KMS. When a token is received from an OAuth provider, it is:
- Serialized to JSON
- Encrypted with the user’s KMS key
- Base64-encoded
- Written to Firestore as a string
When the token is needed to make an API call, the process is reversed: the stored string is Base64-decoded and decrypted with KMS before use.
User-specific encryption keys
Each registered user has a dedicated KMS key. This means a compromise of one user’s key does not expose any other user’s data.
Keys are created automatically in Google Cloud KMS when a user first registers. The key identifier (key_id) is stored in the user’s Firestore document and is used for all encryption and decryption operations for that user.
Key generation is skipped in local development environments. Tokens stored locally are Base64-encoded but not encrypted with KMS.
Key rings
ODAI uses two KMS key rings in the global region:
| Environment | Key ring |
|---|
| Development | odai |
| Production | production |
All keys are HSM-backed (Hardware Security Module), providing the highest level of protection against key extraction.
Local development
In local development mode (LOCAL=true), token encryption is bypassed. Tokens are Base64-encoded before storage as a lightweight substitute, but no KMS operations are performed. This allows you to run the application without Google Cloud credentials.
Never use local development mode in a production environment. Base64 encoding is not encryption and provides no security.