🔑

シークレット情報の管理・運用について

2021/12/24に公開

この記事はUnipos advent calendar 23日目の記事です。
この記事では、僕が最近取り組んでいたシークレット情報の管理と運用について得られた知見を書いていこうと思います。
23日の日付が変わるか変わらないか、ギリギリのラインで書いております。
過ぎました。すみません。
そして、zennへの記事の投稿は初めてです。よろしくおねがいしますmm

シークレット情報とは

シークレット情報といえば、ぱっと思いつくものは外部サービスと通信する際に使用するtoken類がぱっと思いつきますが、それ以外にもsqlサーバーやキャッシュサーバーに接続するためのパスワードなども挙げられると思います。今回はこういった情報をシークレット情報と呼んでいきます。
これらの情報をどのようにで扱うべきか書いていきます。

リポジトリはプライベートだし、扱うも何も安全じゃない??

そんなことはありません。確かにリポジトリはプライベートかもしれませんが、プライベートなリポジトリだとしても、シークレット情報は漏洩する事件等は起きております。つまり、プライベートなリポジトリだからといって、ソースコード内に安易にシークレット情報を載せてしまうのはあまり安全とは言えません。

じゃあどうするの?

gcpやawsにあるsecret managerなどを利用しましょう

Secret Managerは安全なの?

こちらはシークレット情報の暗号化などが行われるため、ソースコード内にベタ書きするよりは安全と言えます。
また、Secret Managerではシークレット情報のバージョン管理などもできるため、シークレット情報のリフレッシュなどもやりやすくなっています。
更に、シークレット情報にアクセスできるアカウントを限定したりもできるので、よりセキュアと言えるでしょう。

Secret Managerの使い方

Secret Managerの基本的な使い方に関しては、今回の主眼ではないので、割愛します。
こちらの記事などが参考になると思います。

使うとどうなるの??

具体的な実装等も調べれば情報は日本語でもあるのでそこも割愛しようと思いますが、具体例を出すと、環境変数を .env から設定していた場合、.envファイルがこうなります(berglasを使った場合)

API_KEY = "xxxxxxxxxxxxx"(実際のtoken)

API_KEY = "sm://myProject/mySecret"

これで、サーバーを起動すると、環境変数の値が、mySecretの値に差し替わっているという感じです。
これでソースコードからシークレット情報を除くことが出来ますね!完璧だ!

これで終わりじゃないのよ

今回は管理と運用という事で、管理はここまでで出来たかなと思います。今度は運用に目を向けていきます。
ということで、今流行りのIaC化しましょう。

Secret Managerのシークレットをterraformで作る

作ること自体は簡単です。こんなコードでOK。

resource "google_secret_manager_secret" "my_secret" {
  secret_id = "secret"

  labels = {
    label = "my-label"
  }

  lifecycle {
    prevent_destroy = true
  }

  replication {
    automatic = true
  }
}

これで、planしてapplyすればシークレットの完成です!

いやいや、これじゃ肝心のシークレットの値が入ってないじゃないの

そうです、これはあくまでもシークレットを入れるための入れ物をつくっただけの状態なので、実際のシークレットはまだ入っておりません。
では、それもterraformでやりましょう。。。。。とはなりませんね。
terraformのコードもgit管理されてます。今回は、シークレット情報をリモートリポジトリに載せないようにするためにやっているので、ここで書いてしまっては台無しです。勢い余ってせっかくソースコードを取り除いたシークレット情報を載せてしまわないように気をつけましょう。(ここ、テストに出ます)
この先をコードに書くことは出来ないので、手動で実施することになるのかなと思います。

実はもう一個ポイントがあります

この部分がちょっとポイント(大したものでは無いですが。)です。

lifecycle {
    prevent_destroy = true
}

terraformでは、リソースに変更があるとき、一度destroyしてからcreateするときがあります。もし、そのタイミングでアプリケーションサーバーがSecret Managerから値を引こうとしてしまうと壊れる可能性があるので、そういった事故を防ぐために意図せず事前にシークレットが削除されることを防ぐ工夫をしています。

Secret Managerをterraform化して嬉しいの?

開発環境全てで用意しないといけないものなので、たくさんの環境に同じものを用意する必要があります。そうなると作成も簡単になりますし、typoなどのミスもなくなります。また、すべての環境で間違いなく同じ環境が再現できていると言えるのも嬉れしいです。
また、どういったシークレット情報を扱っているかも見通しが良くなりますし、terraform外からの意図しない変更等も防ぎやすくなります。
また、手運用でSecret Managerを管理しようとすると、おそらく何に使ってるのかよくわからない、消していいのか、消したら何かが壊れるのかわからないシークレットまみれになることが起きるかもしれません。そういったもことも防げるし、コメントで何に使っている物なのかも残せるので嬉しいですね。

最後に大事なこと。

githubにもともと載せていたシークレット情報をSecret Managerに載せたからと言って安心してはいけません。commitたどれば残っています。
ソースコードからシークレット情報を排除したあとは、トークン類を再生成するなどして、最新の情報はソースコード内からは辿れない状況を作るようにしましょう。

まとめ

ここまで、Secret Managerの運用に関してつらつらと書いてきましたが、Secret Managerの使い方に関しては結構いろいろな記事があると思います。が、運用まで見越した記事はそこまで多くない気がしたので書いてみました。参考になれば幸いです。

Discussion