Django Tink Fields provides encrypted Django model fields using Google Tink cryptographic library. This package offers field-level encryption for Django models with strong security guarantees and easy integration.
- π Strong Encryption: Uses Google Tink for state-of-the-art cryptographic operations
- π‘οΈ AEAD Security: Provides both confidentiality and integrity through Authenticated Encryption with Associated Data
- π§ Easy Integration: Drop-in replacement for Django's standard field types
- β‘ High Performance: Optimized with caching and efficient key management
- π Flexible Key Management: Support for both cleartext and encrypted keysets
- βοΈ Cloud Integration: Works with AWS KMS, GCP KMS, and other key management systems
- π Comprehensive Testing: 97%+ test coverage with modern Python practices
- π Modern Python: Supports Python 3.10+ with full type hints
pip install django-tink-fieldsAdd to your settings.py:
TINK_FIELDS_CONFIG = { "default": { "cleartext": True, "path": "/path/to/your/keyset.json", } }Generate a test keyset using tinkey:
tinkey create-keyset \ --out-format json \ --out keyset.json \ --key-template AES128_GCMfrom django.db import models from tink_fields import EncryptedCharField, EncryptedTextField class UserProfile(models.Model): name = EncryptedCharField(max_length=100) bio = EncryptedTextField() email = EncryptedEmailField() age = EncryptedIntegerField() created_at = EncryptedDateTimeField()| Field Type | Django Equivalent | Description |
|---|---|---|
EncryptedCharField | CharField | Encrypted character field |
EncryptedTextField | TextField | Encrypted text field |
EncryptedEmailField | EmailField | Encrypted email field |
EncryptedIntegerField | IntegerField | Encrypted integer field |
EncryptedDateField | DateField | Encrypted date field |
EncryptedDateTimeField | DateTimeField | Encrypted datetime field |
TINK_FIELDS_CONFIG = { "default": { "cleartext": True, "path": "/path/to/cleartext_keyset.json", } }from tink.integration import gcpkms from tink import aead # Register AEAD primitives aead.register() # Configure GCP KMS TINK_MASTER_KEY_URI = "gcp-kms://projects/your-project/locations/global/keyRings/your-keyring/cryptoKeys/your-key" gcp_client = gcpkms.GcpKmsClient(TINK_MASTER_KEY_URI, "") gcp_aead = gcp_client.get_aead(TINK_MASTER_KEY_URI) TINK_FIELDS_CONFIG = { "default": { "cleartext": False, "path": "/path/to/encrypted_keyset.json", "master_key_aead": gcp_aead, } }TINK_FIELDS_CONFIG = { "default": { "cleartext": True, "path": "/path/to/default_keyset.json", }, "sensitive": { "cleartext": False, "path": "/path/to/sensitive_keyset.json", "master_key_aead": sensitive_aead, } }class SensitiveData(models.Model): # Uses the "sensitive" keyset secret = EncryptedCharField(max_length=100, keyset="sensitive") # Uses the default keyset public_data = EncryptedCharField(max_length=100)Add additional context to your encryption for enhanced security:
def get_aad_for_field(field): """Generate AAD based on field and model context.""" return f"model_{field.model._meta.label}_{field.name}".encode() class UserData(models.Model): # Each field gets unique AAD ssn = EncryptedCharField( max_length=11, aad_callback=get_aad_for_field )Encrypted fields support all standard Django field validators:
class ValidatedModel(models.Model): email = EncryptedEmailField(unique=True) age = EncryptedIntegerField(validators=[MinValueValidator(18)]) name = EncryptedCharField(max_length=50, blank=False)Cleartext keyset (development):
tinkey create-keyset \ --out-format json \ --out dev_keyset.json \ --key-template AES128_GCMEncrypted keyset with GCP KMS:
tinkey create-keyset \ --out-format json \ --out prod_keyset.json \ --key-template AES256_GCM \ --master-key-uri=gcp-kms://projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/my-keyEncrypted keyset with AWS KMS:
tinkey create-keyset \ --out-format json \ --out prod_keyset.json \ --key-template AES256_GCM \ --master-key-uri=aws-kms://arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012- Key Management: Use encrypted keysets in production with proper key management systems
- Key Rotation: Implement regular key rotation strategies
- Access Control: Restrict access to keyset files and master keys
- AAD Usage: Use AAD to bind encryption to specific contexts
- Field Selection: Only encrypt truly sensitive data to maintain performance
- No Database Queries: Encrypted fields cannot be used in database queries (except
isnull) - No Indexing: Encrypted fields cannot be indexed or used as primary keys
- Performance: Encryption/decryption adds computational overhead
- Key Management: Requires careful key management and rotation
The package includes comprehensive tests with 97%+ coverage:
# Run tests pytest # Run with coverage pytest --cov=tink_fields --cov-report=html # Run specific test categories pytest tink_fields/test/test_fields.py # Basic functionality pytest tink_fields/test/test_coverage.py # Edge cases# Clone the repository git clone https://github.com/script3r/django-tink-fields.git cd django-tink-fields # Create virtual environment python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate # Install development dependencies pip install -r requirements-dev.txt # Install package in development mode pip install -e .The project uses modern Python tooling:
# Format code black tink_fields/ isort tink_fields/ # Lint code flake8 tink_fields/ # Type checking mypy tink_fields/ # Run all quality checks tox| Operation | Time (ΞΌs) | Memory (KB) |
|---|---|---|
| Encrypt 1KB | ~50 | ~2 |
| Decrypt 1KB | ~45 | ~2 |
| Field Creation | ~5 | ~1 |
Benchmarks on Python 3.13, Django 5.2, with AES128_GCM
- Use appropriate field types -
CharFieldfor short text,TextFieldfor long content - Cache keysets - Keysets are automatically cached for performance
- Minimize AAD complexity - Keep AAD callbacks simple and fast
- Batch operations - Process multiple records together when possible
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
- β¨ Modernized codebase with Python 3.10+ support
- π§ Updated dependencies to latest versions
- π Improved test coverage to 97%+
- π¨ Applied modern Python formatting and linting
- π Enhanced documentation and examples
- π Fixed compatibility issues
- π¦ Updated package structure
This project is licensed under the BSD License - see the LICENSE file for details.
- Google Tink - The cryptographic library powering this package
- Django Fernet Fields - Original inspiration for this project
- Django Community - For the amazing framework
- π Documentation
- π Issue Tracker
- π¬ Discussions
Made with β€οΈ for the Django community