0. 背景
実務でRails8を触っていたのですが、credentialsの扱いや環境別ファイルとの依存関係がややこしかったのでここで整理します!
1. Rails Credentialsとは
Credentialsは直訳で資格証明書、認証情報といった単語です。
そしてRailsのCredentialsとは一言で言うと、
「アプリの機密情報を、暗号化してGitで安全に管理するための仕組み」
であるといえます!
例えばRailsでアプリ開発をする際、
- データベースにアクセスする際のユーザー名やパスワード
- APIキー
- AWSのアクセスキー
などといったたくさんの機密情報を扱います。
こうした情報はもちろんGitHub上に公開されてはならないトップシークレットですが、
ただチーム開発や企業での開発などにおいては、そうした情報を開発者間で共有する必要があります。
この「共有したいけどGitHubには公開できない」という問題を解決するための、すなわち「機密情報を安全に共有するための」仕組みがCredentialsというわけです!
2. Credentials周りのファイルとそれぞれの役割
Railsには、/config 配下に
credentials.yml.encmaster.key-
credentials/development.yml.encdevelopment.keytest.yml.enctest.keyproduction.yml.encproduction.key
といったファイルが存在します(デフォルトで入っているのはcredentials.yml.encとmaster.keyのみ)。
これらのうち、実際にアプリの機密情報が書かれているのがcredentials.yml.encやdevelopment.yml.encといったファイルで、これらは 暗号化(encrypted)されています。
(.encは「暗号化されているよー」と言う意味)
実際に開いてみると
ynMTeFaIDd8BplF95F9YfWk1VuwhC8IU5px・・・・
のような暗号化された英数文字列が書かれていると思います。
そして、暗号化されている状態では情報の読み取りができないため、それを復号化するのがmaster.keyやdevelopment.keyといった復号鍵ファイル。
(.keyは「復号鍵」としての役割のため)
credentials.yml.encなどは、機密情報が書かれていますが暗号化されているため、GitHubで開発メンバーと共有してOKです。
そしてここが一番重要ですが、
master.keydevelopment.keytest.keyproduction.key
といった復号鍵は、GitHub等に絶対pushしてはいけません!
このファイルが部外者にバレると、credentials.yml.enc等の内容を復号して機密情報が読み取られてしまいます。
例えば...
- データベースのユーザー名とパスワードから、本番環境のデータ(顧客の個人情報など)が読み取られたり書き換えられたりする可能性
- AWSのアクセスキーが盗まれ、勝手にリソースを使用されることで高額請求が発生する可能性
- secret_key_baseが乗っ取られて、管理者権限でログインされたり、Payload(攻撃するためのプログラム)を含んだCookieがサーバーに送り付けられたりする可能性
などなど。
こうした問題を避けるために、デフォルトで.gitignoreには最初から以下のように記述されており、「うっかりGitに入れてしまった!」を防ぐようになっています。
# Ignore master key for decrypting credentials and more.
/config/master.key
/config/credentials/*.key
チーム間で、master.keyなどの中身を共有するときは、
小規模プロジェクトであればSlackのDMや物理的な手渡しなど、
大規模プロジェクトであればAWS Secrets ManagerやGoogle Cloud Secret Managerなどといったクラウドのシークレット管理サービスを活用しましょう!
環境別ファイルの役割と依存関係
RailsのCredentialsには、
credentials.yml.encだけでなく、環境別のdevelopment.yml.encなども存在します。
イメージは、
-
config/credentials.yml.encが共通設定 -
config/credentials/development.yml.encなどが環境固有設定
という感じ。
ここの最も重要なルールは、
「環境別の設定が、共通設定を上書き(オーバーライド)する」
ということです。
【共通】credentials.yml.enc 【環境別】development.yml.enc
------------------------- ------------------------------
aws: aws:
access_key: "COMMON_KEY" access_key: "DEV_KEY" <-- こっちが勝つ!
region: "us-east-1" (regionの記述なし) <-- 共通のまま
⬇ マージ (Merge) ⬇
【最終的な設定値 (Rails.application.credentials)】
aws:
access_key: "DEV_KEY"
region: "us-east-1"
こんな感じで、
「環境別ファイルに書かれていればそれが優先的に適用」
「環境別ファイルに書かれていない項目はcredentials.yml.encの内容が適用」
というポイントだけ抑えておきましょう!