Encrypting email address in db with Email Auth
Wasp/OpenSaas newbie here. I've privacy conscious users and want to show I'm taking steps to protect stored personally identifiable information. This means encrypting their login email address in the DB.
Is there a way to do this by injecting custom logic/overriding functions in the right places in the email auth provider so I'm not covering the same ground? Or am I going to have to write a whole auth flow to do what I want?
I'd like users to still able to easily request a password reset and stuff, which is why I don't want to swap to the username auth. I think the overall approach should work because any time we need to email the user, they're inputting their email address anyway.
9 Replies
Hi @gumboots. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Currently, Wasp's email authentication system doesn't provide built-in functionality for encrypting email addresses in the database. However, you can customize the authentication flow to implement this feature.
Customizing Email Auth
Wasp allows you to create custom sign-up and login actions where you can implement your encryption logic. You can use the helper functions provided by Wasp to handle the authentication process while adding your own encryption layer.
Creating a Custom Sign-up Action
You can create a custom sign-up action where you encrypt the email before storing it:
Password Reset Flow
The good news is that Wasp's password reset flow should still work with your encrypted email approach since, as you mentioned, users input their email address when requesting a password reset. Wasp provides built-in functionality for password reset with rate limiting and security features Password Reset Flow.
Email Configuration
You'll also need to configure email sending in your Wasp app:
You can choose from providers like Mailgun, SendGrid, or SMTP as mentioned in the Email documentation.
Considerations
1. You'll need to implement your own encryption/decryption functions.
2. Remember that the
providerId
in Wasp's auth system uses the unencrypted email, so the authentication flow can still work.
3. You'll need to handle email verification and password reset carefully to ensure they work with your encryption approach.
While this approach requires some custom code, you don't need to rewrite the entire auth flow. You can leverage Wasp's helper functions and just add your encryption layer where needed.
The knowledge sources don't provide specific examples of email encryption in Wasp, so you might need to implement this yourself using standard encryption libraries in your Node.js backend.
I'm a Wasp newbie myself, but this approach seems feasible based on the documentation available.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @gumboots, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?@kapa.ai I'm not sure this is what I want. In the code below, I think this will still store their email in plain text, but also add extra data to store the encrypted email? I need a solution where the email is never stored in plain text.
await createUser(
providerId,
providerData,
// Store encrypted email in User entity
{ encryptedEmail },
)
Let me check the knowledge base for you again. One moment! :books:
----------------------
You're absolutely right, and I apologize for the confusion. Looking more closely at how Wasp's auth system works, the email would still be stored in plain text in the
AuthIdentity
entity, even if you add an encrypted version to the User
entity.
The providerId
in Wasp's auth system is created using the unencrypted email, and this is stored in the database. This is a limitation of the current implementation.
Current Auth Storage in Wasp
In Wasp's auth system, user credentials are stored in the AuthIdentity
entity, which is automatically created and managed by Wasp. The email address is used as part of the providerId
and is stored in plain text.
Possible Approaches
1. Custom Auth Implementation: You would need to create your own authentication system from scratch, bypassing Wasp's built-in auth features. This is a significant undertaking.
2. Username Auth with Email Field: Use Wasp's username authentication instead, and have a separate encrypted email field for communications. However, this would make password reset flows more complex.
3. Feature Request: Consider submitting a feature request to the Wasp team. Looking at their GitHub issues, there have been discussions about auth improvements, including JWT secret handling and email functionality.
Current Limitations
The knowledge sources don't provide a direct way to encrypt the email address in the auth system while maintaining all the functionality like password reset. The email auth method in Wasp is designed with the assumption that the email is stored in a retrievable format.
From the documentation, it appears that Wasp's auth system is not currently designed to support fully encrypted email addresses in a way that would maintain all functionality like password reset and verification.
If privacy is a critical requirement for your application, you might need to consider implementing a custom authentication solution or exploring other frameworks that provide more flexibility in this area.
I apologize that I don't have a more direct solution based on the available knowledge sources.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @gumboots, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?Well that's frustrating, considering that I was thinking that all I need to do is encrypt the email address before it's saved on a sign up, and then tweak the parameters on login + signup +reset pwd to encrypt the email address before searching for a matching user. Damn
A few thoughts:
1. While email addresses are indeed PII, they're generally considered as non-sensitive, so encrypting them — especially in isolation — would offer marginal privacy benefits for your users, while introducing non-trivial technical challenges for you.
2. Encryption introduces a set of new considerations. How are you going to store and retrieve your encryption keys securely? What's your strategy if a key needs to be revoked? What happens if an attacker gains access to more than just the database?
3. Encrypting at the application level means you'd need to modify every touchpoint in your codebase that reads or writes a user's email address (e.g. payment subscriptions, newsletters, etc). It might be better to try database-level encryption (e.g. pgcrypto), although it's not obvious how well that might work with Wasp/Prisma
Is there a specific reason you want to encrypt your email addresses? If you want to improve your overall security/privacy posture, I'd suggest there are other, less disruptive ways to do it:
- Regular system audits
- Tightening access controls
- Implementing logging/monitoring and intrusion detection
- Minimising stored PII data volume
PostgreSQL Documentation
F.26. pgcrypto — cryptographic functions
F.26. pgcrypto — cryptographic functions # F.26.1. General Hashing Functions F.26.2. Password Hashing Functions F.26.3. PGP Encryption Functions F.26.4. Raw Encryption …
These are great points, thanks for such a considered response.
I was hoping to encrypt the email addresses because of mental health factors in the user base. A large portion is likely to be concerned about any of their data being linked back to something that could identify them. They might also have memory challenges, so i still need a forgot password mechanism.
Aside from email address there'd be one text field that could contain PII, but encrypting a custom data field is much easier than a login email address.
Even though I can guide them on "hide my email" tools and things, being able to say "even we don't know your email address, it's not in plain text in the database" could go a long way in helping them feel comfortable, and so more likely to use the tool. I know it's a huge pain in the butt and rarely done, but it's an easily understandable thing to put forward as reassurance to non tech users. I guess it's more about perception?
Aside from using email as a mechanism for password reset, we have no emails or newsletters, no marketing, no direct contact. News / updates would be through the app itself. Most features free. With a bit of extra work I can integrate with a payment provider based solely on customer id, though payment success / failure / receipt would all need to be communicated in the app itself (in my case, this is fine).
So I was thinking one way encryption... at the moment I can't see I'd have a need to decrypt the email address.
Wohooo @gumboots, you just became a Waspeteer level 1!
It was something I wanted to explore. It's not the end of the world if I don't do it, but it would have been nice for me to achieve. I was all "ooooh I think it's less than a dozen lines I'd need to change, I hope I can do it easily" 😅 ah well.
Great points @genyus ! Anything you want to add @miho ?