AWS でパスワードなどの秘密情報をコードに埋め込まずに利用する方法

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

某所で API キーを含む秘密情報をコードに含めて一般公開した為に不正アクセスの原因になった可能性があると話題になっています。

AWS でもサービス利用は基本的には全て REST API を通じて行われため、コードに対して何らかの形でAPIキーとシークレットを渡す必要があります。その為やはり類似の事故が発生する可能性は常にあり、定期的な注意喚起が行われています。

AWS では責任共有モデル1 が採用されており、当たり前のことですがデータの保全処置やパスワードの管理はユーザの責任となります。

そもそもコード中にAPIキーなどの秘密情報を埋め込まなくても安全に利用する仕組みが提供されています。

今回はそのうちのいくつかをご紹介したいと思います。

IAM ユーザ

AWS リソースへのアクセスを制御する最も基本的な機能です。IAM ユーザという単位で ID、パスワードを発行し、マネジメントコンソールへのアクセスを実施します。

またアプリケーションから AWS リソースを利用する場合は、アクセスキーIDとシークレットアクセスキー(以下アクセスキー)を発行して利用することになります。その場合はアクセスキーを所定のファイル(~/.aws/credentials)に保存しコードツリー内には書き込まないことが推奨されます。

通常アプリケーションから、AWS リソースを利用する場合は、利用中の言語に対応する SDK を利用することが多いと思いますが、SDK を利用している場合は所定のファイルを自動的に読み出してアクセスする為、コード上にアクセスキーを登録する必要はありません。

なお、共同開発者同士でも IAM ユーザを共有することは推奨されていません。後述の CloudTrail を利用した流出経路の特定などが困難になる為です。

うっかりの防止 git-secret

上記の通り、通常コード中にアクセスキーを記載する必要はありませんが、それでもちょっとしたメモや、一時的に書いたつもりが消し忘れてコミットしてしまうなどの事故の可能性が考えられます。

その様な事故を防止する為、コミット時などに秘密情報を検出する git プラグインが AWS から提供されています。

git-secrets

IAM ロール

AWS 上にアプリケーションを展開する際は、AMIやインスタンス上に上記 IAM ユーザのアクセスキーをデプロイすることは強く推奨されていません。AMI は共有したり公開することもできるので、AMI を通じたアクセスキーの流出が懸念される為です。

代替手段として、IAM ロールという機能が提供されています。IAM ユーザと同じ様に作成し、適切に AWS リソースへのアクセス権を設定します。違いはインスタンス起動時に、作成した IAM ロールを指定することで、安全にインスタンスに対してアクセスキーを配布することができます。

SDK を利用している場合は、特に IAM ユーザ、IAM ロールの違いを意識する必要はありません。またファイルなどにアクセス権が保存されているわけではないので、流出のリスクを抑えることができます。

開発環境用、本番環境用など用途によってアクセス権を簡単に切り替えられるというメリットもあります。

一時的な認証情報 STS

IAM ユーザの様に比較的長期間固定的に利用するのではなく、短時間だけ一時的にアクセス権を付与もしくは取得したい場合があります。その場合は STS を利用して利用権限を付与することができます。

例えば、外部の作業者に対して1日だけアクセス権を付与したいなどといったユースケースの場合に利用できます。

AWS Secrets Manager

モダンなアプリケーションでは、何らかの形での外部連携が欠かすことができません。その為外部連携に必要な API キーや、クレデンシャル、エンドポイントなどの情報を安全にアプリケーションに対して配布する必要があります。

これらの情報もインスタンスやコード上に保存することは強く推奨されません。代わりに AWS Secrets Manager というサービスが提供されています。

例えばデータベースアクセスに必要な ID、パスワード、ホスト名などの情報を AWS Secrets Manager 上に保存しておき、必要な時に取り出して利用する様に構成できます。

情報の取り出しに対しては、上記 IAMロール・ユーザを利用したアクセス制御によって機密性を保持することができます。

AWS Key Management Service (KMS)

現代では、情報を暗号化して保管することがセキュリティ要件として必要とされるワークロードも多いかと思います。AWS でもブロックストレージの EBS やオブジェクトストレージの S3 など多くのサービスで暗号化をサポートしています。

その場合も暗号化キーの管理が重要となります。AWS Key Management Service 暗号化キーの生成、管理機能を提供します。

キーの取り出しにあたっては、同じくIAMロール・ユーザを利用したアクセス制御によって機密性を保持することができます。

AWS Systems Manager パラメータストア

アプリケーションは一般的に実行時に様々な設定情報を必要とするかと思います。設定情報はコード中に記述することは好ましくなく、実行時に動的に取得するのが理想的です。また設定情報の中にあまり外部に公開したくない情報が含まれる場合もあるでしょう。

その様な場合に AWS Systems Manager パラメータストア に設定情報を保管することで対処できます。

AWS Systems Manager パラメータストア へのアクセスもIAMロール・ユーザによって制御することができ、必要な時に必要な情報を取得することができます。

アプリケーションユーザへの権限付与 Cognito

アプリケーションのユーザに対して、制限されたアクセス権を付与したい場合もあるかと思います。その場合は Cognito が有効でしょう。ID、パスワードを使った認証、外部アカウント連携などを通じて上記で紹介した STS を発行することができます。

不正アクセスの追跡 CloudTrail

万が一機密情報が漏えいした場合や、不正なアクセスを検出するためには API やキーへのアクセス状況を追跡する必要があります。そのためには利用状況のログが必要となりますが、AWS では CloudTrail を有効にすることでログの採取が可能です。

今回紹介した KMS や、Secret Manager からのキーの取得状況をIAMユーザ、ロール毎に把握することもできます。 そのため IAM を個別に発行することでアクセスの詳細な追跡が可能になります。

不正アクセスの検出 GuardDuty

また CloudTrail で単に記録を取るだけでなく、GuardDuty を利用すること API アクセスの不審な挙動を検出することもできます。

GuardDuty についての詳細は以前こちらでも紹介させていただいています。

増加するサイバー攻撃の脅威に対処するには? Amazon GuardDuty のご紹介

以前は推奨されていたが現在はやめたほうがいいこと

環境変数やユーザーデータを利用してインスタンス起動時に秘密情報を渡すこと、また S3 に保存してアプリケーションから読み出すなどの方法も以前は提案されて実際に利用もされていましたが、現在では上記の様に様々なサービスが提供されている為、推奨されていません。

定期的なアーキテクチャの見直しは AWS Well-Architected フレームワークでも強く推奨されているので、この機会に見直してみてはいかがでしょうか。

最後に

AWSサービスを有効に利用することで、パスワードなどの秘密情報の漏えいを防ぎつつ効率よく開発するためのヒントになれば幸いです。今回は各サービスの詳細までは踏み込むことができませんでしたが、機会があれば具体的な利用方法についてもご紹介したいと思います。

今回ご紹介した AWS サービス


  1. 責任共有モデル↩︎