Active Record Encryption のキーを環境変数で直接指定可能に
#56455 で導入された Rails.app.creds の仕組みを活用し、Active Record Encryption の暗号化キーを専用の環境変数名で直接指定できるようになりました。これにより、config/application.rb に手動設定コードを書く必要がなくなります。
背景
これまで Active Record Encryption のキーを環境変数から設定するには、config/application.rb に明示的なコードを記述する必要がありました。公式ドキュメントでも以下のような手動設定例が案内されていました。
config.active_record.encryption.primary_key = ENV["ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY"]
config.active_record.encryption.deterministic_key = ENV["ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY"]
config.active_record.encryption.key_derivation_salt = ENV["ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT"]
この方式はアプリケーションコードへの侵食を招き、暗号化キーの取得経路をアプリケーション側で管理しなければならないという問題がありました。一方、#56455 によって Rails.app.creds は ENV、.env ファイル、暗号化済みcredentialsの順で値を解決できる統合インターフェースとして整備されていました。
本PRはこの Rails.app.creds の能力を活かし、規約となる環境変数名を定めることで、設定コードなしにキーを注入できる仕組みを確立します。
技術的な変更
activerecord/lib/active_record/railtie.rb の active_record_encryption.configuration イニシャライザが、app.credentials.dig から app.creds.option へ切り替わりました。
変更前:
initializer "active_record_encryption.configuration" do |app|
ActiveSupport.on_load(:active_record_encryption) do
ActiveRecord::Encryption.configure(
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
**app.config.active_record.encryption
)
変更後:
initializer "active_record_encryption.configuration" do |app|
ActiveSupport.on_load(:active_record_encryption) do
ActiveRecord::Encryption.configure(
primary_key: app.creds.option(:active_record_encryption, :primary_key),
deterministic_key: app.creds.option(:active_record_encryption, :deterministic_key),
key_derivation_salt: app.creds.option(:active_record_encryption, :key_derivation_salt),
**app.config.active_record.encryption
)
app.credentials.dig はRailsの暗号化済みcredentialsファイルのみを参照していましたが、app.creds.option は ENV → .env → 暗号化済みcredentials の順で値を解決します。これにより、以下の環境変数名を持つ値が自動的に認識されます:
ACTIVE_RECORD_ENCRYPTION__PRIMARY_KEYACTIVE_RECORD_ENCRYPTION__DETERMINISTIC_KEYACTIVE_RECORD_ENCRYPTION__KEY_DERIVATION_SALT
環境変数名の区切りに ダブルアンダースコア(__) が採用されている点が重要です。app.creds.option(:active_record_encryption, :primary_key) の呼び出しは、ネストされたキーパス active_record_encryption.primary_key に対応する環境変数として ACTIVE_RECORD_ENCRYPTION__PRIMARY_KEY を探します。シングルアンダースコアはキー名内の区切り文字として使われるため、ネストの区切りにはダブルアンダースコアが使用される規約です。
また、既存の暗号化済みcredentialsファイルに active_record_encryption.primary_key を記述する運用は引き続き動作します。解決の優先順位上、環境変数が存在すればそちらが優先されます。
設計判断
app.creds という統合インターフェースを経由させる設計が採用されました。
Active Record Encryption のキー取得ロジックをアプリケーション層(config/application.rb)からフレームワーク層(railtie)へ移動した点が本PRの本質です。環境変数を直接 ENV[] で参照する従来の手動設定では、キー名の命名が各アプリケーションに委ねられていましたが、今回の変更で ACTIVE_RECORD_ENCRYPTION__* という規約名が標準として確立されました。
この設計は app.creds が持つ多段解決の仕組みをそのまま利用しており、railtie 側に条件分岐を追加していません。ENV、.env、credentialsのどのソースから値が来るかはフレームワークが透過的に処理するため、アプリケーションコードはキーの出所を意識する必要がなくなります。
まとめ
本PRは Rails.app.creds の多段解決能力を Active Record Encryption のキー設定に適用し、規約となる環境変数名を定めることで設定の定型コードを不要にした変更です。app.credentials.dig から app.creds.option への1行の切り替えが、暗号化キーの管理をアプリケーション層からフレームワーク層へ引き上げるという設計上の意味を持ちます。