こんにちは!インフラやクラウドのセキュリティを担当しているエンジニアの皆さん、そして日々アプリの開発に奔走されている一般開発者の皆さん。
サーバーやクラウドのセキュリティと聞くと、「なんだか難しそうだな」「設定を間違えて会社の一大事になったらどうしよう…」と、少し身構えてしまいますよね。でも、安心してください。セキュリティの基本は、私たちが普段暮らしている現実世界の「防犯」とまったく同じなんです。
今回は、Kubernetesなどのコンテナ環境でクラウドサービスへ安全にアクセスするための仕組み、「Workload Identity(ワークロード・アイデンティティ)」について、身近な例えを交えながら優しく紐解いていきたいと思います。一歩ずつ、一緒に学んでいきましょう!
—
1. 昔ながらの「合鍵を置くやり方」は、なぜ危ないのか?
まずは、私たちがやりがちな「ちょっと危ないお部屋の管理方法」からお話させてください。
例えば、あなたがシェアハウスの管理人をしているとします。シェアハウスの住人(今回のテーマでいうと、Kubernetesの Pod(コンテナアプリ)です)が、お掃除ロボットや倉庫(クラウドサービス)を使いたいとしますよね。
昔は、倉庫の「合鍵(AWSのアクセスキーやパスワードなどの静的クレデンシャル)」を、わざわざ住人の部屋の机の上にポツンと置いておいてあげました。
「倉庫を開けるときは、この鍵を使ってね」と。
これ、一見すると便利そうですが、セキュリティの観点からは「最悪の悪手」なんです。なぜだかわかりますか?
もし、その住人の部屋に泥棒(攻撃者)が侵入してきたらどうなるでしょう?
泥棒は机の上にある倉庫の「合鍵」を簡単に見つけてしまいます。そして、その鍵を使って、あなたの会社の重要なデータが入っている倉庫から、ありったけの宝物を持ち去ってしまうのです。
さらに怖いのは、この合鍵、「いつまでも有効なマスターキー」である点です。泥棒が鍵を持ち去ったことに気づかなければ、何ヶ月も、何年も、あなたのクラウド環境は食い物にされ続けます。
サーバーOSの要塞化やクラウドセキュリティの現場でも、アプリの設定ファイルや環境変数にパスワードを直接書き込んでおく手法は、まさにこの「机の上に合鍵を置きっぱなしにする状態」そのものなんです。
—
2. Workload Identityってなに? —— 「使い捨ての電子キー」の仕組み
この「合鍵の置きっぱなし問題」をスパッと解決してくれるのが、Workload Identityという仕組みです。
現実の世界で考えてみてください。最近のスマートなビルやホテルでは、物理的な合鍵ではなく、スマホの画面に「今から30分間だけ、特定の部屋と倉庫を開けられる電子チケット(一時的なトークン)」を表示させますよね。
Workload Identityもこれとまったく同じです。
1. アプリ(Pod)が起動する。
2. クラウド側(OIDCプロバイダー)に対して、「私はこういう者です。倉庫を開けるための一時的なパスポートをください」と証明する。
3. 身元が確認できたら、クラウド側は「たった1時間だけ有効な、制限付きのパスポート」を発行する。
4. アプリはそのパスポートを使ってクラウドサービスにアクセスし、用事が済んだらパスポートは自動的に消滅する。
これなら、万が一アプリの脆弱性を突かれて侵入されたとしても、攻撃者が手に入るのは「すでに有効期限が切れた、あるいは権限がガチガチに制限された使い捨てのパスポート」だけです。被害を最小限に食い止めることができますよね。
—
3. 実践!KubernetesにおけるWorkload Identityの設定
それでは、実際にKubernetes(GKEやEKSなど)でこの仕組みをどうやって設定するのか、現場でそのまま使える設定ファイルの例を見ていきましょう。
今回は、AWSのEKS(Amazon EKS)を例にとって、サービスアカウントに一時的なIAMロールを紐付ける設定の流れをご紹介します。
ステップ1: Kubernetes側のサービスアカウントを作成する
まずは、Kubernetes側でアプリが使用する「身分証明書(ServiceAccount)」を用意します。ここがすべての起点になります。
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-secure-app-sa # アプリケーションが使用するサービスアカウント名
namespace: default
annotations:
# ここがキモ!AWSのIAMロールのARNと紐付けることで、外部のクラウド権限と結びつけます
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/MyCloudServiceAccessRole
ステップ2: デプロイメント(Pod)にサービスアカウントを割り当てる
次に、実際に動かすアプリケーションのPod設定に、先ほど作成したサービスアカウントを組み込みます。
ここで重要なのは、コードや環境変数の中に、AWSのシークレットキーを1行も書かなくてよいという点です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-secure-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: my-secure-app
template:
metadata:
labels:
app: my-secure-app
spec:
# ステップ1で作ったサービスアカウントを指定する
serviceAccountName: my-secure-app-sa
containers:
- name: web-app
image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:v1.0.0
ports:
- containerPort: 8080
# 注意:ここにはAWS_ACCESS_KEY_IDやAWS_SECRET_ACCESS_KEYを書きません!
# クラウドのSDKが自動的にPod内の仕組みを検知し、一時的な認証情報を安全に取得します。
これだけで、アプリはコードを変更することなく、裏側でセキュアにクラウドのAPI(S3やDynamoDBなど)を叩くことができるようになります。
—
4. 現場のシニアエンジニアからのアドバイス
実務でこうしたクラウド環境やサーバーOSの要塞化を進めるとき、新人エンジニアの方や開発者の方からよくこんな質問を受けます。
> 「今までのやり方(環境変数にキーを入れる方法)のほうが、テスト環境ですぐ動かせて楽なんですけど……」
その気持ち、痛いほどよく分かります。私も昔は、テストを早く通すために同じような近道をしたことがあります。しかし、一度その「楽な道」で情報漏洩が起きると、会社の信頼は一瞬で吹き飛び、原因調査や鍵の無効化、インシデント対応で何十倍もの苦労を背負うことになります。
セキュリティとは、「開発の手間を少しだけ増やして、将来の絶望をゼロにする保険」です。
最初の一歩は難しく感じるかもしれませんが、Workload Identityのような「静的クレデンシャルを排除する仕組み」をデフォルトで使えるようになると、あなたの作るシステムは圧倒的に「破られにくい要塞」に生まれ変わります。
ぜひ、皆さんのプロジェクトでも「合鍵の置きっぱなし」がないかどうか、一度コードやマニフェストを見直してみてくださいね。一歩ずつ、安全なインフラストラクチャを作っていきましょう!
コメント