はじめに
Rails の Credentials の機能がどんなものなのか?は割愛しますが、デフォルトで読み込まれる yml.enc 以外を使いたい場合ってありませんか?
一般的には無いかもしれませんが自分の環境ではあったんですよ。その為に credentials で読み込まれる yml.enc がどのように決まるか?というあたりのコードを少し前に読んで理解〜となったのでメモを残す。
環境は Rails7.0
デフォルトで読み込まれる yml.enc に関して
まずは rails new した後の config 内はこんな感じ
$ ls -1 config application.rb boot.rb cable.yml credentials.yml.enc database.yml environment.rb environments importmap.rb initializers locales master.key puma.rb routes.rb storage.yml # credentials.yml.enc を編集したい場合は下記のようにすればよい $ EDITOR=vi bundle exec rails credentials:edit # 下記で中身の確認ができる $ bundle exec rails credentials:edit
次に environment 毎に yml.enc を分けたい場合はどうするか?というと下記のようにする
$ EDITOR=vi bundle exec rails credentials:edit --environment development # 保存すると Adding config/credentials/development.key to store the encryption key: xxxxxxxxx Save this in a password manager your team can access. If you lose the key, no one, including you, can access anything encrypted with it. create config/credentials/development.key Ignoring config/credentials/development.key so it won't end up in Git history: append .gitignore File encrypted and saved. # production の場合は $ EDITOR=vi bundle exec rails credentials:edit --environment production $ ls -1 config application.rb boot.rb cable.yml credentials credentials.yml.enc database.yml environment.rb environments importmap.rb initializers locales master.key puma.rb routes.rb storage.yml $ ls -1 config/credentials development.key development.yml.enc production.key production.yml.enc
こんな感じになります。.key に関しては下記のように環境変数で指定する方が楽かなと個人的には思います。
$ RAILS_MASTER_KEY=xxxxx EDITOR=vi bundle exec rails credentials:edit --environment production
この状態だと RAILS_ENV が development/production の場合はそれぞれ config/credentials/development.yml.enc と config/credentials/production.yml.enc が読み込まれます。
では RAILS_ENV test だとどうなるかというと config/credentials.yml.enc が読み込まれます。
このようにどの yml.enc を使うか?を決めているのが下記のコード
難しいコードでは無いので読んでもらえればわかりますが config/credentials/#{Rails.env}.yml.enc が存在すればそちらを、存在しない場合は config/credentials.yml.enc を読み込むという感じになっています。
基本的な挙動はこれでおしまいです。
独自のルールで yml.enc を指定したい
ここからが本題
上記で基本的に読み込まれる yml.enc に関しては理解できましたが独自のルールで読み込まれる yml.enc を決めたいとなった場合にどうするか?というと下記のようにします。
# config/application.rb などで module Testapp class Application < Rails::Application config.credentials.content_path = Rails.root.join("config/credentials/#{ENV.fetch('CREDENTIALS_FILE')}.yml.enc") # key を RAILS_MASTER_KEY で指定せず file として読み込ませたい場合 config.credentials.key_path = Rails.root.join("config/credentials/#{ENV.fetch('CREDENTIALS_FILE')}.key") end end
もちろん file name を決める部分は環境変数である必要はなく独自のロジックを書いて決定しても問題ありません。
編集する場合は下記のようにします。
$ RAILS_MASTER_KEY=xxxxx EDITOR=vi bundle exec rails credentials:edit --environment hoge
ただし上記の場合若干罠があり file 名を dev や prod にしたい場合できないという問題が発生します。
dev にすると config/credentials/development.yml.enc が prod にすると config/credentials/production.yml.enc が編集されます。
これはなぜかというと下記のようなコードになっているからです。
environment で渡した値が env として渡ってくるのですが config/environments/ 内に該当の file が存在しない場合 production/development/test に前方一致で正規表現をかけられ match したものが採用されます。そのため dev を指定しても config/credentials/development.yml.enc が編集されるということになります。
ではこういう場合はどうするかというと下記のコマンドで編集が可能です。
$ RAILS_MASTER_KEY=xxxxxx EDITOR=vi bundle exec rails encrypted:edit config/credentials/dev.yml.enc
最後に
config.credentials.content_path をいじったりしないでそのまま使えるのが一番ですよ