こんにちは!インフラやクラウドのセキュリティを担当していると、「APIキーやパスワードをどこに保存すればいいですか?」という質問を本当によく受けます。特に開発を始めたばかりの新人エンジニアさんにとって、プログラムと秘密情報の管理は悩ましい壁の一つですよね。
今回は、システム開発の現場で絶対に避けて通れない「APIキーやシークレット情報の管理」について、身近な防犯の例えを交えながら、優しく一歩ずつ紐解いていきましょう!
—
1. 家の鍵を「玄関のマットの下」に置いていませんか?
まずは、私たちがやりがちなセキュリティの失敗を、身近な「家の鍵」に例えて考えてみますね。
旅行に行くとき、家族みんながいつでも入れるようにと、合鍵を「玄関のマットの下」や「植木鉢の裏」に隠したことはありませんか? あるいは、忘れないようにと「家の壁に鍵を貼り付けておく」なんてことは絶対にしませんよね。そんなことをしたら、泥棒に「どうぞ自由に入ってください」と言っているようなものです。
実はこれ、プログラミングの世界でも全く同じことが起きているんです。
コードへの「ハードコーディング」という危険な罠
開発に慣れていないうちは、プログラム(ソースコード)の中に、データベースのパスワードや、外部サービスと連携するためのAPIキーを直接書き込んでしまいがちです。これをセキュリティの専門用語でハードコーディングと呼びます。
# 【やってはいけない危険な例】プログラムの中にパスワードを直接書く
DATABASE_PASSWORD = "super_secret_password_123"
API_KEY = "sk_live_abcdef1234567890"
def connect_db():
# パスワードが丸見えの状態です
print(f"データベースに接続します... パスワード: {DATABASE_PASSWORD}")
このコードをGitHubなどの公開リポジトリ(あるいは会社の共有サーバー)にうっかりアップロードしてしまったらどうなるでしょう? 世界中の泥棒(攻撃者)が、あなたの家の鍵(APIキー)を簡単に手に入れてしまうことになります。実際に、こうして漏洩したAPIキーが悪用され、勝手に高額なクラウドのサーバーを立てられて莫大な請求が届いた……というインシデントは後を絶ちません。
—
2. 秘密情報は「専用の金庫(シークレットマネージャー)」に預けよう
では、私たちはどうやって鍵を守ればいいのでしょうか?
現実の世界では、大切な貴金属や鍵を自宅の適当な場所に放置せず、頑丈な「貸金庫」や「ダイヤル式の金庫」にしまって、本当に必要な時だけ取り出しますよね。
システムの世界でも同じです。APIキーやパスワードといった機密情報は、プログラムの外へ追い出し、「シークレットマネージャー」と呼ばれる専用の安全な金庫に預けるのが現代のスタンダードな対策になります。
代表的なシークレットマネージャーには、以下のようなものがあります。
- AWS Secrets Manager (Amazon Web Servicesが提供する金庫)
- HashiCorp Vault (クラウドやオンプレミスを問わず使える人気の金庫)
これらを使うと、情報は暗号化されて厳重に保管され、「誰が・いつ・その鍵を取り出したか」というアクセスログもしっかり記録されるようになります。
—
3. 実践!AWS Secrets Managerから安全に値を取得してみよう
「金庫の使い方は難しそう…」と思うかもしれませんが、安心してください。基本の仕組みさえ分かればとてもシンプルです。
今回は、AWSの環境を想定して、Pythonプログラムから AWS Secrets Manager にアクセスし、プログラムが実行される「その瞬間」に動的にパスワードを取得するコード例を見てみましょう。
import boto3
from botocore.exceptions import ClientError
def get_secret():
secret_name = "prod/database/password"
region_name = "ap-northeast-1"
# AWS Secrets Managerのクライアントを作成します
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
try:
# 金庫(Secrets Manager)から秘密情報を取り出します
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
except ClientError as e:
# エラーハンドリング:金庫が開かなかった場合の処理
print(f"シークレットの取得に失敗しました: {e}")
raise e
# 取得した秘密情報を取り出します(JSON形式や文字列で保存されています)
secret = get_secret_value_response['SecretString']
return secret
# 実行例
if __name__ == "__main__":
# プログラムの実行時に初めて安全な場所から値を取得します
db_password = get_secret()
print("データベースのパスワードを安全に取得できました!(※画面には表示しません)")
この方法であれば、もしソースコードが誰の目に入ったとしても、そこにはパスワードそのものは一切書かれていません。安全な金庫の「住所(シークレット名)」が書いてあるだけなので、泥棒は中身を開けることができないのです。
—
4. シークレット管理を成功させるための現場の知恵
最後に、私たちが現場で実践している、シークレット管理をより堅牢にするための実践的なコツをいくつかシェアしますね。
① 環境変数との使い分け
本番環境のようなシビアな場所ではシークレットマネージャーが最適ですが、ローカルでの開発環境(自分のパソコン)では、環境変数ファイル(.envファイルなど)を使うことが多いです。
ただし、ここで絶対に忘れてはならないのが、.envファイルを絶対にGitなどのバージョン管理に含めないことです。.gitignoreというファイルに必ず.envと記述して、うっかりアップロードされないように除外設定をしておきましょう。
② 定期的なローテーション(鍵の付け替え)
家の鍵をずっと同じものにしていると、万が一スペアを作られたときに危険です。APIキーやパスワードも同様に、定期的に新しいものへ取り替える(ローテーションする)仕組みを整えておくと、万が一漏洩したときのリスクを最小限に抑えられます。
—
まとめ:一歩ずつ安全な開発環境を作っていきましょう!
今回は、APIキーやシークレット情報の管理について、ハードコーディングの危険性とシークレットマネージャーの活用法を解説しました。
- プログラムの中にパスワードを直接書く(ハードコーディング)のは絶対にNG!
- 機密情報は「シークレットマネージャー」という専用の金庫に預ける。
- プログラム実行時に動的に値を取得する仕組みを取り入れる。
セキュリティ対策は、一度にすべてを完璧にやろうとすると息切れしてしまいます。「まずはコードにパスワードを直書きするのをやめる」「次はシークレットマネージャーの使い方を試してみる」といったように、一歩ずつ確実に学んで適用していけば大丈夫です。
あなたの書くコードが、より安全で信頼されるものになるよう、これからも一緒に学んでいきましょう!
コメント