こんにちは。
AWS IAMにてJWTを利用できるようになったとのニュースがあったので情報を社内向けにまとめていました。
せっかくなのでqiitaにも落とします。
元記事はこちら
このページの概要
このページでは下記の内容で進みます。
元記事が薄いので、後半は発展的に調査した部分です。
- 元記事の要約
- 実装された機能について
- 従来の認証ロジックについて
- JWTの向き/不向き
では、記事の内容について説明していきましょう。
元記事の要約
- AWS IAM がJSON Web Token (JWT)を使用したアウトバウンドIDフェデレーションが可能になった。
- これにより、長期的な認証情報を使用したり、複雑な回避策を実装したりすることなく、AWSワークロードがサードパーティのクラウドプロバイダー、SaaSプロバイダーなどの外部サービスで安全に認証できるようになった。
実装された機能
AWS IAMのIDフェデレーション機能が拡張され、AWSワークロードが外部サービスに対して認証を行うための短命なJWTを生成できるようになった。
-
利点:
- セキュリティの向上: 外部サービスへのアクセスに長期的な認証情報が不要になります。
- 簡素化: 複雑な実装を必要とせず、AWSワークロードが外部サービスにアクセスするシンプルで安全なメカニズムが利用可能
-
トークンの特徴:
- 短命で暗号署名済みのJWTです。
- AWSワークロードに関する豊富なコンテキストが含まれており、外部サービスできめ細かなアクセス制御を実装できます。
-
管理:
- 管理者はIAMポリシーを使用して、トークン生成へのアクセス制御や、トークンのプロパティ(有効期間、オーディエンス、署名アルゴリズムなど)を適用できます。
- CloudTrailログを使用してトークンの使用状況を監査し、セキュリティおよびコンプライアンス要件を満たすことができます。
ここまでが元記事の内容。
次に、今まではどのように認証を実装していたのか調べてみましょう。
従来の認証ロジック
今回のアップデートの主な利点はこちら。
- 短命で暗号署名されるJWTを利用できる
- JWTは標準的規格なので開発が容易(外部サービスごとに認証機能の開発が不要)
従来の悩み
従来の外部サービスとの認証ロジックは以下の通り。
- アクセス先の外部サービスから発行された長期的な認証情報を環境変数やSecretManager等に保存する方法。
- 悩み:認証情報漏洩時のセキュリティリスク大!
- IAMロールによりアクセス元AWSワークロードが一時的認証情報を取得し、この認証情報を使って外部サービスの認証情報を利用する方法。
- 悩み:ちょっと複雑だし外部サービスごとに認証のロジックを開発する必要あり。
- 外部サービス側でのIPリストホワイトリスト。
- 悩み:AWS側でIPアドレスを変えない工夫や、IPアドレスが変わっても外部サービス側で対応する工夫など運用リスクあり。また、外部サービスからはどのアプリケーションからのアクセスなのか判別できない。
こうみると従来の悩みをJWTなら解決できそうですね。
多くの既存サービスでも採用できる素晴らしいアップデートなのでは?
JWTを使ううえでの注意
ではJWTは万能なの?
調べてみるとどうやらそうではないみたい。
JWTを使ううえで注意すべき点
1. トークンの失効(Revocation)が難しい ⏳
- 課題: もし有効期限内にユーザー(またはワークロード)の権限を緊急で取り消したい(例:不正アクセスが疑われる、ロールが削除された)場合、トークンを即座に失効させることが困難。
- 対策: 有効期限を極めて短く設定するか、または失効リスト(ブラックリスト)を実装する必要あり。ただこれはJWTのステートレスという大きな利点を損ない、サーバーの負荷を増大させる可能性があり。
2. トークンサイズの増加 📏
-
課題:
- ネットワーク負荷: リクエストごとにトークン全体が送信されるため、トークンが大きすぎるとネットワークの帯域幅を消費し、特に大量のAPIコールを行うワークロードではレイテンシ(遅延)の原因になる。
- HTTPヘッダー制限: 大きすぎるJWTは、Webサーバーやロードバランサーが設定しているHTTPヘッダーの最大サイズ制限を超過する可能性あり。
3. トークンが盗まれた場合のリスク 🛡️
- 課題: JWTが盗まれた場合、有効期限が切れるまで、攻撃者はそのトークンを使って正規のワークロードになりすますことが可能。
-
対策:
- 短命化: 前述のとおり、有効期限を短く設定することが最も効果的な防御策。
- トークンの安全な輸送: 必ずHTTPS/TLSを使用して通信を暗号化する必要があります。
4. 暗号化と署名の混同 🤯
JWTは署名(データが改ざんされていないことの保証)を主に目的としており、認証情報の暗号化は行わない。
- 課題: JWTのペイロード(クレーム)はBase64 URLでエンコードされているだけで、誰でも簡単にデコードして内容を読むことができる。機密性の高い情報(例:個人情報など)をJWTに含めてしまうと、第三者に漏洩するリスクがあり。
- 対策: JWTには、ワークロードのIDなど機密性の高くない情報のみを含める。機密性の高い情報は、別途セキュアなストレージから取得するようなロジックを組む。
きちんと性質を理解したうえで対策を実装しなければいけないみたいですね。
JWTを採用するケース
最後に、 JWTを採用できる条件とは一体何なのか調べてみました。
JWTを採用するかの判断基準
| スケーラビリティが最優先か | サーバーがセッション情報を保持しない(= ステートレス)ため、サーバーの負荷が軽減し、スケールアウト時の考慮が不要。 |
| セッション管理が不要か | ユーザーが頻繁にログアウトしないシステムや、セッションの即時失効が不要なシステムに向いている。 |
| 分散環境であるか | マイクロサービスやSSOなど、複数のサービスが同じ認証情報を共有する必要がある場合に有効。 |
| 情報の改ざんを防ぎたいか | JWTは署名によって改ざんを検知できるため、認証情報が本物であることを保証可能。 |
上記の注意すべき点はこれらの要素があればカバーできるのでないでしょうか。
まさにAWSワークロードが外部サービスに対して認証を求めるケースにぴったり!
だから今回のアップデートがあったわけなんですね。
シングルサインオン (SSO) システムではJWTが核の技術であり、マイクロサービスアーキテクチャでもJWTが主流なようです。
まとめ
AWS IAMでJWTを利用した外部サービス認証ロジックを使用できるようになりました。
普遍的な技術であるJWTを利用することで、長期認証情報を扱わなくてOKであり、認証ロジックの開発が楽になりそうです。
当然JWTにも向き不向きはあるのでご利用は計画的に。