-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP 🔑feat: Implement End-to-End Encryption E2EE
Across Messaging
#5906
base: main
Are you sure you want to change the base?
Conversation
small issue to fix. when full response is received it replaces the text with the text from the DB. and then the decryption is not yet implement.
# Conflicts: # client/src/components/Nav/SettingsTabs/Chat/EncryptionPassphrase.tsx # client/src/hooks/SSE/useSSE.ts # packages/data-provider/src/types.ts
const { encryptionPublicKey, encryptedPrivateKey, encryptionSalt, encryptionIV } = req.body; | ||
|
||
// Allow disabling encryption by passing null for all fields. | ||
const allNull = encryptionPublicKey === null && encryptedPrivateKey === null && encryptionSalt === null && encryptionIV === null; |
Check failure
Code scanning / ESLint
Enforce a maximum line length Error
[message.messageId, latestMessage?.messageId], | ||
); | ||
const showCursorState = useMemo(() => showCursor === true && isSubmitting, [showCursor, isSubmitting]); | ||
const isLatestMessage = useMemo(() => message.messageId === latestMessage?.messageId, [message.messageId, latestMessage?.messageId]); |
Check failure
Code scanning / ESLint
Enforce a maximum line length Error
E2EE
Across MessagingE2EE
Across Messaging
…aintext but from the stream the final response is encrypted.
user && typeof user === 'object' | ||
? user | ||
: (this.options.req && this.options.req.user | ||
? this.options.req.user | ||
: { id: user }); |
Check warning
Code scanning / ESLint
Disallow nested ternary expressions Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no nested ternaries please
@danny-avila need some help here 😅 to decrypt the https://github.com/user-attachments/assets/616be36c-7cca-4b97-8c09-36b25073f720![]() |
const { logger } = require('~/config'); | ||
|
||
let crypto; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move this encryption function outside of this module to where the other encryption methods live.
@@ -13,6 +13,77 @@ import Container from './Container'; | |||
import Markdown from './Markdown'; | |||
import { cn } from '~/utils'; | |||
import store from '~/store'; | |||
import { useAuthContext } from '~/hooks/AuthContext'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest making no changes here, as it could impact rendering performance
user && typeof user === 'object' | ||
? user | ||
: (this.options.req && this.options.req.user | ||
? this.options.req.user | ||
: { id: user }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no nested ternaries please
const dbUser = await getUserById(currentUserId, 'encryptionPublicKey'); | ||
|
||
// --- NEW ENCRYPTION BLOCK: Encrypt AI response if encryptionPublicKey exists --- | ||
if (dbUser.encryptionPublicKey && message && message.text) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if possible, consolidate the encryption logic to its own function and outside of this module
* @param {string} pemPublicKey - The RSA public key in PEM format. | ||
* @returns {Object} An object containing the ciphertext, iv, authTag, and encryptedKey. | ||
*/ | ||
function encryptText(plainText, pemPublicKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move this encryption function outside of this module to where the other encryption methods live. also it seems duplicated elsewhere
the hook
what this function returns is what ends up getting cached in the query cache, so it would be best to do it here, i think. to use atom store, you would need to move https://tanstack.com/query/v4/docs/framework/react/reference/useQuery Reference ℹ️ ^ |
E2EE
Across MessagingE2EE
Across Messaging
Summary
This PR introduces a comprehensive end-to-end encryption (E2EE) feature that secures both message content and user credentials using modern cryptographic standards. The changes span across backend models, API endpoints, controllers, and client-side components to ensure that sensitive data is encrypted during transit and at rest.
Closes: #5712
reference: #5856
Key highlights include:
Message Encryption:
Message
model and its schema have been updated to include additional fields such asiv
,authTag
, andencryptedKey
for storing encryption metadata. These changes propagate through all related methods (e.g., saving, updating, and retrieving messages) to handle encryption parameters properly.User Encryption Settings:
EncryptionPassphrase
, has been added to the settings tab. Users can set or change their encryption passphrase. The passphrase is used to derive a symmetric AES-GCM key (via PBKDF2) to encrypt the user’s RSA private key.null
, ensuring that no cryptographic operations occur when handling messages or other sensitive data.Controller Enhancements:
AskController
now includes an encryption branch. If the user has a valid encryption public key, the plaintext response is encrypted before being sent to the client. This ensures that even automated or AI-generated messages are secured.Client-Side Decryption:
MessageContent.tsx
) have been updated to include decryption logic. If a message is received with encryption metadata (i.e.,iv
,authTag
, andencryptedKey
), the client uses the stored RSA private key (after decryption with the user’s passphrase) to decrypt the AES key, which in turn decrypts the message.API & Data Provider Adjustments:
/api/user/encryption
) has been added to handle updates to user encryption settings.useSetUserEncryptionMutation
) have been implemented to seamlessly update user encryption keys from the client.Change Type
Testing
To test the E2EE functionality, please follow these steps:
Test Configuration:
Checklist