【Rails7】Multi Environment Credentialsで秘匿情報を管理する方法

# Multi Environment Credentialsとは
　　
Rails6から秘匿情報を環境毎に管理することができる仕組みがサポートされています。
以前までの方法では、credentials.yml.enc内に`development:` `staging:` `production:` `test:` とまとめて記述していましたが、master.keyを知っている開発メンバーであれば全員がproduction環境にもアクセスできてしまうという問題を抱えていました。
```ruby:config/credentials.yml.enc
development:
         aws:
           access_key_id: 123
           secret_access_key:345
production:
        aws:
          access_key_id: 123
          secret_access_key:345
... 
```
この様にすべての環境をまとめて記述します。

　　
Multi Environment Credentialsは以下の構成のように、環境毎のcredentials.yml.encとmaster.keyがconfig/credentials配下に作成・配置されることになります。


```
├── config
│   ├── credentials 　　　　　　　　　　　　　　　#環境毎で設定を変える場合
│  　　│　　　 　├── development.key
│  　　│　　　 　├── development.yml.enc
│  　　│　　　 　├── production.key
│  　　│　　　 　├── production.yml.enc
│  　　│　　　 　├── staging.key
│  　　│　　　 　├── staging.yml.enc
│  　　│　　　 　├── test.key
│  　　│　　　 　└── test.yml.enc
│   ├── credentials.yml.enc #全環境共通で使われる秘匿情報を管理
│   ├── master.key
```
credentials.yml.encとmaster.keyはconfig配下に格納されています。

このように環境毎に設定ファイルとキーを用意することで、開発者のステージに合った情報のみ提供することができます。


# credentials.yml.encとは

  [![Image from Gyazo](https://i.gyazo.com/dc57e9246f5595d368c2859fcfdd0295.png)](https://gyazo.com/dc57e9246f5595d368c2859fcfdd0295)
  
credentials.yml.encは秘匿情報の設定ファイル、master.keyがそのファイルを復号化（暗号化されたデータを読める状態に戻すこと）する際に用いられるキーになります。復号化の鍵であるmaster.keyがなければcredentials.yml.encのファイルを閲覧・編集することができません。

[![Image from Gyazo](https://i.gyazo.com/8607798d26be6029e1bbef17cbfdd2a5.png)](https://gyazo.com/8607798d26be6029e1bbef17cbfdd2a5)
この様に暗号化されています。

# master.keyとは

 [![Image from Gyazo](https://i.gyazo.com/7312d9199319eef0e35cc87738417d97.png)](https://gyazo.com/7312d9199319eef0e35cc87738417d97)
 
master.keyは秘匿情報の設定ファイルであるcredentials.yml.encを開くためのキーです。
[![Image from Gyazo](https://i.gyazo.com/54a944988fadaa428de281e2e347d7ac.png)](https://gyazo.com/54a944988fadaa428de281e2e347d7ac)
このキーを使い、credentials.yml.encを復号化します。

master.keyを知っていれば秘匿情報のデータを閲覧することができてしまいます。そのため、master.keyは第三者や外部の人間に知られてはいけません。

master.keyは`rails new`した段階で生成され、同時に.gitignoreに入ります。間違ってもGithubやSNSといったオープンな場にmaster.keyの情報をアップロードしないよう注意しましょう。
チーム開発の際はプライベートな方法で共有されます。



# Multi Environment Credentials使い方
　　
**【環境毎のcredentials.yml.encとmaster.keyを生成】**

生成コマンド
```ruby:ターミナル
# development環境
EDITOR="vim" rails credentials:edit --environment development

# test環境
EDITOR="vim" rails credentials:edit --environment test

# staging環境
EDITOR="vim" rails credentials:edit --environment staging

# production環境
EDITOR="vim" rails credentials:edit --environment production
```

credentials.yml.encを扱うのにエディターが必要になります。上記コマンドはvimを使用する設定になっています。他のエディターを使用したい場合、"vim"を変更してください。

　　
**【ファイルの編集】**
　　
development環境の秘匿情報を例に編集してみます。
```
EDITOR="vim" rails credentials:edit --environment development
```
[![Image from Gyazo](https://i.gyazo.com/e104e51f6c5f4d25f127dda1f3a7bc46.png)](https://gyazo.com/e104e51f6c5f4d25f127dda1f3a7bc46)


コマンドを実行すると、ターミナルでエディターが開かれます。

**vimの場合**
`i`キーを押してINSERTモードに切り替えます。
↓
中身を編集します。
↓
`esc`キーでINSERTモードを解除します。
↓
`:w`保存　`:q`エディターを閉じる　`:wq`両方同時に行う

[![Image from Gyazo](https://i.gyazo.com/334231a378978b8ceee97c001a15e8a3.png)](https://gyazo.com/334231a378978b8ceee97c001a15e8a3)
今回外部認証でGitHubとGoogleログインを実装しました。
callbak_urlは秘匿しなくてもいいかなと思いましたが念のため(?)ここに記述しました。ご意見お待ちしております。

　　
**【値の取得】**
先ほど編集した秘匿情報がちゃんと取り出せるか確認してみましょう。
```ruby:コマンド例
% rails c

# 取得方法1
> Rails.application.credentials[:aws][:access_key_id]
=> "dev123"

# 取得方法2
> Rails.application.credentials.aws[:access_key_id]
=> "dev123"

# 取得方法3
Rails.application.credentials.dig(:aws, :access_key_id)
=> "dev123"
```

[![Image from Gyazo](https://i.gyazo.com/0c887854c5e53a7f07206dfcb675fad3.png)](https://gyazo.com/0c887854c5e53a7f07206dfcb675fad3)

実際にコンソールで試して、ちゃんと値が返ってくるのが確認できました。

```ruby:config/initializers/sorcery.rb
  config.github.key = Rails.application.credentials.dig(:github, :key)
  config.github.secret = Rails.application.credentials.dig(:github, :secret)
  config.github.callback_url = Rails.application.credentials.dig(:github, :callback_url)
```

秘匿情報をコード内で使用する場合はこのように記述します。

　　
**【ファイルの秘匿】**
```ruby:.gitignore
/config/credentials/development.key

/config/credentials/production.key
```
ファイルを生成した段階で自動的に.gitignoreに追加されます。

## 最後に
今回、Githubでログインする際に、developmentとproductionでのcallback先を変えたくて記事を探していたところ、Multi Environment Credentialsにたどり着きました。
Rails６からのサポートということで試したくなり、無事こちらに移行できました。

参考資料が丁寧すぎてほぼなぞっているだけですが、自分なりに理解したことを記録するために記事にしました。

　　
Rails６以前の場合はcredentials.yml.encにそれぞれの環境下を記述する方法があります。

https://techtechmedia.com/credentials-masterkey-rails/


　　
# 参考資料
https://techtechmedia.com/multi-environment-credentials/