From 4d3c71029137159f518d662ec81d1f6314d65908 Mon Sep 17 00:00:00 2001 From: Josh Pigford Date: Wed, 18 Jun 2025 04:31:10 -0500 Subject: [PATCH] Fix Active Record encryption for self-hosted deployments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-generate encryption keys based on SECRET_KEY_BASE when not provided. This ensures API key encryption works out of the box for self-hosted users without requiring manual setup steps. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .env.example | 8 ++++++ .../initializers/active_record_encryption.rb | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 config/initializers/active_record_encryption.rb diff --git a/.env.example b/.env.example index 528dad8b..f6804fff 100644 --- a/.env.example +++ b/.env.example @@ -51,6 +51,14 @@ APP_DOMAIN= # Disable enforcing SSL connections # DISABLE_SSL=true +# Active Record Encryption Keys (Optional) +# These keys are used to encrypt sensitive data like API keys in the database. +# If not provided, they will be automatically generated based on your SECRET_KEY_BASE. +# You can generate your own keys by running: rails db:encryption:init +# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY= +# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY= +# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT= + # ====================================================================================================== # Active Storage Configuration - responsible for storing file uploads # ====================================================================================================== diff --git a/config/initializers/active_record_encryption.rb b/config/initializers/active_record_encryption.rb new file mode 100644 index 00000000..30d77153 --- /dev/null +++ b/config/initializers/active_record_encryption.rb @@ -0,0 +1,25 @@ +# Auto-generate Active Record encryption keys for self-hosted instances +# This ensures encryption works out of the box without manual setup +if Rails.application.config.app_mode.self_hosted? && !Rails.application.credentials.active_record_encryption.present? + # Check if keys are provided via environment variables + primary_key = ENV["ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY"] + deterministic_key = ENV["ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY"] + key_derivation_salt = ENV["ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT"] + + # If any key is missing, generate all of them based on SECRET_KEY_BASE + if primary_key.blank? || deterministic_key.blank? || key_derivation_salt.blank? + # Use SECRET_KEY_BASE as the seed for deterministic key generation + # This ensures keys are consistent across container restarts + secret_base = Rails.application.secret_key_base + + # Generate deterministic keys from the secret base + primary_key = Digest::SHA256.hexdigest("#{secret_base}:primary_key")[0..63] + deterministic_key = Digest::SHA256.hexdigest("#{secret_base}:deterministic_key")[0..63] + key_derivation_salt = Digest::SHA256.hexdigest("#{secret_base}:key_derivation_salt")[0..63] + end + + # Configure Active Record encryption + Rails.application.config.active_record.encryption.primary_key = primary_key + Rails.application.config.active_record.encryption.deterministic_key = deterministic_key + Rails.application.config.active_record.encryption.key_derivation_salt = key_derivation_salt +end