| @技術/プログラミング

Rails 5.1 から入った Encrypted Secrets というのがある。 OAuth の client_secret などパスワード的なやつを暗号化して保存する仕組み。この手のやつはこれまで環境変数などにして dotenv などの機能を使ってそれぞれの環境ごとに .env ファイルを置く、というのがベストプラクティスだったと思うけど、 Encrypted Secrets を使えば秘密情報も暗号化してリポリトリに放りこめるので管理対象が少なくなって便利になる。暗号化するときの鍵は RAILS_MASTER_KEY という環境変数に格納するか、 gitignore した上で config/secrets.yml.key という名前で配置すると Rails がいい感じに読み取ってくれる。

Rails のエコシステムには config (旧 rails_config )という gem もあって、こいつも設定系の情報を入れておく用途によく使う。秘密系の情報と設定系の情報でどちらに値が入っているかを意識するのがめんどい& Rails.application.secrets.foo_bar とか入力するのが長い& Encrypted Secrets は YAML をネストさせられないのがだるいので、 config.gem の config/settings.yml の中で以下のようにしたら便利ではないかと思ってやってみた。

foo:
  bar: <%= Rails.application.secrets.foo_bar %>

呼び出し側の before after はこんな感じ。

Before

bar = Rails.application.secrets.foo_bar

After

bar = Settings.foo.bar

「めっちゃ最高便利じゃん」と思っていたけど、これをやると副作用がでかい。なんと Rails.application.secretsfoo_bar が見つからなくなる! というか Rails.application.secrets がほぼほぼ空になる!!!、!

[3] pry(main)> Rails.application.secrets
=> {:secret_key_base=>"xxx", :secret_token=>nil}

config/settings.yml から Encrypted Secrets を参照しているコードを取り除くと見えるようになる。

結論

というわけで config/settings.yml の中に Rails の Encrypted Secrets を混ぜて使うと危険っぽいです ☢️