Skip to main content

Tink-based encrypted model fields for Django

Project description

Django Tink Fields

PyPI version Python Support Django Support License Code style: black Tests

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.

✨ Features

  • 🔐 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

🚀 Quick Start

Installation

pip install django-tink-fields

Basic Configuration

Add to your settings.py:

TINK_FIELDS_CONFIG = {
    "default": {
        "cleartext": True,
        "path": "/path/to/your/keyset.json",
    }
}

Create a Keyset

Generate a test keyset using tinkey:

tinkey create-keyset \
    --out-format json \
    --out keyset.json \
    --key-template AES128_GCM

Use in Your Models

from 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()

📖 Documentation

Supported Field Types

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

Configuration Options

Cleartext Keysets (Development/Testing)

TINK_FIELDS_CONFIG = {
    "default": {
        "cleartext": True,
        "path": "/path/to/cleartext_keyset.json",
    }
}

Encrypted Keysets (Production)

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,
    }
}

Multiple Keysets

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,
    }
}

Advanced Usage

Custom Keyset per Field

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)

Associated Authenticated Data (AAD)

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
    )

Field Validation

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)

Key Management

Creating Keysets with tinkey

Cleartext keyset (development):

tinkey create-keyset \
    --out-format json \
    --out dev_keyset.json \
    --key-template AES128_GCM

Encrypted 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-key

Encrypted 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

🔒 Security Considerations

Best Practices

  1. Key Management: Use encrypted keysets in production with proper key management systems
  2. Key Rotation: Implement regular key rotation strategies
  3. Access Control: Restrict access to keyset files and master keys
  4. AAD Usage: Use AAD to bind encryption to specific contexts
  5. Field Selection: Only encrypt truly sensitive data to maintain performance

Limitations

  • 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

🧪 Testing

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

🛠️ Development

Setup Development Environment

# 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 .

Code Quality

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

📊 Performance

Benchmarks

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

Optimization Tips

  1. Use appropriate field types - CharField for short text, TextField for long content
  2. Cache keysets - Keysets are automatically cached for performance
  3. Minimize AAD complexity - Keep AAD callbacks simple and fast
  4. Batch operations - Process multiple records together when possible

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Workflow

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

📝 Changelog

v0.3.0 (Latest)

  • ✨ 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

v0.2.0

  • 🐛 Fixed compatibility issues
  • 📦 Updated package structure

📄 License

This project is licensed under the BSD License - see the LICENSE file for details.

🙏 Acknowledgments

📞 Support


Made with ❤️ for the Django community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_tink_fields-0.3.1.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_tink_fields-0.3.1-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file django_tink_fields-0.3.1.tar.gz.

File metadata

  • Download URL: django_tink_fields-0.3.1.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_tink_fields-0.3.1.tar.gz
Algorithm Hash digest
SHA256 1ee38cec4795d58057364d77365b00b7bbbe3026990f7027e03fdb1e00bb7fa6
MD5 66e742305a46cf678399ba7d8b1f3cf6
BLAKE2b-256 45333d2aac19241309f1db2cbecc910c0452656e2b422e8e69471d339150a392

See more details on using hashes here.

File details

Details for the file django_tink_fields-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_tink_fields-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 53b2e0783843ebc1afd8e9c1e25092f419f7e16093cd66d8f17eeb09c726129d
MD5 1d7491d026fb1b88b32908872537a148
BLAKE2b-256 5ae6ed9f45c008b914e8b1994c8d1086eb2ff3d9fd4a1bbbe86928f5417ed448

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page