話題の記事

【鍵管理】~/.aws/credentials を唯一のAPIキー管理場所とすべし【大指針】

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。AWSを利用していると、APIキーの利用は必要不可欠です。数多くのAWSアカウントを扱っていれば、たまたまAPIキーは利用せず、管理コンソールへのパスワードだけで済んでしまうケースもあるかもしれませんが、これはごく例外的な状況です。しっかりとAWSを使いこなしている以上、APIキーを管理する機会が必ずあります。

鍵管理が大変

というわけで、皆さんは自分用のAPIキーを数多く管理しているわけですが、その管理は行き届いているでしょうか。少なくとも「失くしたwww」なんていう事態は是非避けたいものです。大丈夫すか?

では、とあるキーがありましで、それが書き込まれている場所を全て挙げられますか? あちこちのファイルに書き込んだりしていませんでしょうか。aws-cli用の設定ファイルはもちろん、環境変数設定用の~/.bash_profileの中、シェルのhistoryファイル内、開発中のアプリケーションのソースの中や設定ファイルの中、そしてDropboxにコピーを置き、Evernoteにも書き込んであり…。

仮にこのような状況だったとして、アクセスキーのローテーション作業ができますか? ローテした途端に何かが動かなくなる恐怖に怯えたくはありませんね。

指針!

私は自分が管理するAPIキーを、作業マシンの~/.aws/credentialsにしか書き込まないことを、ここに宣言します *1

というわけでタイトルの通りですが。この共通設定ファイル~/.aws/credentialsが唯一のAPIキー保存場所です。ここからキーを消せば、このキーが使われることは二度とありません。ローテーションも楽々です。

~/.aws/credentialsは、aws-cli用のキー設定ファイルである、という認識が一般的かもしれません。いや、当初は確かにその通りでした。しかし現在では、AWS SDKfor Rubyでもfor Python (boto)でも、for Javaでも、このロケーションが事実上標準になっています。

つまり、このファイルにさえクレデンシャルを書き込んでおけば、どんなプログラム、スクリプトからでも簡単に読み出しができる、ということです。なので、今現在、他の場所にクレデンシャルを書く必要があるケースは、ほぼ無いと考えて差し支えありません。まぁ、ちょっくらコードを書く必要はあるかもしれませんが、その辺はみなさんエンジニアなんですからどうでもしてください。

まぁ、とりあえずこれを指針として明文化するのが大事だと思ってこのエントリーを書きました。APIキーをどこかのファイルに直書きしたくなった時に、ふと思い出してください。共通設定ファイルだけに書き込んで、そこから読み出すような仕組みがつくれないか? と自問してください。

そして、断腸の思いで「別の場所に書く」という選択をしたのなら、共通設定ファイル内に懺悔のポエムでも書いておくこと。

ここからはJavaの話、そして余談。

以前、こんなエントリーを書きました。この(2)の方ですが、この当時はまだ、AWS SDK for Javaに共通設定ファイルを読み出す仕組みはありませんでした。が、まぁ前述の通り、最新版にはあります。

このエントリーでは、「Javaアプリケーション内でAWSのAPIクライアントを使う場合は、引数なしのコンストラクタでインスタンスを作るべし」と結論付けています。そうすれば "環境変数" → "Javaシステムプロパティ" → "EC2インスタンスプロファイル(IAM Role)" の順にクレデンシャルを自動的に探してくれるため、ローカルでの開発環境やEC2上で共通のコードが使えます。

少し前の話になりますが、去年の5月にリリースされたAWS SDK for Java 1.7.8から、上記の流れに「共通設定ファイルから読み出す」という仕組みが追加になりました。要するに以下のようになりました。

  1. 環境変数
  2. Javaシステムプロパティ
  3. 共通設定ファイル (New!)
  4. EC2インスタンスプロファイル(IAM Role)

さて問題はここからでした。これは大変嬉しい機能でしたが、では共通設定ファイルの情報を使う、となった場合、どのプロファイルを使うのか? という選択です。特に何も指定しなければdefaultを利用します。これを変更するにはAWS_PROFILEという環境変数にプロファイル名を指定します。

ただ、これを環境変数からではなく、Javaシステムプロパティからコントロールする仕組みが今までありませんでした。例えば「Gradleの中から、Gradle自身のJVMプロセスを使ってSpringBootを起動する *2」場合、Gradleスクリプトの中では環境変数を書き換えられないため、プロファイル名を設定できませんでした。

という部分にアチャーとなった都元は、プルリクを送って、本日無事1.9.19としてリリースの運びとなりました。

aws.profileというシステムプロパティにプロファイル名を書いておけば、任意のプロファイルを利用してアプリケーションをローカル起動できます!

これで、もうGradleの設定ファイルやシェルのhistoryに機密情報を書き込んでしまう、という事態ともオサラバであります。

脚注

  1. まぁ、今日宣言したばかりなので、まだ私自身、この指針に対する違反を数箇所認識しています。これらは近々に是正していく所存。
  2. とっても特殊事情な話をしていますw