うん!アプリケーションで使うAPIキーやデータベースの認証情報みたいな機密情報を安全に管理して、必要なときだけ取り出せるようにしてくれるんだよね!
『秘密を守る金庫』みたいでワクワクするよね!
うんうん。その金庫を安全に使うには、正しい設定と運用が必要なんだよ。
今回はその使い方について解説するよ!
この記事では、AWS Secrets Managerを使ってServerless Framework(※)のserverless.yml
から機密情報を安全に取得する方法を解説します。
Secrets Managerでのシークレット作成から、動作確認まで、初心者でも分かりやすいステップでご紹介します。
AWSの「秘密を守る金庫」を正しく使いこなすための第一歩を踏み出しましょう。
Serverless Frameworkは、サーバーレスアプリケーションを簡単に構築・管理できるオープンソースフレームワークです。AWS LambdaやAPI GatewayなどのAWSサービスを効率的にデプロイできるツールで、特に複雑なサーバーレス構成のデプロイや管理に優れています。
Serveless Frameworkについて詳しく知りたい方は、以下の記事をご覧ください。
本ブログで用いているプロジェクトはGitHubリポジトリで公開しています。
以下のリンクからダウンロードしてください。
https://github.com/my-repo-441/SecretsManager-Demo
AWS Secrets Managerとは?
AWS Secrets Managerは、セキュリティを大幅に向上させるための非常に役立つサービスです。
このサービスを利用することで、データベースの認証情報やAPIキーなどの機密情報を安全に管理し、アプリケーションからAPIを介して簡単に取得できます。
1. 機密情報の一元管理:
- Secrets Manager を使用することで、すべての機密情報を AWS 管理の一元化された環境で安全に保存できます。
2. IAM による厳格なアクセス制御:
- Secrets Manager は IAM ポリシーを利用してアクセス制御が可能。特定のサービスやユーザーだけがアクセスできるように設定できます。
3. 動的なシークレットの更新:
- シークレットを更新すると、それを利用するアプリケーションに即座に適用されます。再デプロイの必要がありません。
4. ログと監査の提供:
- Secrets Manager は CloudTrail を通じてすべての操作(取得、更新、削除)を記録。セキュリティインシデントの監視が容易です。
5. 直接記載からの解放で安全性向上:
serverless.yml
に機密情報を記載しないことで、バージョン管理や公開時の事故を未然に防げます。
機密情報管理の重要性
現代のアプリケーション開発では、APIキーやデータベースの認証情報など、多くの機密情報を管理する必要があります。
例えば、Serverless Framework を使用する際には、APIキーなどの環境変数を設定ファイル(serverless.yml
)に直接記載するのはセキュリティリスクを高める原因になります。
具体的には、以下のようなリスクが考えられます。
- バージョン管理システムへの漏洩
serverless.yml
に機密情報を記載していると、Git などのバージョン管理システムにその情報が含まれ、誤って公開されるリスクが高まります。
- チームでの共有時の課題
- ファイルを通じて機密情報を共有する場合、意図しないアクセスや操作が発生する可能性があります。
- セキュリティ標準への準拠不足
- 多くのセキュリティ基準(例: ISO27001、SOC2)では、機密情報の安全な管理が求められます。
AWS Secrets Manager を使うことで、機密情報を安全に管理しながら開発効率を維持することが可能になります。
Secrets Managerの検証手順
本ブログでは、以下の手順でSecrets Managerの動作検証を行います。
- Secrets Managerでシークレット作成
- Secrets Managerのコンソール画面から、API キーのシークレットを作成します。
- AWS CLIからシークレット取得
- AWS CLIを使って、シークレットが作成できているかをどうか確認します。
- Serverless Framework の設定
serverless.yml
に IAM ポリシーを追加し、Lambda 関数からSecrets Managerにアクセスできるよう設定します。
- Lambda 関数での取得ロジック
- AWS SDKであるboto3を使用して、Secrets Managerからシークレットを取得する実装を紹介します。
上記の手順で構築できる検証環境の構成図は以下です。
API GatewayからLambdaに対してGETメソッドでリクエストを送り、Secrets Managerから機密情報を取得するという流れです。
Secrets Managerでシークレット作成
Secrets Managerでシークレットを作成する手順は以下です。
- AWS コンソールの Systems Managerを開く
- 新しいシークレットを保存するを押下
- シークレットタイプを選択する
- 新しいパラメータを作成し、それぞれの値を登録
(例:OPENAI_API_KEY
のAPIキー値) - シークレットの名前を入力する。
(例:OPENAI_API_KEY
) - その他の値は基本的にはデフォルトで問題ない。
シークレットを保存し、作成されていることを確認する。
今回は例として、キーを「OPENAI_API_KEY」、値を「OPENAIのAPIキー」としてシークレットを作成しました。
AWS CLIからシークレット取得
まずSecretsManagerで作成したシークレットが正常に作成完了しているかどうかを、AWS CLIから確認します。aws secretsmanager get-secret-value
コマンドで確認することができます。
aws secretsmanager get-secret-value --secret-id <SECRET_NAME> --region <REGION>
引数の説明
<SECRET_NAME>
: Secrets Manager に登録した秘密情報の名前。<REGION>
: 秘密情報が保存されている AWS リージョン。
実行例
aws secretsmanager get-secret-value --secret-id my-secret-key --region ap-northeast-1
コマンド実行した結果、以下のように自身で作成したシークレットの情報が取得できれば成功です。
出力例
{
"ARN": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:my-secret-key",
"Name": "my-secret-key",
"VersionId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
"SecretString": "{\"OPENAI_API_KEY\":\"sk-example-key\",
"VersionStages": ["AWSCURRENT"],
"CreatedDate": 1672457600.0
}
このコマンドの出力には、シークレットの詳細情報が含まれており、特にデータベースに接続するために必要なユーザー名やパスワードが含まれます。
Serverless Frameworkの設定
次に、ServerlessFrameworkのserverless.yamlという設定ファイルに、Secrets Managerのシークレットを呼び出す設定を記載します。
動作確認のための簡易的なLambda関数も作成します。
ServerlessFrameworkを初回利用する場合は、ツールのインストールおよび、サービスへの登録が必要です。
具体的な手順については、以下の記事をご覧ください。
まず、自身のローカル環境に、以下のようなフォルダ構成を作成します。
.
├── handler.py
└── serverless.yaml
serverless.yml
Serverless Framework の設定ファイルで Secrets Manager を参照する IAM 権限と環境変数設定を記述します。YOUR-SECRETS-KEYには自身のシークレットのARNから確認した値を記載します。
service: secrets-manager-demo
provider:
name: aws
runtime: python3.9
region: ap-northeast-1
environment:
SECRET_NAME: my-secret-key # Secrets Managerに登録したシークレット名
iam:
role:
statements:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: arn:aws:secretsmanager:${self:provider.region}:${aws:accountId}:secret:YOUR-SECRETS-KEY
functions:
getSecret:
handler: handler.get_secret
events:
- httpApi:
path: /get-secret
method: get
my-secret-key
の部分は、Secrets Managerのコンソール画面内で、作成したシークレットのARNから確認した値を記載します。
handler.py
このコードは、AWS Secrets Manager を使った機密情報管理の基本的なLambda 関数の実装例です。AWS SDK を使用して Secrets Manager から秘密情報を取得します。
import boto3
import os
import json
def get_secret(event, context):
secret_name = os.environ['SECRET_NAME']
region_name = os.environ.get('AWS_REGION', 'ap-northeast-1')
# Secrets Manager クライアントの作成
client = boto3.client('secretsmanager', region_name=region_name)
try:
# Secrets Manager からシークレットを取得
response = client.get_secret_value(SecretId=secret_name)
# シークレットが JSON 形式の場合の処理
if 'SecretString' in response:
secret = json.loads(response['SecretString'])
else:
secret = response['SecretBinary']
return {
"statusCode": 200,
"body": json.dumps({
"message": "Secret retrieved successfully.",
"secret": secret
})
}
except Exception as e:
return {
"statusCode": 500,
"body": json.dumps({
"message": "Error retrieving secret.",
"error": str(e)
})
}
シークレットの取得
ServerlessFrameworkのdeployコマンドを使って、関数をデプロイします。
serverless deploy
もしくは
sls deploy
以下のようにGETメソッドのエンドポイントが出力されるので、そのURLにアクセスします。
SecretsManagerで作成した機密情報が表示されれば成功です。
WebアプリでのSecrets Managerの活用
上記の検証では、実際にSecrets Managerから機密情報を取得することを確認しました。
実際のWebアプリの画面もあった方が、よりSecretsManagerの使い方がわかりやすいと思いました。 実際にReactベースのフロントエンドのアプリ画面のコードも作成して、OpenAIのAPIキーを使った簡易的な検証アプリの動作を確認します。
システム構成図は以下です。
Githubからプロジェクトをクローン
以下のコマンドでGithubからプロジェクトをクローンします。
次に、openai-secrets-demo
ディレクトリに移動します。
git clone https://github.com/my-repo-441/SecretsManager-Demo.git
cd openai-secrets-demo
依存関係のインストール
backend
ディレクトリに移動して、以下のコマンドをライブラリをインストールします。
cd backend
npm install
同様に、frontend
ディレクトリに移動して、ライブラリをインストールします。
cd frontend
npm install
serverless.yaml
の修正
SECRET_NAME
は、自身でSecrets Managerに登録したシークレットの名称およびARNに合わせて修正します。
YOUR-SECRETS-KEYには自身のシークレットのARNから確認した値を記載します。
service: openai-secrets-demo
provider:
name: aws
runtime: python3.12
region: ap-northeast-1
layers:
- {Ref: PythonRequirementsLambdaLayer} # レイヤーを追加
httpApi:
cors:
allowedOrigins:
- http://localhost:3000
allowedMethods:
- POST
allowedHeaders:
- Content-Type
environment:
SECRET_NAME: OPENAI_API_KEY # Secrets Managerに登録したシークレット名
iam:
role:
statements:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: arn:aws:secretsmanager:${self:provider.region}:${aws:accountId}:secret:YOUR-SECRETS-KEY
functions:
invokeOpenAI:
handler: handlers/invoke_openai.lambda_handler
events:
- httpApi:
path: /invoke-openai
method: post
timeout: 29
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true # Dockerを利用して依存関係を正確にパッケージング
layer: true
slim: true # 依存関係をスリム化
package:
exclude:
- node_modules/**
- README.md
- package-lock.json
- .git/**
- package.json
- requirements.txt
- requirements.zip
- unzip_requirements.py
フロントエンドでWebアプリを起動
frontend
ディレクトリに移動して、Webアプリを起動します。
cd frontend
npm start
localhost:3000
Webアプリが起動します。
バックエンドのLambda関数をデプロイ
以下のコマンドでbackend
し、Serverless Frameworkを使ってLambda関数をデプロイします。なお、serverless.yaml
APIでIAMロールやAPI Gatewayの設定も記載しているため、必要な設定も自動的に設定されるようになっています。
cd backend
serverless deploy
Webアプリの動作確認
Webアプリの動作確認を行います。
フロントエンドで起動したWebアプリの入力フォームに、何でも良いので質問を投げてみます。
すると、OpenAIのAPIにより処理された結果が出力されます。
バックエンドでは、Secrets ManagerからOpenAIのAPIキーを呼び出し、OpenAIのAPIによる処理が行われます。
具体的には以下のようなコードでOpenAIの処理を定義しています。
system_message = (
"プロンプトの内容を元に返信してください。"
)
user_content = f"プロンプト: {prompt}"
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": user_content},
]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
max_tokens=150
)
まとめ
本記事では、AWS Secrets Manager を使用して Serverless Framework での機密情報管理を安全かつ効率的に行う方法を解説しました。
AWS Secrets Manager を使用することで、Serverless Framework での機密情報管理が安全かつ効率的に行えるようになります。
- Secrets Manager を導入するメリット
- 設定ファイルに直接機密情報を記載するリスクを回避できる。
- IAM による厳格なアクセス制御で、特定のサービスやユーザーだけがシークレットにアクセス可能。
- シークレットの更新が即時適用され、運用中のアプリケーションを停止する必要がない。
- 実践のポイント
- Secrets Manager に API キーや認証情報を登録し、一元管理を実現。
- Serverless Framework の
serverless.yml
で IAM 権限を適切に設定。 - Lambda 関数から Secrets Manager のシークレットを動的に取得し、安全な運用を行う。
- 安全な運用のために
- IAM ポリシーの最小権限化を徹底して、不要なアクセスを防ぐ。
- シークレット管理の簡素化を意識して、運用の手間を減らす。
- コストを考慮しつつ、必要に応じて Secrets Manager の利用を拡張。
機密情報を設定ファイルに直接記載するリスクを排除し、セキュリティ事故を未然に防ぎましょう。
今回紹介した手法はServerless Frameworkの設定ファイル内にSecrets Managerで作成したシークレットを呼び出すという一例ですが、セキュアなアプリケーションを構築するために、本記事の内容が少しでも参考になれば幸いです。
最後まで読んでいただきありがとうございました。
AWS Secrets Managerってどんな役割を担っているか知ってる?