Migrating Guide: Security Features (v2.0.0-pre5)
This guide covers adopting the security enhancements introduced in v2.0.0-pre5.
Security Feature Adoption
1. Configure Encryption Keys
Before using encrypted fields, configure encryption keys:
Familia.configure do |config|
config.encryption_keys = {
v1: 'your-32-byte-base64-encoded-key==',
v2: 'newer-32-byte-base64-encoded-key=='
}
config.current_key_version = :v2
end
Key Management:
- Use secure key storage (environment variables, key management services)
- Rotate keys regularly by adding new versions
- Never remove old key versions while data exists
2. Identify Sensitive Fields
Mark fields that contain sensitive data:
For Encryption:
class Vault < Familia::Horreum
feature :encrypted_fields
field :name # Plaintext
encrypted_field :secret_key # Encrypted at rest
encrypted_field :api_token # Transparent access
end
For Transient Fields:
class User < Familia::Horreum
feature :transient_fields
field :email # Persisted
transient_field :password # Never persisted
transient_field :session_token # Runtime only
end
3. Update Serialization Code
Handle ConcealedString in serialization:
Before:
def to_json
{ name: name, password: password }.to_json
end
After:
def to_json
# ConcealedString automatically excluded from serialization
{ name: name }.to_json # password field omitted if transient
end
Manual ConcealedString Handling:
# Access original value when needed
password.reveal # Returns actual string value
password.cleared? # Returns true if cleared from memory
4. Implement Key Rotation Procedures
Rotation Process:
- Add new key version to configuration
- Update
current_key_version - Re-encrypt existing data using
re_encrypt_fields! - Verify migration completion
- Remove old keys after migration complete
Example Rotation Script:
# Step 1: Add new key version
Familia.configure do |config|
config.encryption_keys = {
v2: ENV['OLD_ENCRYPTION_KEY'],
v3: ENV['NEW_ENCRYPTION_KEY']
}
config.current_key_version = :v3
end
# Step 2: Validate configuration
Familia::Encryption.validate_configuration!
# Step 3: Re-encrypt existing records
Vault.all.each do |vault|
vault.re_encrypt_fields! # Re-encrypts with current key
vault.save
end
# Step 4: Verify migration
Vault.all.each do |vault|
status = vault.encrypted_fields_status
puts "Vault #{vault.identifier}: #{status}"
end
# Step 5: Remove old key (after verification)
Familia.config.encryption_keys.delete(:v2)
Security Best Practices
- Environment Variables: Store keys in environment variables, not code
- Key Rotation: Rotate encryption keys regularly (quarterly/annually)
- Field Selection: Only encrypt fields that truly need protection
- Memory Clearing: Use transient fields for temporary sensitive data
- Logging: Verify ConcealedString prevents accidental logging
- Configuration Validation: Use
validate_configuration!before production - Monitoring: Use
encrypted_fields_statusto track encryption state
Next Steps
After implementing security features:
- Review Architecture Migration for persistence improvements
- Explore Relationships Migration for the relationship system