はじめに
本記事では、AWSサービスで最も重要といっても過言ではないIAMについて、改めて振り返ってみようと思います。
IAMとは
IAM(Identity and Access Management)は、AWSリソースへのアクセスを安全に管理するために認証
と認可
の機能を提供します。
提供される機能は多くありますが、その中でコアになるのは以下の機能になります。
- IAMユーザ
- IAMポリシー
- IAMグループ
- IAMロール
本章では、IAMユーザとIAMポリシーを学び、次章でIAMグループとIAMロールについて学んでいきます。
なお、それぞれの関連性は以下のようになります。
※今見てもイメージが付かないと思いますが、本章と次章が終わった後に再度見てもらうと理解が深まるはずです😀
認証と認可の違い
まず、IAMを学ぶ上で必要な前提知識となる認証と認可について説明します。
認証
認証とは、誰であるか
を確認・特定することです。
例えば、Amazonで買い物する場合、以下のような流れになるかと思います。
- AさんがAmazonの会員登録画面にアクセス
- 必要事項を入力し、会員登録を完了させる。
- 会員登録時に入力したID・パスワードでログイン
- 自由に買い物
この3.のログインで、
- Amazon会員であること
- Aさんであること
を確認しますがこれが認証になります。
一番身近な認証としてログインがありますが、現実世界だと免許証やパスポートによる本人確認なども認証に当たります。
認証の種類
認証は大きく以下の3つに分類されます。
分離 | 認証方法例 |
---|---|
知識情報 | ・ID/パスワード認証 ・秘密の質問 |
所持情報 | ・SMS認証 ・ICカード ・ワンタイムパスワード |
生体情報 | ・指紋認証 ・顔認証 ・虹彩認証 ・静脈認証 |
AWSコンソールには、以下の認証情報(知識情報)でログインします
- アカウントID(12桁)
- ユーザ名
- パスワード
MFA(多要素認証)
Multi-Factor Authenticationの略で、知識情報と所得情報など2つ以上の要素を使った認証になります。
※2つの要素で認証することが多いため、2要素認証
とも言います。
1つの要素だけでも認証としては成り立ちます。
しかし、知識情報のみでの認証だとブルートフォース攻撃に対して脆弱だったりするため、多くのサービスで多要素認証によるセキュリティ強化が一般的になっています。
2要素認証に似た名前として2段階認証があり、2つの情報で認証するという点では同じです。
しかし、2段階認証では要素数は問わないため別物になります。
AWSでは、仮想MFAデバイス(GoogleAuthenticatorなど)などで2要素認証が可能です。
MFA設定は任意ですが、AWSでも推奨されていますので必ず設定するようにしましょう。
認可
認可とは、認証された人やモノに対して、何かしらの権限
を与えることです。
例えば、無料/有料で利用するアプリの場合、以下のような流れになるかと思います。
- 無料会員登録
- ログイン←認証
- 無料会員なのでマイページの閲覧など特定の操作のみ行える
- 有料会員になる
- 有料会員になったので商品の購入など全ての操作が行える
この
- 3.で無料会員が行える操作の権限
- 5.で有料会員が行える操作の権限
が与えられますがこれが認可になります。
先ほど認証例としてパスポートを上げましたが、パスポートだけでは目的地に行くことは出来ません。
航空券を購入することで目的地に行くための権利が与えられますが、これが認可に当たります。
AWSでは、後述のIAMポリシーによって認可を行っています。
IAMユーザ
AWSコンソールにログインし、サービスを利用するためにはまずAWSアカウントを作成する必要があります。
アカウントの作成
以下の情報を登録することでAWSアカウントの作成が完了し、rootユーザが作成されます。
登録する情報 | 入力値 |
---|---|
アカウント情報 | ・メールアドレス ・パスワード ・アカウント名 |
連絡先情報 | ・名前 ・電話番号 ・国/地域 ・住所 など |
請求情報 | ・クレジットカード情報 ・請求先住所 |
本人確認 | ・認証コード ・セキュリティチェック文字列 |
サポートプラン | 以下のいずれか ・ベーシック(無料) ・デベロッパー ・ビジネス ・エンタープライズ |
rootユーザとは
IAMユーザには、rootユーザ
とIAMユーザ
の2種類があり、全てのAWSリソース操作が可能なユーザをrootユーザと呼びます。
rootユーザは、全AWSリソースの操作に加えて以下の操作も行える特別なユーザです。
・支払情報の変更
・サポートプランの変更
・アカウントの解約 など
漏洩や作業ミスのリスクが非常に高いため、上記のrootユーザでしか出来ない作業以外では絶対に利用しないようにしましょう。
IAMユーザの作成
AWSサービスを利用したい場合は、IAMユーザを作成する必要があります。
以下の情報を登録することでIAMユーザが作成されます。
※IAMユーザを作成しただけではAWSリソースを操作する権限を持っていません。後述のIAMポリシーをアタッチして利用します。
登録する情報 | 入力値 | 備考 |
---|---|---|
ユーザ名 | 任意のユーザ名 | |
AWS認証情報タイプ | 以下のいずれかまたは両方 ・アクセスキー ・パスワード |
・アクセスキー:CLIやAWS SDKを使う場合 ・パスワード:AWSコンソールを利用する場合 ※ユーザ作成後に変更可能 |
コンソールのパスワード | ・自動生成パスワード ・任意のパスワード |
AWS認証情報タイプでパスワードを選択した場合のみ |
AWS認証情報タイプとしてパスワードを選択した場合、パスワードが払い出されてAWSコンソールへログイン出来るようになります。
IAMユーザは必ず利用者毎に作成しましょう。
複数の利用者が同じIAMユーザを利用することももちろん可能です。
しかし、それだと何か誤った操作をした場合に誰が操作をしたのかを追跡することが出来なくなります。
IAMポリシー
IAMポリシーとは
AWSリソースを操作する認可を与える機能になります。
JSON形式で以下を定義します。
要素 | 説明 | 備考 |
---|---|---|
Principal | 誰が | IAMユーザやIAMロールを指定します |
Resource | どのAWSサービスの、どのリソースに対して | ・全て(*) ・特定のAWSサービスの全て ・特定のAWSサービスの特定のリソース のいずれかを指定します |
Action | どの操作をすることを | ・全て(*) ・特定の種類の操作全て(Get系全てなど) ・特定の操作 のいずれかを指定します |
Effect | 許可/拒否する | 操作を許可するか拒否するか指定 |
Version | ポリシーバージョン | 最新バージョンの2012-10-17 で固定 |
Sid | 識別子 | JSON内で一意な任意の値 |
Condition | 条件を指定 | IPアドレス、日付、Principal、ARN^[Amazon Resource Nameの略でAWSサービスのリソースを一意に識別するための値]などを条件に設定 |
例えば、
・IAMユーザの山田さんが、S3の、testバケットに対して、オブジェクトを取得することを、許可
・IAMユーザ全てが、S3の、全てのバケットに対して、オブジェクトを保存することを、拒否
するIAMポリシーはそれぞれ以下になります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement001",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test/*",
"Condition": {
"StringEquals": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:user/yamada"
}
}
},
{
"Sid": "Statement002",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:user/*"
}
}
}
]
}
AllowとDenyの優先度
AllowとDenyでActionが重複した場合、Denyが優先されます。
具体的には以下のようになります。
No | Allow | Deny | 操作結果 | 備考 |
---|---|---|---|---|
1 | 未記載 | 未記載 | 全ての操作を拒否 | ポリシー未定義の状態 |
2 | s3:* | 未記載 | ・S3の操作を全て許可 ・S3以外の操作は全て拒否 |
Allowで定義していない操作は暗黙的に拒否されます |
3 | s3:* | s3:* | 全ての操作を拒否 | No1と同じ結果 |
4 | s3:* | * | 全ての操作を拒否 | No1と同じ結果 |
5 | * | s3:* | ・S3以外の操作は全て許可 ・S3の操作を全て拒否 |
フローにすると、以下のようになります。
※公式サイトのフローをもとに作成しました。
※「2.Organizations SCP」、「5.IAMアクセス許可の境界」と「6.セッションポリシー」の一部内容に関しては、本教育資料の対象外とします。詳しく知りたい場合は、こちらをご参照ください。
最小権限の原則
IAMポリシーでは、ActionとResourceで*(全て)を指定できることがわかりました。
いちいちResourceにS3、ActionにGetObjectなど具体的に指定せず、広く許可すればいいのではないか、と思う人もいるかと思います。
しかし、これは非常に危険で以下のようなリスクがあります。
- プログラムにバグがあり、本来アクセスする必要がないAWSリソースへアクセスしてしまい、データが書き替えられた
- 総務部の人がシステム開発部が作成したシステムの情報を誤って書き換えてしまった
- 悪意のある人にIAMユーザが乗っ取られ、高額請求が発生するAWSリソースを作られてしまった
こういったリスクを出来るだけ減らすために、AWSでは最小権限の原則
を提唱しています。
これは、必要な操作
を必要なリソース
に必要な時
に付与しましょう、という考えで、
この考えに沿ってポリシーを定義することによって、セキュリティリスクを最小化出来ます。
ポリシーの種類
ポリシーには、2つの種類があります。
- アイデンティティベースポリシー
- リソースベースポリシー
アイデンティティベースポリシー
IAMユーザ・IAMグループ・IAMロールのいずれかに関連付ける(アタッチする)ポリシーで、以下の3種類が存在します。
名称 | 概要 | メリット/デメリット |
---|---|---|
AWS管理ポリシー | ・AWS が管理するポリシー・AWSサービス毎のフル権限や、利用用途が多い権限が付与されている ・ポリシーの追加・修正・削除: 不可 ・ 複数 のリソースにアタッチできる・ポリシーのバージョン管理: 可 (AWSが実施)例:AmazonS3ReadOnlyAccess(S3の読み取り系の権限を付与したポリシー) 例:AdministratorAccess(rootユーザのみ可能な操作以外の全ての操作権限を付与したポリシー) |
メリット ・AWSサービスのアップデート時にポリシーの修正もAWSが行ってくれるため、ユーザの手間が減る ・必要な権限を持ったポリシーが準備されているため、開発にすぐ入れる デメリット ・AWSが管理するため、不要なアクションやリソースに対しても操作が許可される |
カスタマー管理ポリシー | ・ユーザ が管理するポリシー・任意に定義した権限を付与出来る ・ポリシーの追加・修正・削除: 可 ・ 複数 のリソースにアタッチできる・ポリシーのバージョン管理: 可
|
メリット ・任意の権限を付与できるため、最小権限の原則に沿うことが出来る ・複数のIAMに共通で使えるポリシーを作成できるので、同じようなポリシーを作成する必要がない デメリット ・複数のリソースにアタッチできるので、ポリシー定義を修正した際の影響把握が必要 |
インラインポリシー | ・ユーザ が管理する埋め込み型のポリシー・任意に定義した権限を付与した出来る ・ポリシーの追加・修正・削除: 可 ・ 単一 のリソースにアタッチできる・ポリシーのバージョン管理: 不可
|
メリット ・任意の権限を付与できるため、最小権限の原則に沿うことが出来る ・ポリシーの修正の影響が単一のリソースに限定される デメリット ・複数のIAMユーザに必要な共通的な権限を持ったポリシーを作成することは出来ない ・埋め込み型のため、IAMのAWSコンソールで確認できない |
リソースベースポリシー
S3やLambdaなどAWSリソースにアタッチするポリシーです。
IAMではなく各AWSリソースで管理するインラインポリシー
なので、IAMコンソール画面には表示されず、AWSリソース毎に作成する必要もあります。
アイデンティティベースポリシーは、操作する側
にポリシーをアタッチしていましたが、リソースベースポリシーは操作される側
にアタッチします。
ポリシー定義としては、操作する側(Principal)からのActionを許可します。
よく使われるのが、IAMロールの信頼ポリシーやS3のバケットポリシーなどです。
信頼ポリシーやバケットポリシーなど呼称が違いますが、同じリソースベースポリシーです。
例えば、S3(操作する側)がLambda(操作される側)を実行するために必要なリソースベースポリシーは以下のようになります。
{
"Version": "2012-10-17",
"Id": "s3-invoke-function-id",
"Statement": [
{
"Sid": "s3-invoke-function",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ap-south-1:012345678901:function:test-function",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "012345678901"
},
"ArnLike": {
"AWS:SourceArn": "arn:aws:s3:::lambda-invoke-bucket"
}
}
}
]
}
このリソースベースポリシーでは、
- S3の
- バケット:lambda-invoke-bucket(操作する側)が
- Lambda関数をInvokeFunction(実行)することを
- 許可する権限を
- Lambda関数:test-function(操作される側)に
付与しています。
ハンズオン
それでは説明はここまでにして、実際に手を動かしてIAMユーザとIAMポリシーの関係について理解を深めていきましょう。
前提
- ハンズオンに使用するAWSアカウントのIAMユーザが作成されていること
- ログインユーザにIAMポリシーを操作する権限が付与されていること
- S3バケット(study-meeting-${AWSアカウントID})が作成されていること
実施内容
1. インラインポリシーを作成し、IAMユーザにアタッチしてみよう
期待する動作
IAMユーザにインラインポリシーがアタッチされること
実施内容
・[IAM]コンソール画面に遷移
・[ユーザ]をクリック
・ユーザ一覧から、自身のユーザ名をクリック
・[許可を追加]で、[インラインポリシーを追加]をクリック
・[JSON]でポリシーを入力し、[ポリシーの確認]をクリック
・[名前]を入力し、[ポリシーの作成]をクリック
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "*"
}
]
}
2. 1.で許可された操作が実行出来ることを確認するために、S3にアクセスし、オブジェクトを表示してみよう
期待する動作
オブジェクト一覧が表示されること
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、対象のS3バケットをクリック
※study-meeting-${AWSアカウントID}
3. 許可されていない操作が実行出来ないことを確認するために、S3にアクセスし、オブジェクトをアップロードしてみよう
期待する動作
エラーメッセージが表示され、オブジェクトがアップロード出来ないこと
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、対象のS3バケットをクリック
・[アップロード]をクリック
・[ファイルを追加]をクリックし、任意のオブジェクトを選択して[アップロード]をクリック
4.書き込み権限のIAMポリシーをアタッチし、オブジェクトをアップロードしてみよう
期待する動作
オブジェクトアップロードが正常に終了し、オブジェクト一覧に表示されること
実施内容
・[IAM]コンソール画面に遷移
・[ユーザ]をクリック
・ユーザ一覧から、自身のユーザ名をクリック
・[許可を追加]をクリック
・[ポリシーを直接アタッチする]をクリックし、[AmazonS3FullAccess]を選択し、[次へ]をクリック
・[許可を追加]をクリック
・3.と同じS3操作を行う
5. 拒否された操作が実行出来ないことを確認するために、S3にアクセスし、オブジェクトを削除してみよう
期待する動作
エラーメッセージが表示され、オブジェクトが削除出来ないこと
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、対象のS3バケットをクリック
・オブジェクト一覧から、4.でアップロードしたオブジェクトにチェックを付け、[削除]をクリック
・[完全に削除]と入力し、[オブジェクトの削除]をクリック
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"s3:Delete*"
],
"Resource": "*"
}
]
}
6.書き込み権限のIAMポリシーをデタッチし、オブジェクトを削除してみよう
期待する動作
オブジェクト削除が正常に終了し、オブジェクト一覧に表示されないこと
実施内容
・[IAM]コンソール画面に遷移
・[ユーザ]をクリック
・ユーザ一覧から、自身のユーザ名をクリック
・[study-meeting-delete-policy]にチェックを付け、[削除]をクリック
・[ポリシーを削除]をクリック
・5.と同じS3操作を行う
IAMグループ
IAMグループとは
その名の通り、IAMユーザを束ねるためのグループです。
IAMグループは以下のように作成します。
- IAMグループの作成
- IAMグループにIAMポリシーをアタッチ
- IAMグループにユーザを追加
IAMユーザは、IAMグループのIAMポリシーで許可された操作が可能になります。
複数のグループにIAMユーザを追加した場合、各IAMグループそれぞれの権限が付与されます
部署毎、支社毎、役割毎(SE, PG, TEなど)にIAMグループを作成し、IAMユーザを追加することで以下のようなメリットがあります。
- ユーザAは経理部、ユーザBは総務部など各IAMユーザの所属を現実世界と近しくすることが出来る
- IAMユーザ個別に権限を付与する必要がなくなるため、権限の修正漏れが起きにくく、管理コストも下がる
ハンズオン
それではIAMグループの説明はここまでにして、実際に手を動かしてIAMグループについて理解を深めていきましょう。
IAMユーザーが、2つの異なる権限のIAMグループに所属した際の挙動を確認するために、以下の許可/拒否を確認します。
ハンズオンNo | 操作 | システム開発部の権限 | 総務部の権限 | 操作結果 |
---|---|---|---|---|
4 | オブジェクトの一覧表示 | Allow | Allow | 許可 |
5 | S3バケットの削除 | Deny | Deny | 拒否 |
6 | オブジェクトのアップロード | Allow | 未定義 | 許可 |
7 | オブジェクトの削除 | Allow | Deny | 拒否 |
前提
- ログインユーザにIAMグループ、IAMポリシーを操作する権限が付与されていること
- S3バケット(study-meeting-${AWSアカウントID})が作成されていること
実施内容
1. システム開発部と総務部のIAMグループを作成してみよう
期待する動作
ユーザグループ一覧に作成したIAMグループが表示されること
実施内容
・[IAM]コンソール画面に遷移
・[ユーザグループ]をクリック
・[グループを作成]をクリック
・[ユーザグループ名]を入力し、追加したいIAMユーザにチェックを付け、[グループを作成]をクリック
・system-development
・general-affairs
2. 1.で作成した[システム開発部]にインラインポリシーをアタッチしてみよう
期待する動作
[システム開発部]にインラインポリシーがアタッチされること
実施内容
・[IAM]コンソール画面に遷移
・[ユーザグループ]をクリック
・ユーザグループ一覧から、1.で作成した[system-development]をクリック
・[許可]をクリックし、[許可を追加]で、[インラインポリシーを作成]をクリック
・[JSON]でポリシーを入力し、[ポリシーの確認]をクリック
・[名前]を入力し、[ポリシーの作成]をクリック
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"s3:CreateBucket"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:Put*",
"s3:Delete*"
],
"Resource": "*"
}
]
}
3. 1.で作成した[総務部]にインラインポリシーをアタッチしてみよう
期待する動作
[総務部]にインラインポリシーがアタッチされること
実施内容
```text・[IAM]コンソール画面に遷移
・[ユーザグループ]をクリック
・ユーザグループ一覧から、1.で作成した[general-affairs]をクリック
・[許可]をクリックし、[許可を追加]で、[インラインポリシーを作成]をクリック
・[JSON]でポリシーを入力し、[ポリシーの確認]をクリック
・[名前]を入力し、[ポリシーの作成]をクリック
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"s3:CreateBucket"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"s3:Delete*"
],
"Resource": "*"
}
]
}
4. 両方のIAMグループで許可された操作が実行出来ることを確認するために、S3にアクセスし、オブジェクトを表示してみよう
期待する動作
オブジェクト一覧が表示されること
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、対象のS3バケットをクリック
※study-meeting-${AWSアカウントID}
5. 両方のIAMグループで許可されていない操作が実行出来ないことを確認するために、S3にアクセスし、S3バケットを作成してみよう
期待する動作
エラーメッセージが表示され、バケットが作成出来ないこと
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・[バケットを作成]をクリック
・[バケット名]を入力し、[バケットを作成]をクリック
6. システム開発部のIAMグループで許可された操作が実行出来ることを確認するために、S3にアクセスし、オブジェクトをアップロードしてみよう
期待する動作
オブジェクトアップロードが正常に終了し、オブジェクト一覧に表示されること
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、5.で作成したS3バケットをクリック
・[アップロード]をクリック
・[ファイルを追加]をクリックし、任意のオブジェクトを選択して[アップロード]をクリック
7. システム開発部で許可、総務部で拒否されている操作が実行出来ないことを確認するために、S3にアクセスし、オブジェクトを削除してみよう
期待する動作
エラーメッセージが表示され、オブジェクトが削除出来ないこと
実施内容
・[S3]コンソール画面に遷移
・[バケット]をクリック
・バケット一覧から、対象のS3バケットをクリック
・オブジェクト一覧から、4.でアップロードしたオブジェクトにチェックを付け、[削除]をクリック
・[完全に削除]と入力し、[オブジェクトの削除]をクリック
IAMロール
IAMロールとは
ロールという名前から分かる通り、役割を意味します。
1つ以上のIAMポリシーをアタッチしたIAMロールを作成します。
※IAMポリシーは、アイデンティティベースポリシーを利用します。
例えば、以下のような役割を与えるロールを作成したりします。
- 書籍管理アプリケーション用ロール:Laravelで作成した書籍管理アプリケーションがS3とDynamoDBへアクセスする役割
- 経理部用ロール:経理部のIAMユーザが請求情報にアクセスする役割
IAMロールは権限を持っているだけなので単体では動作しません。
IAMユーザやAWSサービスがIAMロールを一時的に引き受ける
ことで、定義されたIAMポリシーの権限の操作が可能になります。
このIAMロールを一時的に引き受けることをAssumeRole
と呼びます。
AssumeRoleした際に一定期間有効な認証情報がSTS(Security Token Serviceの略)というAWSサービスから返却されます。
有効期間内であれば、この認証情報を利用することでAWSリソースの操作が可能になります。
なお、誰でもIAMロールを自由にAssumeRole出来るわけではなく、IAMロールとPrincipal(操作する側)との間で信頼関係
を結ぶ必要があります。
そのために、信頼ポリシーを定義しIAMロールにアタッチします。
信頼関係を結ぶことによって、同一アカウントだけではなく、別アカウントのIAMロールを引き受けることも可能です。
信頼ポリシー
信頼関係とも呼ばれ、IAMロールの権限移譲に特化したリソースベースポリシーです。
ポリシー定義のActionには、sts:AssumeRole
を設定します。
例えば、以下のような信頼ポリシーをアタッチしたIAMロールは、
- IAMロールにアタッチしている
- アイデンティティベースポリシーの権限を
※ 今回だとtest-bucketからのオブジェクト読み取り権限 - 一時的に引き受けることを
- 許可する権限を
- Lambda関数に付与
という動作になります。
// アイデンティティベースポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::test-bucket/*"
],
"Effect": "Allow"
}
]
}
// 信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
スイッチロール
ここまでは1つのAWSアカウント内での話をしてきましたが、実際は以下のように複数のアカウントを利用することがほとんどです。
- アカウント1:案件Aの開発環境
- アカウント2:案件Aの検証環境
- アカウント3:案件Aの本番環境
- アカウント4:案件Bの開発、検証環境
- アカウント5:案件Bの本番環境
- アカウント6:総務部が人事データを管理するための環境
- アカウント7:経理部が経費データを管理するための環境
- アカウント8:営業部が顧客情報を管理するための環境 など
これらの環境を全て利用したいとなった場合、アカウント毎にIAMユーザを作成するのが良いのでしょうか?
答えはNoです。
アカウント毎にIAMユーザを作成すると以下のようなデメリットがあります。
- 各アカウントの認証情報を利用者が管理しなくていけないため、管理コストとセキュリティリスクが上がる
- IAMユーザを作成する管理担当者の運用コストが上がる
- 別アカウントに移動したい場合は都度、ログアウト・ログインをしなければならない
こういった懸念を解消するために存在するのがスイッチロール
です。
スイッチ元アカウントにスイッチ先アカウントの権限を一時的に移譲することによって、別アカウントのAWSリソースの操作が可能になります。
スイッチロールによって、わざわざログアウトしたり、アカウントの認証情報を管理する必要がなくなり、アカウント間の移動がスムーズになります。
おまけ
文字だけだと信頼ポリシーやスイッチロールのイメージが付きにくいので、図を使って説明していきます。
スイッチロールは、下図のように踏み台アカウント^[各AWSアカウントでのIAMユーザ作成だと、同じ人だとしても複数のIAMユーザを作成する必要があり、AWS管理コストやID/パスワードの保管リスクなどが増大するため、踏み台アカウントに集約する]を1つ用意しIAMユーザを作成して、各アカウントへスイッチロールするのが一般的です。
流れとしては以下のようになります。
- 事前準備
1-1. IAMユーザを作成
1-2. スイッチ先アカウントにIAMユーザが引き受けるIAMロールを作成し、アイデンティティベースポリシーと信頼ポリシーをアタッチ
1-3. IAMユーザがIAMロールをAssumeRoleするためのアイデンティティベースポリシーをアタッチ - AWSコンソールにログイン
- スイッチ元アカウントから対象のIAMロールにスイッチロール
※スイッチロールに必要な情報は、スイッチ先のアカウントID
とIAMロール名
- STSが一定期間有効な認証情報を返却
- スイッチ先アカウントで、許可されたAWS操作を実施
※4で取得した認証情報を利用して、スイッチ先のアカウントのAWSリソースを操作
※認証情報は透過的に利用されるので、ユーザが意識する必要は無い
「踏み台アカウント→開発アカウント→本番アカウント」とスイッチロールした際に、開発アカウントから本番アカウントへスイッチロールしているように感じます。
しかし、実際は開発アカウントから踏み台アカウントに戻り(スイッチバック)、踏み台アカウントから本番アカウントへスイッチロールしています。
流れを説明したところで実際にスイッチロールを行い、S3の操作を行った際のログを見ていきます。
まず、スイッチロールを行った際には以下のようなログが出力されます。
スイッチロール時のログ
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAVVB45INFFQWMBWKV7:Suzuki",
"arn": "arn:aws:sts::222222222222:assumed-role/s3-role/Suzuki",
"accountId": "222222222222"
},
"eventTime": "2022-12-22T01:26:07Z",
"eventSource": "signin.amazonaws.com",
"eventName": "SwitchRole",
"awsRegion": "us-east-1",
"sourceIPAddress": "124.35.147.218",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"requestParameters": null,
"responseElements": {
"SwitchRole": "Success"
},
"additionalEventData": {
"SwitchFrom": "arn:aws:iam::111111111111:user/Suzuki",
"RedirectTo": "https://ap-south-1.console.aws.amazon.com/cloudtrail/home?region=ap-south-1#/events?EventName=AssumeRole"
},
"eventID": "68f0ee99-dfe3-40ed-82fb-7b1c1dedb148",
"readOnly": false,
"eventType": "AwsConsoleSignIn",
"managementEvent": true,
"recipientAccountId": "222222222222",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"clientProvidedHostHeader": "signin.aws.amazon.com"
}
}
ここで注目してもらいたいのが、
- SwitchFromが
arn:aws:iam::111111111111:user/Suzuki
- eventNameが
SwitchRole
- userIdentity.arnが
arn:aws:sts::222222222222:assumed-role/s3-role/Suzuki
※arn:aws:sts::スイッチ先アカウント名:assumed-role/スイッチ先ロール名/セッション名(IAMユーザ名)
になっているところです。
これは
- 111111111111(スイッチ元アカウント名)の
- Suzuki(IAMユーザ)さんが
- スイッチロールを行い
- 222222222222(スイッチ先アカウント名)の
- s3-roleを
- AssumeRoleして取得した一時的な認証情報で
- AWSリソースを操作出来るようになった
ことを意味します。
スイッチロールすることで操作する側がIAMユーザ
から一時的にロールの権限を持ったロールセッション
に変わります。
AWSコンソールでスイッチロールすると、スイッチ元アカウントのIAMユーザがスイッチ先のAWSリソースを操作しているように見えますが、実際はIAMユーザではなくロールセッションが操作しています。
では、本当にIAMユーザではなくロールセッションが操作しているのか確認してみましょう。
S3をAWSコンソールで表示すると、以下のようなログが出力されます。
S3操作時のログ
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAVVB45INFFQWMBWKV7:Suzuki",
"arn": "arn:aws:sts::222222222222:assumed-role/s3-role/Suzuki",
"accountId": "222222222222",
"accessKeyId": "ASIAVVB45INFICFVHKVA",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "AROAVVB45INFFQWMBWKV7",
"arn": "arn:aws:iam::222222222222:role/s3-role",
"accountId": "222222222222",
"userName": "s3-role"
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2022-12-22T00:33:53Z",
"mfaAuthenticated": "true"
}
}
},
"eventTime": "2022-12-22T00:34:12Z",
"eventSource": "s3.amazonaws.com",
"eventName": "ListBuckets",
"awsRegion": "ap-south-1",
"sourceIPAddress": "124.35.147.218",
"userAgent": "[AWSCloudTrail, aws-internal/3 aws-sdk-java/1.11.1030 Linux/5.10.144-111.639.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.322-b06 java/1.8.0_322 vendor/Oracle_Corporation cfg/retry-mode/standard]",
"requestParameters": {
"Host": "s3.ap-south-1.amazonaws.com"
},
"responseElements": null,
"additionalEventData": {
"SignatureVersion": "SigV4",
"CipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"bytesTransferredIn": 0,
"AuthenticationMethod": "AuthHeader",
"x-amz-id-2": "gi8RCysD5lERjgMx2gKV+Va9NQZJJuW7s+PLjb0Q5W7ZFM/b3YqTDUoHJBFgCgrQ+zVtvKRXoCg=",
"bytesTransferredOut": 2693
},
"requestID": "5RNY85Q089277A5F",
"eventID": "d26f13dc-fdc0-4ba3-b87e-f81a2327b28b",
"readOnly": true,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "222222222222",
"vpcEndpointId": "vpce-7edb2e17",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.2",
"cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
"clientProvidedHostHeader": "s3.ap-south-1.amazonaws.com"
}
}
- userIdentity.arnが
arn:aws:sts::222222222222:assumed-role/s3-role/Suzuki
- eventSourceが
s3.amazonaws.com
- eventNameが
ListBuckets
になっているので、 - s3-roleのSuzukiさんロールセッションで
- S3の
- バケット一覧を取得している
ことを意味します。
ハンズオン
それでは実際にスイッチロールを行ってみましょう。
前提
- ログインユーザにスイッチロールする権限が付与されていること
- 別アカウント間スイッチロール用のIAMロール(study-meeting-1-role)が作成されていること
- 同アカウント間スイッチロール用のIAMロール(study-meeting-2-role)が作成されていること
実施内容
1. 別アカウント間のスイッチロールをしてみよう(アカウントAからアカウントBのIAMロールC)
期待する動作
指定したアカウントのスイッチロールが成功すること
※IAMロールにアタッチされているIAMポリシーで許可された操作が可能です
実施内容
・[ロールの切り替え]をクリック
・以下の情報を入力し、[ロールの切り替え]をクリック
・アカウントB:ハンズオン実施時に確認
・ロール:study-meeting-1-role
・表示名:study-meeting-1-role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"${IAMユーザのARN}",
"${IAMユーザのARN}"
]
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
2. 同アカウント間のスイッチロールをしてみよう(アカウントBのIAMロールCからIAMロールD)
期待する動作
同アカウントでのスイッチロールが成功すること
※IAMロールにアタッチされているIAMポリシーで許可された操作が可能です
実施内容
・[ロールの切り替え]をクリック
・以下の情報を入力し、[ロールの切り替え]をクリック
・アカウントB:ハンズオン実施時に確認
・ロール:study-meeting-2-role
・表示名:study-meeting-2-role
AWSリソースへのアクセス時の認証
ここまでAWSリソースへのアクセスにAWSコンソールを使用していましたが、アクセス方法としては以下の3つがあります。
1. AWSコンソールでのアクセス
2. CLIコマンドでのアクセス
AWSが提供しているCLIコマンドで操作を行います。
例えば、S3バケットを一覧表示させるコマンドを実行した結果は以下になります。
aws s3 ls --profile hmbp-dev
2021-07-29 15:33:05 aurora-import-from-s3-111111111111
2021-10-08 09:04:38 aws-cloudtrail-logs-111111111111
2020-09-14 09:54:19 bex-api-stub-bucket-111111111111
3. AWS SDKでのアクセス
こちらは、AWSが提供しているSDKをアプリケーションから利用して操作を行います。
2022年12月現在、以下の12言語がサポートされています。
- C++
- Go
- Java
- JavaScript
- Kotlin
- .NET
- Node.js
- PHP
- Python
- Ruby
- Rust
- Swift
おわりに
本記事では、についてご紹介しました。
改めて記事の最初に、張った図を見てください。