Skip to content

arnabJ/ODMantic-Fernet-Field-Type

Repository files navigation

ODMantic Fernet Field Type

Publish Python Package python-3.9-3.10-3.11-3.12-3.13 Package version PyPI Downloads


A field type that encrypts values using Fernet symmetric encryption.

Features

  • EncryptedString: A custom field type that transparently encrypts data before storing it in MongoDB and decrypts it when retrieved
  • EncryptedInt: A custom field type to encrypt Integer values.
  • EncryptedFloat: A custom field type to encrypt Floats values.
  • EncryptedDecimal: A custom field type to encrypt decimal.Decimal values.
  • EncryptedJSON: A custom field type to encrypt JSONs.
  • Simple integration with ODMantic models
  • Compatible with FastAPI and starlette-admin
  • Keys rotation is possible by providing multiple comma separated keys in the env variable.

Installation

pip install odmantic-fernet-field-type

Quick Start

1. Set up your encryption key

This package requires a Fernet encryption key stored in the FERNET_KEY environment variable. You can generate a suitable key by running:

python -m pip install odmantic-fernet-field-type
fernet-key

This will output a generated key along with instructions for setting up your environment.

2. Basic Usage

Single Key

# .env
...

FERNET_KEY="xxxxxxxyyyyyyyyzzzzzzzzzzz="

Multiple Keys (For rotation)

# .env
...

FERNET_KEY="pppppppqqqqqqqrrrrrrrrrr=,xxxxxxxyyyyyyyyzzzzzzzzzzz="
from decimal import Decimal

from odmantic import Model
# Note: The import package is "odmantic_fernet_field" and not "odmantic_fernet_field_type"
from odmantic_fernet_field import EncryptedString, EncryptedInt, EncryptedFloat, EncryptedJSON, EncryptedDecimal

class User(Model):
    name: str
    email: str
    password_hash: str
    # This field will be automatically encrypted in the database
    secret_answer: EncryptedString
    account_no: EncryptedInt
    account_balance: EncryptedFloat
    bank_details: EncryptedJSON
    amount: EncryptedDecimal

...

# Create and save a user - the secret_answer, account_no, account_balance, bank_details & amount will be encrypted in MongoDB
user = User(
    name="John", email="[email protected]", password_hash="...", secret_answer="April 1st, 2025", account_no=1234567890, 
    account_balance=1000000.00, amount=Decimal("100.00"), bank_details={
        "accountHolder": "John Doe",
        "accountNumber": 1234567890,
        "type": "Checking",
        "isActive": True
    }
)

# When you retrieve the user, the secret_answer is automatically decrypted
retrieved_user = await engine.find_one(User, User.email == "[email protected]")
assert retrieved_user.secret_answer == "April 1st, 2025"  # This will pass!

Integration with FastAPI and starlette-admin

The package has been tested and works with FastAPI and starlette-admin:

from fastapi import FastAPI
from starlette_admin import Admin
from starlette_admin.contrib.odmantic import ModelView
from models import User

app = FastAPI()
admin = Admin(title="Admin Panel")

class UserAdmin(ModelView):
    # Configure your admin view
    pass

admin.add_view(UserAdmin(User))
admin.mount_to(app)

Security Considerations

  • Never hardcode encryption keys in your source code
  • Use environment variables
  • Rotate your encryption keys periodically
  • Back up your encryption keys—if lost, encrypted data cannot be recovered

Compatibility

  • Python 3.9+
  • ODMantic 1.0.2+
  • MongoDB 6.0+
  • Tested with MongoDB 8.0.5

Dependencies

  • odmantic 1.0.2+
  • python-dotenv 1.0.1+
  • cryptography 44.0.2+

Inspiration

This package was inspired by django-fernet-fields, which provides similar functionality for Django models.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

A field type that encrypts values using Fernet symmetric encryption.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages