Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 7.1: ローカル環境のsecret_key_baseの保存場所がcredentialsに変わる(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

この変更は、Railsのsecretsをcredentialsに移行する一連の取り組みの一環です。

参考: Add credentials using a generic EncryptedConfiguration class by dhh · Pull Request #30067 · rails/rails

Rails 7.1: ローカル環境のsecret_key_baseの保存場所がcredentialsに変わる(翻訳)

RailsのcredentialsはRails 5.2で導入されました。Rails 7.1では従来のsecretsが非推奨となり、代わりにcredentialsが使われるようになります。

本記事執筆時点の最新の安定版Rails(Rails 7.0.6)では、ローカル環境でのsecret_key_baseの保存場所としてsecretsが使われています。しかしRails 7.1からは、secret_key_baseの保存場所がcredentialsに移動します。

🔗 secret_key_baseとは何か

Rails(7.0)のAPIドキュメントには以下のように書かれています。

secret_key_baseは、アプリケーションのキージェネレーターへの入力secret(秘密情報)として使われることで、ActiveSupport::MessageVerifierおよびActiveSupport::MessageEncryptorのあらゆるインスタンスを作成するのに使われます(cookieに署名や暗号化を行うインスタンスも含まれます)。
Rails API secret_key_base -- Rails::Applicationより

secret_key_baseは、暗号理論におけるsalt1に似たランダムな生成文字列です。secret_key_baseの値は、主にアプリケーション内のcookieやセッションなどのデータを不正なユーザーによる改ざんから防ぐための追加のセキュリティ層として使われます。

secret_key_baseが使われる場所は、ActiveSupport::MessageVerifierActiveSupport::MessageEncryptorです。

ActiveSupport::MessageVerifier
改ざんを防ぐために署名付きメッセージを生成・検証します。
ActiveSupport::MessageEncryptor
値をBase64形式で暗号化し、安全にその値を渡せるようにします。

ローカルのdevelopment環境とtest環境におけるsecret_key_base値は、tmp/development_secret.txt(Rails 7.0まで)またはtmp/local_secret.txt(Rails 7.1以降)から取得します。

これらのファイルには、secret_key_baseとして使われる値が含まれます。


development/test以外の環境におけるsecret_key_base値の取得元は、以下の上から順に試行されるようになります。

  • ENV["SECRET_KEY_BASE"]
  • credentials.secret_key_base
  • secrets.secret_key_base

Dockerイメージのビルド中は、アセットをプリコンパイルする必要があります。このとき本物の秘密鍵を渡す必要はなく、ENV["SECRET_KEY_BASE_DUMMY"]環境変数に何らかのランダムな値を渡しておけばプリコンパイルできるようになります2。これらの値はsecret_key_baseに保存されます。

🔗 改修前

従来のRails 7.0では、secret_key_baseをRails.application.secrets.secret_key_baseに保存します。

アプリケーションでsecret_key_baseの値を取得することも、以下のようにRailsコンソールで取得することも可能です。

Rails.application.secrets.secret_key_base

# "e965987d66462fdf254a9b11aec30dbc27e37e53c01babfd0a52745d66e6f4ad186ee80151628c72cd0c0"

Rails.application.credentials.secret_key_base

# "e965987d66462fdf254a9b11aec30dbc27e37e53c01babfd0a52745d66e6f4ad186ee80151628c72cd0c0"

🔗 改修後

#48470の変更によって、secret_key_baseの保存場所はRails.application.credentials.secret_key_baseに変わります。

Rails.application.credentials.secret_key_base

# "e965987d66462fdf254a9b11aec30dbc27e37e53c01babfd0a52745d66e6f4ad186ee80151628c72cd0c0"

Rails.application.secrets.secret_key_base

# DEPRECATION WARNING: `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2. (called from eval at /Users/gowsikvivekanandan/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.7.4/lib/irb/workspace.rb:113)

# "e965987d66462fdf254a9b11aec30dbc27e37e53c01babfd0a52745d66e6f4ad186ee80151628c72cd0c0"

secret_key_base値をsecretsから取得しようとすると、上のように非推奨警告が出力され、secretsが次のRails 7.2で廃止されることをユーザーに通知します3

🔗 secret_key_baseの正しい取得方法

secretscredentialsにある secret_key_baseに直接アクセスするのではなく、以下のように常にRails.application.secret_key_base呼び出しで値を取得することが推奨されています。

Rails.application.secret_key_base

# "e965987d66462fdf254a9b11aec30dbc27e37e53c01babfd0a52745d66e6f4ad186ee80151628c72cd0c0"

このRails.application.secret_key_baseは、現在の環境に応じたsecret_key_base値を返します。

関連記事

保存版: Railsアプリケーションのセキュリティベストプラクティス(翻訳)


  1. 訳注: ソルト (暗号) - Wikipedia 
  2. 訳注: SECRET_KEY_BASE_DUMMY環境変数もRails 7.1で導入されました(#46760)。 
  3. 訳注: この改修は#48472で行われました。 

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。