Encrypted database fields

Rational
Sometimes sensible user data has to be stored in the database. Most commonly they are credentials for external systems due to an automated communication fromTryton.

Obviously, they should be encrypted in the database.

This can be done with a functional field but I wish Tryton solved this issue out of the box.

Proposal
The API I imagine would be similar to the Functional field:

secret = fields.Encrypted(
    fields.Char('Secret')
)

or maybe

secret = fields.EncryptedChar('Secret')

That should be enough. The modules using such a field would be responsible for restricting read field permission by groups and domain rules.

Search would be out-of-scope. (yet)

Encryption key rotation should be an essential feature. It can be easily achieved by using https://cryptography.io/en/latest/fernet/#cryptography.fernet.MultiFernet . What I can’t depict is how and when sysadmins could trigger a full database rekey. Maybe with the trytond-admin tool?

Implementation
I once implemented this with a hacked Function field, overriding the set and get methods of the Field class, but that code is gone :frowning: . It was a proof of concept lacking some desirable features and tests. But I know it is feasible if the community agrees it is convenient.

Although slightly different, and just for reference, there is another proposal to Add in/out transformation for Binary, which could potentially be used for encrypting data in fields.

2 Likes