How to inject or access user's contextual data within a custom Ecto.Type?

I am trying to figure out how to inject the current user data into a custom Ecto.Type field.
The custom field is suppose to encrypt/decrypt using the user’s own key when it is loaded and save.

How to “inject” user (contextual) data into the custom Ecto.type field?

1 Like

Not sure I understand the question (sorry! :frowning: ) … are you able to post some code (even if it does not compile/work…) showing what you are attempting / wanting to do?

I suppose you have created a module with the Ecto.Type behavior as described here: … are you now trying to use it in a query, or in a schema, or …?

1 Like


Thanks for helping.

Here’s the gist of the code I am trying out.
See the function MyApp.EncryptionTool.encrypt/1 and MyApp.EncryptionTool. decrypt/1.

So I am trying to encrypt and decrypt the field value with the user’s own key, but I can’t figure out how to ‘inject’ the user’s key into any point of the process where ecto save or load the data.

1 Like

Ecto Types are functional, so they don’t really give you an opportunity to introduce external data into the mix. They’re effectively custom reversible hash functions to help translate in-memory values to the external ones your persistence layer supports.

To accomplish what you are looking to do you entirely within an Ecto type you would need some sort of global mutable state that knew what the current user is, accessible from anywhere. I’m sure this can be jury rigged somehow but I wouldn’t recommend it.

TL;DR you have to do this outside of the Ecto type since you need to supply user-specific information to do the encryption. Depending on your use case you could use database-level encryption, or in-app encryption based on a user id or token (see: Phoenix.Token). But you can’t do it at the translation layer between the two. :slight_smile:


Thanks @christhekeele, I share your thoughts.

It’s been a good learning experience to see if there is anyway to do this without some sort of global state.


Given that multiple requests (and therefore multiple users) may be being served at the same time, this would be difficult. I suppose one could always drop the key into an ETS table mapped to the current process or similar … but yeah … that would be SUPER brittle and also open the door for potential security issues w/regards the keys …

It would probably make a lot more sense to do the crypto outside the ecto queries and just pass in encrypted data and decrypt the encrypted data that is returned.