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:

  1. Add new key version to configuration
  2. Update current_key_version
  3. Re-encrypt existing data using re_encrypt_fields!
  4. Verify migration completion
  5. 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_status to track encryption state

Next Steps

After implementing security features:

  1. Review Architecture Migration for persistence improvements
  2. Explore Relationships Migration for the relationship system