Encryption
Dits supports end-to-end encryption for sensitive content, ensuring your files remain private even on shared storage.
Encryption Overview
Dits encryption protects your content at multiple levels:
At Rest
Chunks are encrypted before being written to storage. Even with storage access, data is unreadable.
In Transit
All transfers use TLS encryption. Optional additional layer of content encryption for zero-trust scenarios.
Key Management
Flexible key management with support for passphrases, key files, and hardware security modules.
Quick Start
Enable Encryption on New Repository
# Initialize with encryption
$ dits init --encrypt
Enter encryption passphrase: ********
Confirm passphrase: ********
Initialized encrypted Dits repository in .dits
Encryption: AES-256-GCM
Key derivation: Argon2id
Your repository is now encrypted. Keep your passphrase safe!Enable Encryption on Existing Repository
$ dits encrypt enable
Enter encryption passphrase: ********
Confirm passphrase: ********
Encrypting repository...
Encrypting 45,892 chunks... done
Updating metadata... done
Repository encrypted. All existing and new data is now protected.Encryption Algorithms
Default: AES-256-GCM
Dits uses AES-256-GCM for chunk encryption:
- AES-256: Industry-standard symmetric encryption
- GCM mode: Authenticated encryption (integrity + confidentiality)
- Per-chunk nonces: Each chunk has a unique nonce
Key Derivation: Argon2id
Passphrases are converted to keys using Argon2id:
Key Derivation Parameters:
Algorithm: Argon2id
Memory: 64 MB
Iterations: 3
Parallelism: 4
Salt: 32 bytes (random per repository)
Output: 256-bit keyKey Management
Passphrase
# Set passphrase interactively
$ dits encrypt set-passphrase
# Use environment variable
$ export DITS_PASSPHRASE="your-secure-passphrase"
$ dits pull
# Use passphrase file
$ dits config encrypt.passphraseFile ~/.dits-passphrase
$ chmod 600 ~/.dits-passphraseKey Files
# Generate a key file
$ dits encrypt generate-key ~/.dits-key
Generated 256-bit key file: ~/.dits-key
Keep this file secure!
# Use key file
$ dits config encrypt.keyFile ~/.dits-key
# Or via environment
$ export DITS_KEY_FILE=~/.dits-keyCombining Methods
# Use both passphrase AND key file (most secure)
$ dits config encrypt.keyFile ~/.dits-key
$ dits config encrypt.requirePassphrase true
# Now both are required to decryptKey Backup Warning
If you lose your encryption key/passphrase, your data is permanently unrecoverable. Always maintain secure backups of your keys.
Selective Encryption
Encrypt specific files while leaving others unencrypted:
# .ditsattributes
# Encrypt confidential files
contracts/*.pdf encrypt=true
financial/*.xlsx encrypt=true
# Encrypt all video in specific folder
client-confidential/** encrypt=true
# Don't encrypt public assets
public/** encrypt=false
# Encrypt by default for entire repo
* encrypt=true
public/** encrypt=falseCheck Encryption Status
$ dits encrypt status
Repository Encryption: ENABLED
Algorithm: AES-256-GCM
Key derivation: Argon2id
File Status:
contracts/agreement.pdf ENCRYPTED
footage/scene1.mov ENCRYPTED
README.md ENCRYPTED
public/logo.png UNENCRYPTED
Encrypted: 45,890 chunks (12.5 GB)
Unencrypted: 2 chunks (150 KB)Convergent Encryption
By default, Dits uses convergent encryption which allows deduplication to work across encrypted data:
Standard encryption:
Same file → Different ciphertext (random IV)
Result: No deduplication possible
Convergent encryption:
Same file → Same ciphertext (content-derived key)
Result: Deduplication works!
Dits approach:
chunk_key = HKDF(master_key, chunk_hash)
ciphertext = AES-GCM(chunk_key, nonce, plaintext)
Same chunk + same master key = same ciphertext
Deduplication preserved across encrypted repos!Security Trade-off
Convergent encryption reveals if two chunks are identical. For maximum security at the cost of deduplication, use:
dits config encrypt.convergent falseTeam Encryption
Shared Key Distribution
# Export encrypted key for team member
$ dits encrypt export-key --for jane@example.com > jane-key.enc
# Jane imports the key
$ dits encrypt import-key jane-key.enc
Enter your personal passphrase: ********
Repository key imported.Role-Based Access
# Set up key hierarchy
$ dits encrypt add-key --role editor
$ dits encrypt add-key --role reviewer --read-only
# Assign roles
$ dits encrypt grant editor jane@example.com
$ dits encrypt grant reviewer client@example.com
# Reviewers can read but not modify encrypted contentConfiguration
# .dits/config
[encrypt]
# Enable encryption
enabled = true
# Algorithm
algorithm = aes-256-gcm
# Key source (passphrase, keyfile, or both)
keySource = passphrase
# Key file path
keyFile = ~/.dits/keys/project.key
# Require passphrase in addition to key file
requirePassphrase = false
# Use convergent encryption (enables dedup)
convergent = true
# Key derivation parameters
argon2Memory = 65536
argon2Iterations = 3Best Practices
- Use strong passphrases: At least 16 characters with mixed case, numbers, and symbols
- Back up your keys: Store key files in a secure location separate from the repository
- Rotate keys periodically: Change encryption keys for long-lived projects
- Audit access: Regularly review who has access to encryption keys
- Use key files for CI: Don't store passphrases in CI systems; use key files with restricted access
Commands Reference
# Enable/disable encryption
$ dits encrypt enable
$ dits encrypt disable
# Key management
$ dits encrypt set-passphrase
$ dits encrypt generate-key <path>
$ dits encrypt rotate-key
# Status and verification
$ dits encrypt status
$ dits encrypt verify
# Team management
$ dits encrypt add-key --role <role>
$ dits encrypt grant <role> <email>
$ dits encrypt revoke <email>