【2022年版ベストプラクティス】AWS IAMまとめ

# はじめに
**AWSのアクセス制御サービス**である**IAM**について、2022年7月時点での機能および使用法を、初学者でも理解しやすいことを心掛けてまとめました。

IAMをよく分からないまま**適当に設定するとセキュリティ的にまずい**ので、これを機に設定を見直して頂き、セキュリティレベル向上に貢献できれば幸いです。

<img width=600 alt="IAMの重要さ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2e9190ed-59c6-e301-c92e-af8d778ffa35.png">

特に、後述する[**IAM設定手順**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam設定手順)は、**AWSに登録して最初に実施すべき設定**に相当するため、セキュリティに興味がなくとも一度は実施することをお勧めします。

また[**公式のベストプラクティス**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)は丁寧にまとめたつもりなので、初学者以外でも**AWSのセキュリティ確保**に興味がある方は、ぜひご一読頂けると嬉しいです。

<br>
<br>

# IAMとは
「Identity and Access Management」の略です。

[公式ドキュメント](https://aws.amazon.com/jp/iam/)によると、IAMは「**誰**」が「**どのAWSのサービスやリソース**」に「**どのような条件**」でアクセスできるかを指定できるサービスです。

同様に以下のAWS公式概念図では、**"Who"(誰)**, **"Can access"(アクセス条件)**, **"What"(サービスやリソース)** の3要件が提示されており、本記事でもこの3要件に則って解説を進めます

<img width=800 src="https://d1.awsstatic.com/product-marketing/IAM/iam-how-it-works-diagram.04a2c4e4a1e8848155840676fa97ff2146d19012.png">

IAMはAWSのセキュリティ確保において不可欠な仕組みであり、**知らずに使っているとセキュリティリスクを増大させる**事も多いサービスのため、クラウド利用において**最初に学ぶべき分野**の一つと言えます。

※セキュリティ的にまずい使用例は、以下の方が丁寧にまとめられています

https://zenn.dev/yutaro1985/articles/daa2aaa6cc9907#%E3%82%88%E3%81%8F%E8%A6%8B%E3%82%8B%E3%81%BE%E3%81%9A%E3%81%84%EF%BC%88%E3%81%A8%E6%80%9D%E3%81%86%EF%BC%89%E4%BD%BF%E3%81%84%E6%96%B9

<br>

## AWSにおけるセキュリティサービス
IAM以外にも、AWSにはセキュリティに関係したサービスが多く存在します。
その中でのIAMの位置付けを考えてみます。

### セキュリティの3要素
セキュリティ対策で求められる要件として、[一般的に](https://www.soumu.go.jp/main_sosiki/joho_tsusin/security/business/executive/02.html)以下の3種類が挙げられます（英語での頭文字を取って`CIA`と呼ばれます）

- **機密性** → 許可されたものだけが情報にアクセスできる
- **完全性** → 情報の改ざん、欠落が起こらない
- **可用性** → 必要なときにいつでもサービスが提供されている

この中でも**機密性**を確保するためには、許可されていないアクセスを遮断する**アクセス制御**が必要となります。

### ネットワークとホスト
アクセス制御は対策が行われる位置に応じて、以下のように分類されます。

- **ネットワーク**上でのアクセス制御 → ネットワーク経路上でアクセスを制限
- **ホスト**上でのアクセス制御 → ホスト（PCやサーバ）上の情報資産に対するアクセスを制限

AWSのようなクラウドにおいて「ホスト」はEC2を始めとした仮想サーバ（VM）の事を表しており、サーバ上で動作するSaaSのような**多くのサービス**や、サーバ上に保存されるS3のデータのような**リソース**も、**ホスト上でのアクセス制御**と同様の仕組みで管理されることが多いです。

IAMもこの**ホスト**上でのアクセス制御を設定するサービスに該当します。

### 認証と認可
アクセス制御は、一般的に以下の2手順で実施されます

- **認証** → アクセスしたのが「誰」であるかを**識別**する
- **認可** → 識別した「誰」に「どの情報資産」を「どのような条件」で**アクセスを許可**するか、**ルールに基づき決定**する

認可の`「誰」に「どの情報資産」を「どのような条件」でアクセスを許可するか`の部分は、[IAMのサービスの定義](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamとは)と非常に近い事がわかります。
以上から明らかなように、IAMは**認可**のルールを定めるためのサービスとなります。

### IAMの位置付け
以上まとめるとIAMは

**`機密性`確保のために`ホスト（サービス、リソース）`における`認可`を実行するサービス**

と位置付けることができます。

### AWSの主なセキュリティサービス一覧

参考までに、AWS各種セキュリティサービスの分類を下表に一覧化しました
（分類には筆者の主観が入っていることをご容赦ください）

|サービス名|3要素|ネットワーク or ホスト|認証, 認可 or 暗号化|概要|
|---|---|---|---|---|
|[**IAM**](https://aws.amazon.com/jp/iam/)|機密性|ホスト|認可|各種AWSリソースへのアクセス認可を管理する|
|[**Resource Access Manager**](https://aws.amazon.com/jp/ram/)|機密性|ホスト|認可|複数AWSアカウントのリソース共有を管理する|
|[**Organizations**](https://aws.amazon.com/jp/organizations/)|機密性|ホスト|認可|複数AWSアカウントの請求情報やSCP(複数アカウントへのアクセス制限設定)を一括管理する|
|[**KMS**](https://aws.amazon.com/jp/kms/)|機密性, 完全性|ホスト|認証, 暗号化|暗号化や認証に使用する鍵を管理する|
|[**Certificate Manager**](https://aws.amazon.com/jp/certificate-manager/)|機密性|ホスト|認証|サーバ・クライアント認証に使用する公開鍵証明書を管理する|
|[**Directory Service**](https://aws.amazon.com/jp/directoryservice/)|機密性|ホスト|認証|Microsoft Active Directory(AD)による認証管理をAWS上で実現＆オンプレADとの連携|
|[**Single Sign-On**](https://aws.amazon.com/jp/single-sign-on/)|機密性|ホスト|認証|複数のAWS アカウントやアプリケーションへの認証情報を一元管理する|
|[**Cognito**](https://aws.amazon.com/jp/cognito/)|機密性|ホスト|認証|Webアプリおよびモバイルアプリへの認証情報を一元管理する|
|[**Network Firewall**](https://aws.amazon.com/jp/network-firewall/)|機密性|ネットワーク|認可|サブネットに対するアクセスルールを設定する|
|[**WAF**](https://aws.amazon.com/jp/waf/)|機密性|ネットワーク|-|Webアプリに対する一般的な攻撃パターンをブロックする|
|[**Cloud Front**](https://aws.amazon.com/jp/cloudfront/)|可用性|ネットワーク|-|CDNによるアクセス速度向上と過負荷防止|

※上表は独立したサービスのみを記載していますが、VPCのセキュリティグループやS3のバケット暗号化等、各サービス内にも重要なセキュリティ機能が実装されています

※上表ではIAMを"Who"に対してアクセス権限を与える**認可**サービスとして定義しましたが、実際には"Who"が正しいかどうかを判定(なりすまし防止)する**認証**を強化する機能（MFA等）も一部含まれています。

※ホストの機密性確保という観点で類似するSingle Sign-OnとCognitoは、IAMと密接に関わっています。前者は後述の[SAML2.0による認証](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_saml.html)、後者は[ウェブアイデンティティによる認証](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_oidc.html)等、AWS以外の認証情報との連携には両者の利用が不可欠です。

上記のようにまとめてみると、認証に関連したサービスが多く、これらのサービスで得られた認証情報を元に**認可を付与するサービスはIAMにほぼ一本化されている**（Resource Access ManagerやOrganizationsもIAMの延長線上の1機能）という意味で、AWSのセキュリティにおける**IAMの重要性が非常に高い**ことが分かります。

<br>
<br>

# IAMの仕組み
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamとは)IAMは、「**誰**」(Who)が「**どのAWSのサービスやリソース**」(What)に「**どのような条件**」(Can access)でアクセスできるかを管理するためのシステムです。

具体的には、以下の2種類の要素（プリンシパルとポリシー）を設定する事で、この管理を実現します

- 「**誰**」(Who)の管理 → **プリンシパル**
- 「**対象サービス**」(What),「**条件**」(Can access)の管理 → **ポリシー**

プリンシパルとポリシーについて詳細を解説します。

## "Who"の管理 (プリンシパル)
アクセスの主体となる「**誰**」(Who)を、AWSでは**プリンシパル**と呼びます。

プリンシパルを管理するための構成要素を**IAMエンティティ** (あるいは単にエンティティ)と呼び、以下のように分類されます。

|名称|使用する場面|
|---|---|
|**ユーザー**|**アクセス主体が人**（アカウント）のとき|
|**ロール**|**アクセス主体がサービス**（アプリケーション）のとき|

また、複数のユーザーをまとめて管理しやすくしたものを**グループ**と呼びます。

これら「ユーザー」、「ロール」、「グループ」の3つをまとめて**IAMアイデンティティ** (あるいは単にアイデンティティ)と呼びます。

※「プリンシパル」「IAMエンティティ」「IAMアイデンティティ」は紛らわしいですが、いずれも「**誰**」を表す構成要素をまとめた呼び方となります。参考までに、各種別に含まれる対象を下記します。

||ユーザー|ロール|グループ|
|---|---|---|---|
|**プリンシパル**|○|○|○|
|**IAMエンティティ**|○ (ルートユーザー以外)|○|×|
|**IAMアイデンティティ**|○ (ルートユーザー以外)|○|○|

<br>

これら「ユーザー」、「ロール」、「グループ」の概要について、以下で解説します。

### ユーザー
アクセス主体である"**Who**"**が人**のとき、これを定義する基本単位です。
基本的にはAWS上で作成したアカウントと紐付きます

ユーザーは

- ルートユーザー
- IAMユーザー

に分けられ、IAMユーザーは大まかに以下のように分類できます。

- 管理者ユーザー
- パワーユーザー
- 個別に権限付与するユーザー

以上まとめると以下のようになります。

||課金情報等へのアクセス|IAM操作権限|各種AWSサービスへのアクセス|想定される職責|
|---|---|---|---|---|
|**ルートユーザー**|○|○|○|IT管理者|
|**管理者ユーザー**|×|○|○|IT管理者|
|**パワーユーザー**|×|×|○|開発責任者、多数のサービスを利用する開発者|
|**個別に権限付与するユーザー**|×|×|△ (個々に設定)|開発者|

ユーザーを登録する際はこれら大まかな分類をまず定めたのち、細かなアクセス権限（例：その他のユーザーへの各種AWSサービス権限付与）をポリシにより逐次設定していきます。

以下、各ユーザー分類の概要を解説します。

#### ・ルートユーザー
AWSへの最初の登録時に作成されるユーザーであり、最も強い権限を持っています。

全てのAWSサービスとリソースにアクセス可能であることに加え、IAMユーザーにはない以下の権限を持ちます。

- IAMユーザへの課金情報アクセス権限付与
- 複数アカウント請求情報の統合
- AWSアカウントの停止
- 逆引きDNS申請、ドメイン登録の移行

お金に関する情報へのアクセスやアカウントの停止、ドメイン登録の操作ができるため、乗っ取られるとトンデモない事になってしまいます。
このようなリスクを防ぐため、**ルートユーザーを日常的な開発に使用することは推奨されません**

個人開発であっても、管理用のIAMユーザー（管理者ユーザー）を作成し、こちらを日常的に使用した方が良いでしょう

#### ・IAMユーザー (管理者ユーザー)
**IAM自身の操作権限を持つ**ユーザーです。
[後述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者用グループの作成)`AdministratorAccess`と呼ばれるポリシーを付与する事で作成できます。

[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamの位置付け)、IAMを操作すればアクセス権限を自由に付与する事ができるため、管理者ユーザーは

「**認可に関しては万能の存在**」

となることができます。よって不必要に増やすとセキュリティリスクが増えることから、**管理者ユーザーの数は必要最小限に絞る**ことが望ましいです。
（後述の[ベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)における「最小限の特権を認める」に相当）

組織においては、組織内のAWSアカウントを統括するIT管理者を管理者ユーザーとすることが一般的です。

#### ・IAMユーザー (パワーユーザー)
管理者ユーザーとの差は**IAM自身の操作権限を持たない**事で、**IAM以外の大半のサービスへのアクセス権限を持つ**ユーザーです。
[後述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#パワーユーザー用グループの作成)`PowerUserAccess`と呼ばれるポリシーを付与する事で作成できます。

元々は[こちらの記事](https://xtech.nikkei.com/it/article/COLUMN/20060926/249021/)で言及されているように、セキュリティと利便性（サービスを利用するたびに逐一権限付与するのは手間が掛かる）のバランスを取るために誕生したユーザーですが、強い権限を持つ事には変わらず、**むやみにパワーユーザーの数を増やす事は推奨されません**。

組織においては、開発を統括する責任者や多くのサービスを継続的に利用する開発者に付与されることが多いですが、セキュリティリスクのある**パワーユーザーを置かずに**、[後述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー個別に権限付与するユーザー)「**個別に権限付与するユーザ**」**のみを使用することも多い**です。

#### ・IAMユーザー（個別に権限付与するユーザー）
[後述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)に「最小限の特権を認める」という項目があることから分かるように、セキュリティを高めるためには**必要な権限のみを付与する**事が有効です。

よって管理者やパワーユーザー等の特殊なユーザーを除くと、AWSのユーザには**使用するサービスの権限**(EC2, S3等へのアクセス権限)を**個別に付与する**事が一般的です。

権限を付与するためには、[後述の「サービスごとの管理ポリシー」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#サービスごとの管理ポリシー)を必要に応じて複数選択し、ユーザー(またはグループ)にアタッチします。

なお、上記のように複数の「サービスごとの管理ポリシー」を個々に付与する方法では、サービス数が増えた際に管理が煩雑となってしまいます。そこで「ネットワーク管理者」「データサイエンティスト」等の職責を想定し、必要な複数サービスへの権限を一括付与できる
「**ジョブ機能のポリシー**」
という仕組みも、AWS側が用意してくれています（[詳細は後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ジョブ機能の管理ポリシー)）


### グループ
組織が大きくなると、全てのIAMユーザーの権限を個々に管理するのは大変です。
そこで**同じ権限を持つ複数のIAMユーザーをまとめて管理**できる仕組みが、**グループ**です。

グループに設定された権限は、グループに所属する全てのIAMユーザーに適用されます。

例えば、パワーユーザー用ポリシーを付与したグループを作成すれば、このグループに所属させたユーザーは全てパワーユーザーとなるため、個別のユーザーにポリシーを付与する手間が省け、**管理の複雑さやそれに伴う設定ミスを防ぐ**事が出来ます。

設定ミスはセキュリティリスクの主要因の一つなので、**チームでの運用時はグループを積極的に活用する事をお勧め**します ([後述のIAM設定手順](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam設定手順)でもグループを使用して権限付与します)

### ロール
AWS上でアプリケーションを動作させる場合、ユーザーが直接寄与する事なく**あるサービスから他のサービスへのアクセス**が生じることがあります。

例えばEC2上のプログラムで出力されたデータをS3に保存する場合、「EC2 → S3への書き込み権限」が必要となります。

このようにサービスから他のサービスへのアクセスが生じる際に、**アクセス元のサービス**(上例でのEC2)に**権限を付与**するための仕組みを、**ロール**と呼びます。

ロールもユーザーやグループと同様にポリシーを付与してアクセス権限を与える事ができますが、ユーザーやグループとは異なり**アクセス権限の主体**が**人ではなくサービス**であることにご注意ください。

<br>
<br>

## "Can access", "What"の管理 (ポリシー)
アクセス権限を適用する「**対象サービス**」(What)と「**アクセス条件**」(Can access)の管理をするのが、**ポリシー**です

### ポリシーの分類
ポリシーは以下のように、[管理ポリシーとインラインポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html)に分類できます。
- **管理ポリシー** → スタンドアロン（ユーザーやロールとは別個に作成する）ポリシー
- **インラインポリシー** → 1つのアイデンティティ（ユーザー、ロール、グループ）に埋め込まれたポリシー

上記だけでは分かりづらいですが、管理ポリシーは「**複数のユーザーやグループ、ロール（アイデンティティ）で使い回し**」できるのに対し、インラインポリシーはアイデンティティと1対1で紐づいているため、**使い回しできない**事が最大の差となります

管理ポリシーはさらに、以下の2種類に分類できます

- **AWS管理ポリシー** → AWSがデフォルトで準備しているIAM管理ポリシー
- **カスタマー管理ポリシー** → 利用者が独自に作成、管理する管理ポリシー

以上のように、ポリシーには「**AWS管理ポリシー**」、「**カスタマー管理ポリシー**」 、「**インラインポリシー**」の3種類が存在します。

### 使用するポリシーの優先順位
[後述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)では、

**AWS管理ポリシーを使用 → 必要に応じてカスタマー管理ポリシーを追加**

**の順で選択・運用**する事が推奨されています (**インラインポリシーは推奨度低**)

選択方法の詳細は後述の[ベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws管理ポリシーを使用したアクセス許可の使用開始)および[IAM設定手順](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザー用ポリシーの作成)を参照ください

### AWS管理ポリシーの概要
第一の選択肢として利用が推奨されるAWS管理ポリシーですが、実際の選択画面は以下のようになっています。

大きく分けると、「タイプ」の列の内容に合わせて
- **ジョブ機能の管理ポリシー**
- **サービスごとの管理ポリシー**

の2種類に分類されます。

<img width=600 alt="AWS管理ポリシー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e9cca9f2-badb-a2a8-99e3-4f0d12aa310b.png">

#### ・ジョブ機能の管理ポリシー
ジョブ機能の管理ポリシーは[前述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー個別に権限付与するユーザー)**職責ごとに割り振られた**管理ポリシーであり、**管理者ユーザー**用の`AdministratorAccess`や**パワーユーザー**用の`PowerUserAccess`を始めとし、職責に応じて複数のサービスをまとめた管理ポリシーが定められています。

指定できる職責は以下のページでまとめられているので、これら**ジョブ機能の職責に該当する開発者**（一般的には多くのサービスにアクセスするメイン開発者が該当）となるユーザーはこちらを参考にポリシーを選択すると良いでしょう。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html

なお、ベストプラクティス的には[最小限の特権](https://qiita.com/c60evaporator/items/0121399880625cc1de51#最小限の特権を認める)を詳細設定できる「サービスごとの管理ポリシー」の方が望ましいので、どちらを選択するかはセキュリティと利便性のバランスを見て判断してください。

#### ・サービスごとの管理ポリシー
サービスごとの管理ポリシーは、**AWSのサービスごとに書込、読取などの権限を個別設定できるポリシー**です。

[前述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー個別に権限付与するユーザー)「**個別に権限付与するユーザー**」に相当する一般ユーザーは、[特権を最小限にする原則](https://qiita.com/c60evaporator/items/0121399880625cc1de51#最小限の特権を認める)に基づいてこちらを選択するのが良いでしょう。

### ポリシーの構造
上記3種類のポリシーはいずれも、JSONファイルで記述されています。

例えば、S3の読取のみが許可されるAWS管理ポリシー`AmazonS3ReadOnlyAccess`は、以下のように記述されています。

```json:AmazonS3ReadOnlyAccess
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*",
                "s3-object-lambda:Get*",
                "s3-object-lambda:List*"
            ],
            "Resource": "*"
        }
    ]
}
```

ポリシーが記述されたJSONの最上位は、以下のフィールドが記述されます

- **Version** → ポリシーの記述言語のバージョン（基本的には`2012/10/17`で固定）
- **id** → ポリシーの識別子（オプションのため、上記AmazonS3ReadOnlyAccessでは記述なし）
- **Statement** → ポリシーの詳細を記述するフィールド

**Statementフィールド**の下には、以下のフィールドに**具体的な条件**を記述する必要があります。

- **Effect** → アクセス権限の種類（基本的には"Allow"(許可)か"Deny"(拒否)）
- **Action** → 許可または拒否するアクション（アスタリスク*は以下の全アクションが対象となる）
- **Resource** → アクションの設定対象となるリソース一覧（S3の場合、バケット名等を指定）
- **Sid** → 複数Statementが存在する場合の識別子（上記AmazonS3ReadOnlyAccessでは記述なし）
- **Condition** → ポリシー適用対象を絞るための追加条件（上記AmazonS3ReadOnlyAccessでは記述なし）

カスタマー管理ポリシーやインラインポリシーを作成する際には、このJSONファイルを編集する事となりますが、**GUIで簡易的に作成することもできます**（後述の「[IAM設定手順](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザー用ポリシーの作成)」ではGUIでの作成方法を紹介します）

また、JSONからの作成方法として、以下のサイトでAWS管理ポリシーをベースにカスタマー管理ポリシーを作成する方法を分かりやすく紹介されています、

https://dev.classmethod.jp/articles/how2make-custompolicy/

<br>
<br>

## 例外的なポリシー
今まで解説した内容は

- IAMは「誰」(プリンシパル/アイデンティティ)が「どのAWSのサービスやリソース」に「どのような条件」(ポリシー)でアクセスできるかを管理
- 上記アクセス制御を、**ポリシーをプリンシパルに付与**する事で実現
- **アクセス主体が人なら「ユーザー」、アクセス主体がサービスやアプリケーションなら「ロール」**

を前提としていましたが、**これらが成り立たない例外的なポリシー**も存在するので、解説します。

特に「**バケットポリシー**」や「**信頼ポリシー**」は例外と呼ぶのがはばかられるほどよく使用されるので、覚えておいて損はないかと思います。

### リソースベースのポリシー
ここまで解説したように、IAMでは通常、アクセスする側であるプリンシパル (アイデンティティ)にポリシーを付与する事でアクセス制御を実現します。この方法を「アイデンティティベースのポリシー」と呼びます

一方で一部サービスには、アクセス**される**側である「**リソース**」を主体としてアクセス権限を設定する「**[リソースベースのポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_identity-vs-resource.html)**」という手法も存在します。

例えばS3の[バケット](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucket-policies.html)には、独自のリソースベースのポリシー(**バケットポリシー**)を設定する事ができます。これにより、アクセス**される**側であるバケットへのアクセス制御を実現する事ができます。

リソースベースのポリシーは使用できるサービス（S3、SQS、VPC等）が限られていますが、**特定のリソース**（例：S3内の特定のバケットに保存された機密データ）**のセキュリティを選択的に高めたい場合**に役立つでしょう。

なお、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-basics)によるとアイデンティティベースとリソースベース両方のポリシーが設定された場合、**両方のポリシーで許可されている**主体のみがアクセスを許可されるようです。
上記のようにAND条件で厳しくアクセス条件を縛ることで、S3等のサービスでは強固なセキュリティを実現する事ができます。

### 信頼ポリシー
リソースベースのポリシーの一種として**よく使用される**ものに**信頼ポリシー**が挙げられます。

信頼ポリシーはコンソール上では**信頼関係**とも呼ばれ、このポリシーを使用する事で、**あるロールが持っている権限を他のプリンシパル**（ユーザー、グループ、ロール）**に移譲**することができます

先ほど「ロールはアクセス主体がサービスやアプリケーションの場合に使用される」と述べましたが、信頼ポリシーによるロール権限移譲は、移譲先が人（ユーザー、グループ）であってもサービスであっても実施可能で、主に**移譲元ロールとは別のAWSアカウント、またはAWS外のSSO対応サービスへの権限移譲**に用いられます。

#### ・信頼ポリシーを意識する必要がある場面
ロールをAWSサービスに付与する際は基本的に信頼ポリシーが必要となりますが、EC2やLambda等の**主要サービス**では[ロール作成時のユースケース選択](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールの作成)に応じて**自動で信頼ポリシーが付与されるため、意識する必要性は低い**です。

**意識する必要がある** (手動設定が必要な)**場面の代表例**として、後述の[**一時的に権限を付与**する場合](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)や、以下の**VPCフローログ** (自動付与されるユースケースに含まれないサービス)の例が参考になるかと思います

https://qiita.com/c60evaporator/items/b9e645b96afa3a34f41e#フローログ記録用のiamポリシー作成

### Perminssions boundary (アクセス許可境界)
通常のIAMでの権限設定(下図のIdentity-based policy)に加えて、[Permissions boundary](https://dev.classmethod.jp/articles/iam-permissions-boundary/)と呼ばれるサービスにポリシーを設定することで、**IAMで付与できる権限に制限を設ける**事ができます。
![image.png](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/images/EffectivePermissions-scp-boundary-id.png)
Permissions boundaryを設定すると、上図で示されたように

- 通常のIAMでの権限設定
- Permissions boundaryで設定したアクセス許可境界
- 組織側で設定したアクセス許可境界であるSCP(AWS Organizationsサービスで設定可能)

の**全てで共通して設定された権限のみが、実際に付与される権限**となります。
(上のベン図で全てが重なった部分のみ権限が付与される)

これらPermissions boundary, SCPによる制限は、権限を付与したくないサービスに誤って権限が付与されることを防いだり、各アカウントで付与できる権限を組織側からコントロールすることを主な目的として使用されるようです。


### アクセスキーによる認証
Pythonのようなプログラム言語で書かれたアプリケーションからAWSのサービスにアクセスしたい場合、アプリケーションの動作場所がEC2のようなAWSサービス、あるいは[ウェブアイデンティティ](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_oidc.html)や[SAML2.0](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers_saml.html)に対応したサービスの場合、[後述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)ロールと権限移譲によるアクセス権限の付与が推奨されています。
(2022/7以降は後述の[IAM Roles Anywhere](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam-roles-anywhere)も選択肢に追加)

一方で上記に該当しない場合（例:オンプレサーバ上で動作するアプリケーション）、ロールによるアクセス権限の付与は困難です。

このような**ロール非対応のアプリケーション**から、**AWSリソースへのアクセス**を実現する方法が**アクセスキー**です。
IAMユーザーに紐づいた**アクセスキー**をAWS側で発行し、プログラムが動作するデバイスに保持することで、アクセス主体がプログラムの場合でも「ユーザー」と同様の認証情報を使用する事ができます。

アクセス主体がプログラム（アプリケーション）であるという点で、「アクセスキー」と「ロール」は紛らわしいですが、前者は**AWS外部のプログラム**、後者はAWS内のサービスを主に対象にしています（[前述の記事](https://zenn.dev/yutaro1985/articles/daa2aaa6cc9907#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9Aiam%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%9B%E3%82%8B)でも触れられていますが、AWSサービス内からアクセスキーを使用することは推奨されません）

アクセスキーは**ID**と**シークレット**から構成され、この両者をプログラム側からAWSに提供することで、認証が成立します。**シークレットは作成時にしか閲覧・ダウンロードできない**ので、忘れてしまったら再度アクセスキーを作成し直す必要があります（これによりセキュリティを確保しているとも言えます）

アクセスキーは便利な機能ですが、通常の認証をすっ飛ばす**セキュリティリスクの塊**と言える存在でもあるため、**取り扱いに注意**が必要です。
例えばGitHubにアップロードしてしまうと、以下のような恐怖体験を味わう事ができます

https://qiita.com/saitotak/items/813ac6c2057ac64d5fef

以下のAWS公式にベストプラクティスが記載されているので、使用前に一読をお勧めします。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.html

<br>
<br>

## 一時的に権限を付与する方法 (権限移譲)
IAMで特に理解が難しいのがこの部分です。

[後述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールを使用してアクセス許可を委任する)には「**一時的な権限の付与にはアクセスキーでなくロールを使うべき**」と記載されていますが、ロールを簡単に付与できる**同アカウントのAWSサービス以外**では、

「**何使えばええねん！**」

と思って公式ドキュメントや他のWebページを検索し、以下のように多数のサービスの名前がヒットし、混乱して使用を諦めた方も多くいるでしょう

- **信頼ポリシー**(信頼関係)
- **AssumeRole**
- **STS**

実際には上記を組み合わせることで権限移譲を実現できるので、相互関係を整理する事でイメージが掴めるかと思います。
**以下の記事が非常に分かりやすい**ので、リンクを貼らせていただきます

https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/

### 権限を移譲できる対象
上記の信頼ポリシー＋AssumeRole＋STSを組み合わせて**権限移譲用のロール**を作成することで、**様々なユーザやサービスに権限を移譲**する事ができます。

詳しくは[後述の「IAM設定手順」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)で解説しますが、現状のAWSコンソールからは大きく分けて以下の3種類の対象に権限を移譲する事ができます

|権限の移譲先|AWSコンソールからの指定方法 ([後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールの作成))|
|---|---|
|同アカウントor別アカウントの**AWSユーザやサービス**|AWSアカウント|
|Amazon,Facebook,Googleなどの**OpenID Connect互換のIdP**と連携して認証したいとき([参考](https://zenn.dev/mn87/articles/a0231e417a883e))|ウェブアイデンティティ|
|**SAMLシングルサインオン**でAD等と連携して認証したいとき|SAML2.0フェデレーション|

#### IAM Roles Anywhere
上記3種類の対象以外にも、**一時的なAWSアクセス権限**を**公開鍵証明証に渡す**、**IAM Roles Anywhere**という機能が、2022/7に追加されました。

今までは[セキュリティリスクのあるアクセスキー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)を使用せざるを得なかった用途の一部で、IAM Roles Anywhereを使用する事で**一時的な権限付与を実現**する事ができ、[**ベストプラクティスに則った運用**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールを使用してアクセス許可を委任する)が可能となります。

詳細は以下の記事を参照下さい。

https://dev.classmethod.jp/articles/hashicorp-vault-pki-for-iam-role-anywhere/

### スイッチロール
上記の**権限移譲用ロールを付与した仮想的なユーザ**で、**AWSコンソール上でログイン**する事ができます。
この仕組みを「**スイッチロール**」と呼び、対象ユーザが本来権限を持たないサービスにアクセスしたい時、一時的に権限を付与したい場合に便利です。

具体的な方法は[後述の「IAM設定手順」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)で解説します。

<br>
<br>

# IAMコンソール画面の見方
AWSコンソールにログインしてIAMのサービスに入ると、以下のような画面が表示されます。

<img width=960 alt="IAMコンソール画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3a80d830-c7a1-1b98-c33b-fa2886808544.png">

IAMの操作は基本的に上図の「左側のタブ」（ナビゲーションペイン）と「IAMダッシュボード」を使用するため、それぞれ簡単に解説します

## 左側のタブ（ナビゲーションペイン）
[前述したIAMの基本構成要素](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamの仕組み)であるユーザー、グループ、ロール、ポリシーを中心とした、各種リソースの管理画面に移動できるタブです
### User groups
[グループ](https://qiita.com/c60evaporator/items/0121399880625cc1de51#グループ)の作成や、許可するポリシー、所属するユーザー等を管理する画面です。
<img width=600 alt="ユーザーグループ画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/780cea1d-27f5-0824-a35f-caca0aa2e653.png">

### ユーザー
[ユーザー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ユーザー)の作成や、許可するポリシー、所属するグループ、認証情報等を管理する画面です
<img width=600 alt="ユーザー画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c7ae0203-b8e8-e822-19de-48ad2ad09931.png">

### ロール
[ロール](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロール)の作成や、信頼ポリシーの設定等を管理する画面です。
<img width=600 alt="ロール画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/894ffc51-b1ec-a07f-2bd9-841f03d09a51.png">

### ポリシー
[ポリシー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#can-access-whatの管理-ポリシー)の作成や、ポリシーが許可されたグループ、ユーザー等を管理する画面です。

### IDプロバイダ
AWS外の認証情報（WindowsのActive Directory等）と紐づけるためのシングルサインオン情報を管理する画面です

### アカウント設定
パスワードポリシーや[AWS STS](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp.html)を管理する画面です

### Access Analyzer
アクセスアナライザーは、後述の[ポリシーの検証](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの検証)やアクセス監視に使用されるツールで、端的に言うと**外部からアクセスできる状態となっているリソースがないか検知**する機能を持ちます。

具体的には、**以下のリソースが検知の対象**となります。

- [**S3**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-resources.html#access-analyzer-s3) ([ブロックパブリックアクセス]()が無効のバケット等)
- [**IAMロール**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-resources.html#access-analyzer-iam-role) (外部からアクセスできる[信頼ポリシー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#信頼ポリシー)が付与されたロール)
- [**KMS**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-resources.html#access-analyzer-kms-key) (外部エンティティに対してアクセスが許可されたキー)
- [**Lambda**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-resources.html#access-analyzer-lambda) (外部エンティティに対して関数へのアクセスを許可するポリシー)
- [**SQS**](https://aws.amazon.com/jp/sqs/) (外部エンティティに対してキューへのアクセスを許可するポリシー)

いずれもセキュリティリスクが高めの状態であるため、これらを**簡易的に検知**することは**セキュリティ診断の一種**としての役割を果たすでしょう。

Access Adviserと名前が紛らわしいですが、差異を理解するために以下の記事が参考になります

https://dev.classmethod.jp/articles/iam-accessanalyzer-vs-iam-accessadvisor/

### 認証情報レポート
認証情報を簡略化したレポートをCSV形式でダウンロードすることができます。


## IAMダッシュボード
重要度の高い情報を簡略化して表示してくれる便利な画面です

### セキュリティに関するレコメンデーション
重要な設定が、[後述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)等のAWS推奨設定に合致しているかを判定・表示してくれます。
ここが赤色になっていたらセキュリティリスクが高い状態となっているので、指示に従って設定変更しましょう

<img width=600 alt="セキュリティに関するレコメンデーション" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c4fda1ae-16f2-e6dd-28a0-681928168bd0.png">

### IAMリソース
現在のAWSアカウントに含まれるリソース（ユーザー、グループ、ロール、ポリシー、IDプロバイダ）の数を一覧表示します。

クリックすると、前述の[左側のタブ](https://qiita.com/c60evaporator/items/0121399880625cc1de51#左側のタブナビゲーションペイン)と同様にこれらのリソースの設定画面にアクセスすることができます。

<img width=600 alt="IAMリソース" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/972a92d6-6bb4-920f-f686-b86e16ba9670.png">

### AWSアカウント
[後述のアカウントIDやエイリアス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成続き)等、アカウントへのログイン情報を表示します

### クイックリンク
現在ログインしているユーザーの認証情報（自分の認証情報）が確認できます

### ツール
IAMに関連した以下2ツールのリンクに飛べます（使用法はリンク先を参照ください）
- [ポリシーシミュレータ](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_testing-policies.html) → 設定したポリシーが想定通り動作しているかを確認するためのシミュレータ
- [Web Identity Federation Playground](https://dev.classmethod.jp/articles/web-identity-federation-playground/) → シングルサインオンのアクセストークンにAWSの一時認証情報を付与できるツール

<br>
<br>

# IAMセキュリティのベストプラクティス
[**AWS公式に記載されているベストプラクティス**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html)では、**以下の項目に従って権限設定**することが**推奨**されています。

後述の[IAM設定手順](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam設定手順)においても、これらの推奨項目を満たすよう設定を進めていきます

|ベストプラクティス推奨事項|後述の[IAM設定手順](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iam設定手順)での実施箇所|
|---|---|
|[**AWSアカウントルートユーザーのアクセスキーをロックする**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#awsアカウントルートユーザーのアクセスキーをロックする)|[ルートユーザーの設定](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ルートユーザーの設定)|
|[**MFAの有効化**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの有効化)|[ルートユーザーの設定](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ルートユーザーの設定)、[管理者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成)|
|[**ユーザーのために強度の高いパスワードポリシーを設定する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ユーザーのために強度の高いパスワードポリシーを設定する)|[ルートユーザーの設定](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ルートユーザーの設定)|
|[**最小限の特権を認める**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#最小限の特権を認める)|[アプリ開発者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)|
|[**AWS管理ポリシーを使用したアクセス許可の使用開始**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws管理ポリシーを使用したアクセス許可の使用開始)|[管理者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成), [パワーユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#パワーユーザーの作成), [アプリ開発者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)|
|[**インラインポリシーではなくカスタマー管理ポリシーを使用する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#インラインポリシーではなくカスタマー管理ポリシーを使用する)|[アプリ開発者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)|
|[**ポリシーの検証**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの検証)|[アプリ開発者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)|
|[**アクセスレベルを使用して、IAM のアクセス許可を確認する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスレベルを使用してiamのアクセス許可を確認する)|[アプリ開発者ユーザーの作成](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)|
|[**Amazon EC2 インスタンスで実行するアプリケーションに対し、ロールを使用する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#amazon-ec2-インスタンスで実行するアプリケーションに対しロールを使用する)|[AWS内サービスへの権限付与](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws内サービスへの権限付与)|
|[**ロールを使用してアクセス許可を委任する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールを使用してアクセス許可を委任する)|[別のAWSアカウントへの権限移譲](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)|
|[**アクセスキーを共有しない**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーを共有しない)|[AWS外アプリの権限設定](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws外アプリの権限設定)|
|[**追加セキュリティに対するポリシー条件を使用する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#追加セキュリティに対するポリシー条件を使用する)|[AWS内サービスへの権限付与](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws内サービスへの権限付与)|
|[**認証情報を定期的にローテーションする**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#認証情報を定期的にローテーションする)|適宜定期確認|
|[**不要な認証情報の削除**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#不要な認証情報の削除)|適宜定期確認|
|[**AWSアカウントのアクティビティのモニタリング**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#awsアカウントのアクティビティのモニタリング)|適宜定期確認|

上記項目名だけでは内容が分かりづらい(公式ドキュメントも自動翻訳のためか非常に難解な)ので、それぞれを簡単に解説します

<br>

## AWSアカウントルートユーザーのアクセスキーをロックする
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)AWSでは、**アクセスキー**を使用してプログラム経由での認証が可能となっていますが、認証情報を保持したアクセスキーは**流出時のセキュリティリスクが大きい**とも言えます。

特にルートユーザーの認証情報が流出すると、文字通り「何でもできてしまう」事となるため、このリスクを防ぐため**ルートユーザーのアクセスキーはそもそも作成しない事が望ましい**です。

デフォルトではルートユーザーのアクセスキーは作成されないので、ルートユーザーでログインした状態でコンソールからIAMにアクセスし、ダッシュボードに以下のように表示されていればOKです
<img width=600 alt="ルートユーザーのアクセスキー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5f811fc3-c228-02ed-a280-3bb0da265522.png">

<br>

## MFAの有効化
MFAとは、**多要素認証**(Multi-Factor Authentication)の事を指します。

多要素認証とは、文字通り複数の認証方法を組み合わせる方法で、一般名詞としては様々な方法が考えられますが、AWSにおいては「**通常のパスワード認証**」＋「**スマホアプリ(Google Authenticator)による時刻同期型ワンタイムパスワード(OTP)認証**」を組み合わせる方法が最も一般的です。

[ベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users)では、**全てのユーザーにMFAを設定する事が推奨**されています。

具体的な設定方法は[後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの設定)しますが、MFAが設定されているかどうかは、各ユーザーでAWSコンソールにログインしてIAMにアクセスした際の、ダッシュボードに表示されます。
以下のように「MFAが設定されている」と表示されていればOKです
<img width=600 alt="ルートユーザーのMFA" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b6e26836-992b-467c-5ddb-8e36bfcaa225.png">

<br>

## ユーザーのために強度の高いパスワードポリシーを設定する
[詳細は後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#パスワードポリシーの設定)しますが、**パスワードポリシー**（IAMユーザー作成時のパスワード設定に必須となるルール）は、**ある程度厳しく**設定することが推奨されています。

デフォルトでは以下のパスワードポリシーが適用されていますが、**組織のルールと適合性を確認しながら、適宜より厳しいルールを適用してください**
<img width=600 alt="パスワードポリシーの変更" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/dafc4bf0-ec31-8ef8-2ab5-41fb0c954953.png">

<br>

## 最小限の特権を認める
アクセス制御を運用する際の手順として、以下の2通りの方法が考えられます

- 最小限のアクセス許可から開始し、必要に応じて追加のアクセス許可を付与
- 余分にアクセス許可を与えた状態から開始し、必要ないアクセス許可を後から削除

ベストプラクティスでは、**前者**の**最小限のアクセス許可からスタートする**事が推奨されています。
後者の方法は開始時点のセキュリティが弱い（アカウントが乗っ取られた際のリスクが大きい）事が理由です。

基本的には、「**アクセス権限は必要になったときに付与する**」（必要になるまで付与しない）ことを心掛けてください。
特に[前述の記事](https://zenn.dev/yutaro1985/articles/daa2aaa6cc9907#よく見るまずい（と思う）使い方)で触れられていたように、**むやみに管理者権限を付与する事は避けるべき**です。

<br>

## AWS管理ポリシーを使用したアクセス許可の使用開始
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの分類)、ポリシーには「AWS管理ポリシー」、「カスタマー管理ポリシー」 、「インラインポリシー」の3種類が存在しますが、**初期状態**ではデフォルトで用意されている**AWS管理ポリシーの使用が推奨**されています。

[公式にも](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#bp-use-aws-defined-policies)
`チームに必要な許可のみを提供するIAMカスタマーマネージドポリシーを作成するには、時間と専門知識が必要です`
と記載されているように、カスタマー管理ポリシーの作成は難易度が高く、**初心者が独自にカスタマー管理ポリシーを作るとミスや勘違いでセキュリティリスクを作る原因となる**ので、まずは**AWSが準備してくれているAWS管理ポリシーを使用する**のが良いでしょう。
(ただし、カスタマー管理ポリシーの方が権限範囲を柔軟に絞れるので、慣れてきたらこちらの方が「最小限の特権」に合致したポリシーを作成できます)

[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws管理ポリシーの概要)AWS管理ポリシーは「ジョブ機能の管理ポリシー」と「サービスごとの管理ポリシー」が存在しますが、

**・ジョブ機能の職責に該当する開発者**（[管理者ユーザー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー-管理者ユーザー)、[パワーユーザー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー-パワーユーザー)等） → 以下に基づき「**ジョブ機能の管理ポリシー**」を選択

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_job-functions.html

**・ジョブ機能の職責に該当しない開発者**（[個別に権限付与するユーザー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー個別に権限付与するユーザー)） → 「**サービスごとの管理ポリシー**」を必要なものだけ選択

すると良いでしょう

<br>

## インラインポリシーではなくカスタマー管理ポリシーを使用する
**AWS管理ポリシーでは設定しきれない細かな権限を設定したい場合**、カスタマー管理ポリシーまたはインラインポリシーを使用する必要があります。

この場合[先ほど触れたように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#使用するポリシーの優先順位)、[ベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#best-practice-managed-vs-inline)では、**カスタマー管理ポリシーの使用が推奨**されています。

カスタマー管理ポリシーを使用すべき理由ですが、以下を見ると「コンソール内のすべての管理ポリシーを1か所で確認できること」や「設定を使い回せる事（再利用可能性）」が挙げられています。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#choosing-managed-or-inline

<br>

## ポリシーの検証
新しくポリシー（カスタマー管理ポリシーまたはインラインポリシー）を作成した際には、**作成したポリシーにエラーやセキュリティリスクがないか検証**することが推奨されています。

簡易的な方法として「[IAMコンソールでのポリシーの検証](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-policy-validation.html)」が推奨されており、本記事でも[**実際の使用法を後述**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの検証-1)します

また、上記に加えて[前述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#access-analyzer)**Access Analyzer**で**外部アカウントと共有しているリソースを検出**することも、ベストプラクティスでは推奨されています。
Access Analyzerの使用方法は以下の方がわかりやすく解説されています。

https://dev.classmethod.jp/articles/reinvent-2019-getting-start-iam-analyzer/

<br>

## アクセスレベルを使用して、IAMのアクセス許可を確認する
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの構造)、ポリシーはJSONで記述されますが、これだけでは内容が直感的に分かりづらく、ミスの原因となってしまいます。

ミスを防ぐための仕組みとして前述の[ポリシーの検証](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの検証)が挙げられますが、これ以外にも**ポリシーの概要を分かりやすく表示**する**アクセスレベル**と呼ばれる指標が存在します

アクセスレベルは、`List`(リソースのリスト表示)、`Read`(読取)、`Write`(書込)、`Permissions management`(権限設定)、`Tagging`(リソースのタグ付け)の5つの分類からなり、テーブル表示された[ポリシー概要](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_understand-policy-summary.html)を直感的に確認することができます。

例えば[前述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの構造)`AmazonS3ReadOnlyAccess`というAWS管理ポリシーでは、アクセスレベルは以下のように表示されます
（表示方法は[後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの検証-1)）

<img width=480 alt="アクセスレベル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/4b590065-aa64-6cbe-5a52-6a4562e8aea9.png">

S3およびLambdaからS3へのリスト表示と読取が許可されていることが分かり、JSONよりも直感的にポリシーの内容が確認できる事が分かります。

<br>

## Amazon EC2 インスタンスで実行するアプリケーションに対し、ロールを使用する
[前述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)したように、アプリケーションからAWSへのアクセス権限を与える方法には「ロール」と「アクセスキー」の2通りが存在しますが、**アクセス元がAWS内のサービスである場合は「ロール」が推奨されます**。

EC2は「AWS内のサービス」に相当するため、EC2上で動作するアプリケーションにはロールで権限を与える必要があります
（[具体的な方法は後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws内サービスへの権限付与)します）

<br>

## ロールを使用してアクセス許可を委任する
**他のAWSアカウントやアプリケーションに一時的にアクセス権限を与える**際の手法として、セキュリティリスクの大きい**アクセスキーの使用は避け**、[前述の](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)**信頼ポリシーによる権限移譲**が推奨されています。

アクセスキーの使用が推奨されるのは、AWS外かつシングルサインオンに対応していないアプリケーション等、権限移譲に対応していない場合のみです。

詳細は[「**一時的に権限を付与する方法**」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)を参照ください

<br>

## アクセスキーを共有しない
「**同一のアクセスキーを複数人で使い回すな**」という趣旨の項目です。
代わりに**ロールを使用して一時的に権限を付与**する方法が推奨されています。

前節と同様、詳細は[前述の「**一時的に権限を付与する方法**」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)を参照ください

<br>

## 追加セキュリティに対するポリシー条件を使用する
タイトルだけでは何のことやらといった感じですが、[前述の「ポリシーの構造」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの構造)で述べた`Statement`フィールドの`Condition`要素を記載することで、**ポリシーにアクセスできる条件を限定してセキュリティを向上**させることを推奨する内容となっています。

`Condition`要素への条件指定方法は以下を参照ください

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_condition.html

また、[後述の「IAM設定手順」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ec2へのロールのアタッチ-管理者権限を持たないユーザから実施する場合)でも、実際に`Condition`要素への条件を指定する例を紹介しています。

<br>

## 認証情報を定期的にローテーションする
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#rotate-credentials)の記載が端的にまとまっているので、そのまま引用します。

`パスワードとアクセスキーを定期的に変更し、アカウント内のすべての IAM ユーザーにも変更を促してください。そうすることにより、知らない間にパスワードまたはアクセスキーが漏れた場合でも、その認証情報を使ってお客様のリソースにアクセスされる期間を制限できます。`

上記のように、**ユーザのパスワードとアクセスキーを定期的に変更**してください

<br>

## 不要な認証情報の削除
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#remove-credentials)に記載の通り、長期間にわたって使用していないアクセスキーやパスワードはセキュリティホールの原因となるため、削除が推奨されます。

何をもって「使用していない」とするかは難しいところですが、調査には以下の「使用していない認証情報の検索」が役に立ちます

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_finding-unused.html

また、AWSにはポリシーやロールを自動作成するサービス(例:S3のレプリケーション設定)が多く、使用していないロールやポリシーが大量に溜まって管理が困難となるため、**使用していないリソースは定期的に削除**する事をお勧めします。

<br>

## AWSアカウントのアクティビティのモニタリング
セキュリティの基本として「**ログを取って後で調査できるようにする**」ことは重要です。

公式ドキュメントでは、以下のサービスによる取得が推奨されています。

|サービス名|ログ取得対象|
|---|---|
|Amazon CloudFront|CloudFront が受信したユーザーリクエストを記録|
|AWS CloudTrail|AWS APIコールおよび関連イベント|
|Amazon CloudWatch|AWS上のリソースおよび実行しているアプリケーションの動作を、定義したメトリクスに基づきモニタリング|
|AWS Config|IAMユーザー、ユーザーグループ、ロール、およびポリシーを含む、AWSリソースの設定に関する詳細な履歴情報|
|Amazon S3|AmazonS3バケットへのアクセスリクエスト|

取得方法は以下の公式ドキュメントを参照ください

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#keep-a-log


<br>
<br>

# IAM設定手順
ここからは実際のAWS画面（コンソール）において、IAMの設定手順を解説します。
[前述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamセキュリティのベストプラクティス)を満たしつつ、基本的な操作法を網羅できることを目指します。

## ユースケース
以下のような開発チームでAWSアカウントを運用する場合を考えます。

|名称|使用する権限|人数|
|---|---|---|
|IT管理者（兼支払管理者）|ルートユーザー＋管理者ユーザー|1名|
|開発責任者|パワーユーザー|1名|
|アプリ開発者|EC2, ELB, RDS, S3, VPCを個別付与|2名|

※以下の公式ドキュメントの構成を参考にしています

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/IAM_UseCases.html

[前述の通り](https://qiita.com/c60evaporator/items/0121399880625cc1de51#グループ)、権限（ポリシー）はユーザー単位でもグループ単位でも設定することができますが、今回は人数が増えても管理しやすい**グループ単位での管理**を実施する事とします。

設定は**以下の手順**で実施します

- [**ルートユーザーの設定**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ルートユーザーの設定)
- [**管理者ユーザーの作成**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成)
- [**パワーユーザーの作成**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#パワーユーザーの作成)
- [**アプリ開発者ユーザーの作成**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アプリ開発者ユーザーの作成)
- [**AWS内サービスへの権限付与**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws内サービスへの権限付与)
- [**AWSアカウント内での権限移譲**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#awsアカウント内での権限移譲)
- [**別のAWSアカウントへの権限移譲**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)
- [**AWS外アプリの権限設定**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws外アプリの権限設定)

**本設定手順に従えば、前述のベストプラクティスをあらかた網羅できること**を目指して設定を進めたいと思います。

## ルートユーザーの設定
まずはルートユーザーの設定を変更し、ベストプラクティスに基づいてセキュリティを強化します。

なお、本節の解説はAWSの登録とルートユーザの作成が完了した時点をスタートとしますが、完了していない方は[こちら](https://aws.amazon.com/jp/register-flow/)を参考にAWSの登録を実施してください。

### MFAの有効化
まずはGoogle AuthenticatorによるMFA(多要素認証)を有効にします。

AWSのコンソールにログインすると、左上に以下のような検索ボックスが出てくるので、「IAM」と検索します
<img width=600 alt="IAMの検索" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/721de167-dac9-df87-be71-15a4bb9838da.png">

「IAM」を選択するとIAMダッシュボードが表示され、以下のような「rootユーザーのMFAを追加する」という注意書きが出るかと思います。注意に従い「MFAの追加」をクリックします。
<img width=600 alt="rootユーザーのMFAを追加する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/745d5f47-6602-1562-5aaa-a6c8644a632f.png">

多要素認証（MFA） → MFAの有効化をクリックします
<img width=600 alt="多要素認証" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c3dfd68e-1346-e9e9-b4d7-5cfe33377296.png">

MFAデバイスにGoogle Authenticatorを使用する場合、「仮想MFAデバイス」を選択します
<img width=400 alt="仮想MFAデバイス" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/27b8ad93-7928-75a7-44d6-97a694a55194.png">

スマホに[Google Authenticator](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=ja&gl=US)をインストールし、[こちら](https://yattokoo.com/google-authenticator-setting)を参考に、AWS側の以下の画面に表示されているQRコードから2段階認証を登録し、アプリに表示されるワンタイムパスワードを2回連続（60秒で切り替わる）で以下の画面に入力します
<img width=600 alt="仮想MFAデバイスの設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/a7262eeb-f776-cf30-c2fd-adb278beff82.png">


### ルートユーザーのアクセスキー無効を確認
デフォルトではルートユーザーのアクセスキーは作成されないので、IAMダッシュボードに以下のように表示されていればOKです
<img width=600 alt="rootユーザーにアクティブなアクセスキーがありません" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5f811fc3-c228-02ed-a280-3bb0da265522.png">

### パスワードポリシーの設定
今後IAMユーザーを作成する際には、一緒にパスワードを設定します。
このパスワードに対して必須となるルールを設定します。

デフォルトでは以下の制限が適用されていますが、**組織のルールと適合性を確認しながら、適宜より厳しいルールを適用してください**

<img width=600 alt="パスワードポリシーを変更する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/dafc4bf0-ec31-8ef8-2ab5-41fb0c954953.png">



## 管理者ユーザーの作成
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ルートユーザー)、セキュリティリスクを抑えるためにはルートユーザーの使用頻度を極力抑えるべきです。
よってIT管理者であっても、日常的に使用するためのIAMユーザーである、管理者ユーザをルートユーザーとは別に作成する必要があります。

### 管理者ユーザーの作成
ルートユーザーでコンソールにログインした状態でIAMに入り、「ユーザー」→「ユーザーの追加」をクリックします

<img width=720 alt="ユーザーを追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/93b18999-f6da-03c1-19c6-84e9be9ae29f.png">

作成したい管理者ユーザー名を入力し、「アクセスキー - プログラムによるアクセス」「パスワード - AWSマネジメントコンソールへのアクセス」をチェックし、カスタムパスワードを入力します

<img width=720 alt="ユーザーを追加 画面" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/6dd1b385-c426-17bb-0c42-31c068937652.png">

※「アクセスキー - プログラムによるアクセス」をチェックすると、アクセスキーが有効になります。[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)、AWS外部のプログラムからAWSへのアクセスには多くの場合アクセスキーが必要となりますが、「外部から使わない」という場合は、**チェックしない方がセキュリティが強くなります**。管理者ユーザはかなり強い権限を持つため、**不要であればチェックしないことをお勧め**します）

※「パスワード - AWSマネジメントコンソールへのアクセス」をチェックすると、パスワードによるコンソールのアクセスが可能となります。チェックしなくとも[スイッチロール](https://qiita.com/c60evaporator/items/0121399880625cc1de51#スイッチロール)によるコンソールへのアクセス自体は可能ですが、イレギュラーな方法となるので基本的にはチェックしたほうが良いでしょう

※「パスワードのリセットが必要」をチェックすると、最初のログイン時にパスワードの再設定が必要となります。基本的にはユーザー作成者と実際の使用者が一致しない場合（後述のパワーユーザーや開発者ユーザーが該当します）にチェックします

### 管理者用グループの作成
以下のような画面が表示されますが、今回はグループ単位で権限を設定するので、「グループの作成」をクリックします
（ユーザー単位で権限を設定したい場合は「既存のポリシーを直接アタッチ」を使用します）
<img width=480 alt="グループを作成してユーザーを追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5d4f08c6-fbdb-dab4-cc96-06b6436513db.png">

管理者向けのポリシーとして、[ジョブ機能ごとに定義されたAWS管理ポリシー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ジョブ機能の管理ポリシー)である`AdministratorAccess`を選択します。

以下の手順で`AdministratorAccess`を選択し、「グループの作成」をクリックします
<img width=720 alt="AdministratorAccessのグループ作成" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/d30a10f6-e8a7-0f91-497d-e1d9b4c47766.png">

### 管理者ユーザーの作成（続き）
以下の画面に戻るので、「次のステップ」に進みます
<img width=600 alt="ユーザーをグループに追加 続き" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/8692aae8-60c6-e908-d79c-13872329ca86.png">

後々管理しやすいようNameタグを指定します（何も指定せず「次のステップ」へ進んでもOKです）
<img width=600 alt="管理者ユーザーのタグの追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3db373d4-8997-70d8-d480-a8462e98265f.png">

今まで指定した内容が確認できるので、問題なければ「ユーザーの作成」をクリックします。

作成が完了したら以下の画面が表示されます。シークレットキーはこのタイミングでしか確認できないので、アクセスキーを使用する場合は流出に気を付けつつ「表示」を押してメモしてください

![スクリーンショット 2022-05-08 2.59.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/923278be-d084-e040-1ac9-2f0a159304d2.png)

なお、作成したIAMユーザーでログインするためには、IAMダッシュボードに表示される以下赤塗り部分の「アカウントID」または「アカウントエイリアス」が必要となるのでご注意ください
![スクリーンショット 2022-05-08 3.06.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/7f5faac5-5d4a-2e63-1854-7d778fd49103.png)

ルートユーザーからログアウトし、ログイン画面にアカウントID、ユーザー名、パスワードを入力して作成したIAM管理者ユーザーにログインします
<img width=240 alt="IAMユーザーとしてサインイン" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/9e390c41-1109-ccad-a3b3-372538326b23.png">

### MFAの設定
管理者ユーザーにMFAを設定します。

IAMダッシュボードに移動すると、以下のような「MFAを自分用に追加」という注意書きが出るかと思います。注意に従い「MFAの追加」をクリックします。
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/a071b7e5-0ddd-6be1-d01d-10d522ab0a4e.png">

多要素認証（MFA） → MFAデバイスの割り当てをクリックします
<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/bd75afb3-c97f-83e7-09a9-fc7eb7ebfac0.png">

以降は[ルートユーザーのMFA設定](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの設定)の時と同様の手順で、MFAを適用してください



## パワーユーザーの作成
開発責任者が使用するパワーユーザーを作成します。

パワーユーザーはIAM以外のほぼ全てのサービスにフルアクセス可能な強い権限を持ったユーザーで、注意して管理しないとセキュリティリスクを高める原因にもなるので、不要であればより弱い権限を設定してください（本記事ではひとまずパワーユーザー権限を使用する前提で設定を進めます）

### パワーユーザーの作成
**IT管理者**が先ほど作成した管理者ユーザー（ルートユーザーではない）にログインしてIAMコンソールに入り、[管理者ユーザー作成時](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成-1)と同様の手順でパワーユーザーを作成します。

なお、管理ユーザー作成時との違いとして、
・作成者と使用者が異なるので、「パスワードのリセットが必要」をチェックしてください
・作成したパスワード、ユーザー名およびアカウントIDは初回ログインに使用するので、実際に使用するユーザー（今回は「開発責任者」）に伝えてください

<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/4547bcfa-87a8-7c6e-1c29-d7de280f3cb7.png">

### パワーユーザー用グループの作成
以下のような画面が表示されるので、「グループの作成」をクリックします
（ユーザー単位で権限を設定したい場合は「既存のポリシーを直接アタッチ」を使用します）
<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5d4f08c6-fbdb-dab4-cc96-06b6436513db.png">

管理者向けのロールとして、[ジョブ機能ごとに定義されたAWS管理ポリシー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ジョブ機能の管理ポリシー)である`PowerUserAccess`を選択します。

以下の手順で`PowerUserAccess`を選択し、「グループの作成」をクリックします
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/79aa9a96-affd-9d01-37a8-e3ae1f0565f6.png">

グループの作成が完了したら、[管理者ユーザーの時](https://qiita.com/c60evaporator/items/0121399880625cc1de51#管理者ユーザーの作成続き)と同様にNameタグを設定してユーザー作成を完了させます。

### パワーユーザーの初回ログイン
以降はIT管理者でなく**実際にパワーユーザーを使用する開発責任者**が行う作業となります。

先ほどIT管理者から伝えられたユーザー名、パスワード、アカウントIDを使用してAWSコンソールにログインすると以下のような画面が表示されるので、パスワードを再設定します。
<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/d3dd94ff-feed-b2e8-525f-9c4263f9db54.png">

### MFAの設定
パワーユーザーにMFAを設定します。

ですがこの設定、一筋縄ではいきません。
[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#iamユーザー-パワーユーザー)パワーユーザーはIAMの操作権限を持たないため、そのままではMFAを登録することができません。

**以下の記事のMFA設定用カスタマー管理ポリシーをパワーユーザに付与**したのち、**パワーユーザーを使用する本人にMFAを設定**してもらってください (MFA設定操作自体は[管理者ユーザの時](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの設定)と同様です)

https://dev.classmethod.jp/articles/iam-mfa-policy/

上記MFA設定用カスタマー管理ポリシーは、MFA設定後にパワーユーザから削除した方がセキュリティレベルが高まりますが、MFAの再設定が煩雑となるので削除するかどうかは各組織で判断してください。

## アプリ開発者ユーザーの作成
EC2, ELB, RDS, S3, VPCへのアクセス権限を持ったアプリ開発者ユーザーを作成します。
（実際は、使用するサービスに絞って与える権限を適宜変更してください）

### アプリ開発者ユーザー用ポリシーの作成
アプリ開発者ユーザーに適用するポリシーを**IT管理者が作成**します。

管理者ユーザーやパワーユーザーでは[ジョブ機能の管理ポリシー](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ジョブ機能の管理ポリシー)を使用して全サービス一括で権限設定しましたが、使用するサービスが限られた**アプリ開発者ユーザ**では、「[**最小限の特権を認める**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#最小限の特権を認める)」の原則に則って

-[**サービスごとのAWS管理ポリシー**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#サービスごとの管理ポリシー)
-[**カスタマー管理ポリシー**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ポリシーの分類)

のいずれかを**必要サービスに絞って**設定します。

**両者それぞれのポリシー作成方法**を解説します。

※ベストプラクティスの「[AWS管理ポリシーを使用したアクセス許可の使用開始](https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws管理ポリシーを使用したアクセス許可の使用開始)」の原則に従うと、慣れないうちはサービスごとのAWS管理ポリシーを使用した方が良さそうです
※同じくベストプラクティスの「[インラインポリシーではなくカスタマー管理ポリシーを使用する](https://qiita.com/c60evaporator/items/0121399880625cc1de51#インラインポリシーではなくカスタマー管理ポリシーを使用する)」に従うと、インラインポリシーは熟練者以外は使用を避けた方が良さそうです

#### 1. サービスごとのAWS管理ポリシーを設定する場合
デフォルト状態でAWS管理ポリシーが準備されているので、新たにポリシーを作成する必要はありません

#### 2. カスタマー管理ポリシーを作成する場合
管理者ユーザーでログインしてIAMコンソールに入り、左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0990bac4-640f-4e77-1c78-ba2fdeec3de7.png">

・サービス → EC2
・アクション → すべてのEC2アクション（権限を絞りたい場合（例:読取のみ）は適宜チェックを絞ってください）
を選択します
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/91e90224-e206-7c49-0ea0-f53847eaae0e.png">

・リソース → すべてのリソース（リソースを絞りたい場合は適宜選択してください）
・リクエスト条件 → チェック不要（MFAやリクエスト元IPにフィルタを掛けたい場合は適宜チェックしてください）
を選択します
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3479deed-297c-f586-896a-560cab15d601.png">

「さらにアクセス許可を追加する」をクリックし、EC2と同様にELB, RDS, S3も
・アクション → すべてのアクション（権限を絞りたい場合は適宜チェックを絞る）
・リソース → すべてのリソース（リソースを絞りたい場合は適宜選択）
・リクエスト条件 → チェック不要（MFAやリクエスト元IPにフィルタを掛けたい場合は適宜チェック）

を指定して追加してください(VPCはEC2アクションに権限が含まれるため追加不要)
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/1318ad85-5d6a-029f-c3ed-1760d816fb80.png">

「次のステップ: タグ」をクリックしてください
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3b33d54c-dc13-df2a-8fef-78acb7e8f407.png">

後々管理しやすいようNameタグを指定します（何も指定せず「次のステップ」へ進んでもOKです）
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/383ee295-2033-4d1d-b6b1-941828b135e9.png">

付けたいポリシー名と説明を入力し、「ポリシーの作成」をクリックします
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/eb1cd54a-3ac4-ff3d-17b3-27614754934f.png">

これでカスタマー管理ポリシーの作成完了です。


### ポリシーの検証
前節で「2.カスタマー管理ポリシーの作成」を選択した場合、ベストプラクティスにも記載された

-「[**アクセスレベルを使用して、IAMのアクセス許可を確認する**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスレベルを使用してiamのアクセス許可を確認する)」
-「[**IAMコンソールでのポリシーの検証**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-policy-validation.html)」

を実施する事で、アクセス権限が想定通り付与されているかや、文法等にミスがないかを確認できます。

IAMの左側のタブから「ポリシー」をクリックし、先ほど作成したポリシー名をクリックします
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/41c42775-8691-a6b5-b7a5-2b360bcb29a0.png">

「アクセス権限」タブでアクセスレベルを表示できます。これにより与えられた権限をわかりやすく一括確認することができます。
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/22b152f0-2d5d-65d2-332d-2380e7da5de7.png">

ポリシーの検証を実施したい場合はさらに「ポリシーの編集」をクリックします

「JSON」タブをクリックすると、下側のタブにエラーや注意事項がないかの検証結果が表示されます
※下の画面ではエラー等が発生しておらず、構文上は問題なく作成できた事が分かります
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ab87acac-fe69-835d-fd44-e35baa0ce448.png">

### アプリ開発者グループの作成
上記ポリシーを適用するグループを、**IT管理者が作成**します。

IAMの左側のタブから「User groups」 → 「グループを作成」をクリックします
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ea22c81b-a01a-8d5a-5240-e8a16b5bd758.png">

作成したいグループ名を入力します
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e0a9c507-7944-be17-c154-fab6a9fcda05.png">

ここからは先ほど「1.サービスごとの管理ポリシー」「2.カスタマー管理ポリシー」いずれを選択したかで処理が変わります

#### 1. サービスごとの管理ポリシーを設定する場合
以下のアクセスポリシーを検索して全てチェックします

・EC2のフルアクセスポリシー → AmazonEC2FullAccess
・ELBのフルアクセスポリシー → ElasticLoadBalancingFullAccess
・RDSのフルアクセスポリシー → AmazonRDSFullAccess
・S3のフルアクセスポリシー → AmazonS3FullAccess
・VPCのフルアクセスポリシー → AmazonVPCFullAccess

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/905be42f-1e9c-4c9c-5875-8e3c550e38c4.png">

#### 2. カスタマー管理ポリシーを設定する場合
[先ほど作成した](https://qiita.com/c60evaporator/items/0121399880625cc1de51#2-カスタマー管理ポリシーを作成する場合)カスタマー管理ポリシーを検索してチェックします
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/715190f1-5d36-b4cd-4730-88e7c3771fb2.png">

1と2いずれを選択した場合も、「グループを作成」をクリックしてグループ作成完了します
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/e5208e27-455c-b1ba-2a62-140da21e7b95.png">

### アプリ開発者ユーザーの作成
アプリ開発者ユーザを2名作成し、上記でポリシーを付与したグループに追加します。

IAMの左側のタブから「ユーザー」 → 「ユーザーを追加」をクリックします
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/1eafed2b-3fde-ff06-393e-55635a546518.png">

パワーユーザと同様に、以下を選択、実施してください
・作成者と使用者が異なるので、「パスワードのリセットが必要」をチェックしてください
・作成したパスワード、ユーザー名およびアカウントIDは初回ログインに使用するので、実際に使用するユーザー（今回は「アプリ開発者」）に伝えてください
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/f8e6fe21-03ed-fe04-17d7-e3c0ee9e43c8.png">

ユーザーを先ほど作成した開発者用のグループに追加します
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/26c6b440-6119-4ca7-e1ed-79c16f2db41b.png">

必要に応じてタグを追加し、確認画面を経て「ユーザの作成」をクリックすると、ユーザ作成が完了します。
同様に2人目の開発者ユーザーも作成します。


### アプリ開発者ユーザーの初回ログイン
以降はIT管理者でなく**実際にユーザーを使用するアプリ開発者が行う作業**となります。

先ほどIT管理者から伝えられたユーザー名、パスワード、アカウントIDを使用してAWSコンソールにログインし、パスワードを再設定します。

### MFAの設定
[ベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの有効化)に従うのであれば、アプリ開発者ユーザーにもMFAを設定すべきです。

ただし、管理者ユーザーやパワーユーザーと比べると権限をある程度絞っているので、実際にMFAを設定するかは利便性とのバランスを見て各組織で判断頂ければと思います。

MFAを設定する場合、[パワーユーザの時と同様](https://qiita.com/c60evaporator/items/0121399880625cc1de51#mfaの設定-1)にMFA設定用カスタマー管理ポリシーを付与してください。

## AWS内サービスへの権限付与
**サービスやアプリケーションからAWSへのアクセス権限を与える**方法には、「ロール」と「アクセスキー」の2通りが存在しますが、[前述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#アクセスキーによる認証)したように、**アクセス元がAWS内のサービスである場合は「ロール」が推奨**されます。

例えば、AWS内のアプリケーションからAWS内のリソースにアクセスする例として、以下のようにEC2上のPythonスクリプトからCSVファイルをS3にアップロードする例を考えてみます。

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/dfdaed5b-3af2-0bf2-b605-cd0c57c4fb27.png">
上記の処理を実現するためには、ロールを使ってEC2にS3へのアクセス権限を付与する必要があります。

具体的には
「**S3へのアクセス権を持つポリシーを付与したロールを作成し、EC2にロールをアタッチする**」
という処理を実行します。
以下手順を紹介します

### EC2インスタンスとS3バケットの作成
EC2インスタンスを作成します（デフォルト設定のAmazonLinux + t2.micro + キーペアありで大丈夫です）

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/058072a9-9155-d2cc-7b90-aa715b52409b.png">

S3バケットを作成します（こちらもデフォルト設定でOKです）

<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/9032a0b5-6347-ecb7-6d37-318b598a9e20.png">

### EC2へのPythonスクリプトの作成
EC2内にPythonスクリプトを作成します。例としてVSCode＋SSHでの作成例を紹介します。

まずは[こちら](https://qiita.com/c60evaporator/items/26ab9cfb9cd36facc8fd#vscodeのインストール)を参考にVSCodeとRemote Developmentをインストールしてください。

VSCodeを開き、以下の手順で`.ssh/config`を開きます
<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b7e8d7ef-6566-a26d-3769-05cb532c6517.png">

開いた`.ssh/config`に、以下の内容を記載します
```
Host [VSCode上での表示名]
  HostName [EC2のIPアドレス]
  User [EC2インスタンスユーザ名]
  IdentityFile [EC2のキーのパスを入力]
```
EC2インスタンスのIPアドレスはEC2の「インスタンス」コンソールの以下の位置に記載されています
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/af86a798-8d20-813a-9eed-1b9a9fcf7f6f.png">

例えば、以下のように記載します

```
Host ec2-test
  HostName ***.***.***.***
  User ec2-user
  IdentityFile ~/.ssh/key.pem
```
先ほどのSSH Targetsの画面に以下のように接続先が表示されるので、赤枠部分をクリックするとEC2にSSH接続されます

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/12fb444f-dd82-9f74-2dba-f02f16e2ffaf.png">

今回はseaborn, pandas, boto3という3つのPythonパッケージを使用します。Amazon Linuxにはおそらくインストールのためのパッケージ管理ツールpipが入っていないので、VSCodeのターミナルから

```bash
pip list
```

と打って見つかりません的なメッセージが返ってきたら、

```bash
sudo yum -y install python-pip
```

と打ち、pipをインストールします。ここから以下コマンドで、必要パッケージをインストールします

```bash
pip install seaborn pandas boto3
```

インストールが終わったらEC2内に適当な作業用フォルダを作成し、以下の操作で作成したフォルダを開きます

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/9c83c92a-0afe-20bb-d52f-2818ac035e3b.png">

開いたフォルダに以下のようなスクリプトを作成します。S3へのデータのアップロードには[boto3](https://aws.amazon.com/jp/sdk-for-python/)ライブラリを使用します

```python
import seaborn as sns
import pandas as pd
import boto3

# データセットを読み込んでEC2内に一旦CSV保存
iris = sns.load_dataset('iris')
iris.to_csv('iris.csv')
# S3にアップロード
s3 = boto3.resource('s3')
bucket = s3.Bucket('[S3のバケット名]')
bucket.upload_file('iris.csv', 'iris.csv')
os.remove('iris.csv')
```
上記を実行すると

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/16390773-9c75-604b-8b00-42fcb738c2cc.png">

という、クレデンシャル情報がありませんというエラーが出るかと思います。
これはEC2インスタンスにS3へのアクセス権限が与えられていないことに由来するため、**ロールを使用して権限を与える**必要があります。

### ロールの作成
S3にアクセスするためのロールを作成します。

IAMの左側のタブから「ロール」 → 「ロールを作成」をクリックします
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b58a4e56-134f-8b93-7be3-0e9db52640d3.png">
- 信頼されたエンティティタイプ → AWSのサービス
- ユースケース → EC2
を選択します。
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/f56a1606-b88c-2ff2-d1fe-46a8452d483d.png">

※「信頼されたエンティティタイプ」は、以下のように用途に合わせて選択します。今回のように同一アカウント内のAWSサービスに権限を与える場合は「AWSのサービス」を選択して直接権限をアタッチできますが、別アカウントやWebアイデンティティ、SAML2.0対応のサービスの場合[前述の信頼ポリシーとAssumeRole](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)を使用して権限を移譲します ([具体的な権限移譲法も後述](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)します)

|信頼されたエンティティタイプ (権限の付与先)|用途|
|---|---|
|AWSのサービス|同アカウントAWSサービスに権限を与えるとき|
|AWSアカウント|別アカウントのAWSユーザやサービスに権限を与えるとき (同アカウントも可)|
|ウェブアイデンティティ|Amazon,Facebook,Google などの OpenID Connect互換のIdPと連携して認証したいとき([参考](https://zenn.dev/mn87/articles/a0231e417a883e))|
|SAML2.0フェデレーション|SAMLシングルサインオンでAD等と連携して認証したいとき|

※「ユースケース」は、アクセス元のAWSのサービスに合わせて選択してください（EC2, Lambda以外はプルダウンで選択）

「S3」で検索し、`AmazonS3FullAccess`（S3へのフルアクセス）をチェックして「次へ」を押します
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/6c047581-2c94-3076-f14c-c7f3d9e95514.png">

ロール名と説明を記載し、「ロールを作成」をクリックするとロールの作成が完了します
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c90b9877-f8ce-0d9d-6c0a-80c0f04fab60.png">


### EC2へのロールのアタッチ
EC2インスタンスに作成したロールを付与します。

なお、ロールの付与には[前述の権限移譲に関する記事](https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/)でも登場したPassRole権限が必要となります。
PassRoleはIAM内の機能であるため、**デフォルト設定では管理者権限を持つユーザでないと実施できません**

ひとまず本節では管理者ユーザでロールを付与する前提で解説を進めますが、[後ほど](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ec2へのロールのアタッチ-管理者権限を持たないユーザから実施する場合)管理者権限を持たないユーザからロールを付与する場合も紹介します。

EC2ダッシュボードからEC2インスタンス画面に入り
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/90bcea14-b45b-8f2a-2004-19e615f40cc8.png">

対象のEC2インスタンスをチェックして「アクション」→「セキュリティ」→「IAMロールを変更」をクリックし
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5b488d37-3411-81ec-a285-cd78a7cd3cc2.png">

先ほど作成したロールを選択して「保存」を押すと、ロールのアタッチが完了します。

先ほどのEC2内のPythonスクリプトを再度実行し、エラーを出さずにS3にデータをアップロードできれば成功です。

### EC2へのロールのアタッチ (管理者権限を持たないユーザから実施する場合)
前述のように、デフォルト設定でははPassRole権限を持つ管理者ユーザでないとEC2へのロールのアタッチを実施できませんが、管理者ユーザ以外でも**PassRole権限を付与することによりロールのアタッチを実現できます**

以下の記事を参考に、パワーユーザにPassRole権限を付与し、EC2へのロールのアタッチを実行してみます。

https://www.ntt-tx.co.jp/column/211004/

まず、管理者ユーザーでログインしてIAMコンソールに入り、左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0990bac4-640f-4e77-1c78-ba2fdeec3de7.png">

「JSON」タブをクリックし、JSONでの編集モードに入ります

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c60cbcd6-dbf2-2a9d-1fac-57944eec2eaf.png">

以下のようなPassRole権限を持つポリシーを記述します
(例えば、`PassRoleToEC2`というポリシー名を付けます)

```json:作成するPassRoleToEC2ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPassRoleOnlyEC2",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::[アカウントIDの12桁数字]:role/*",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": [
                        "ec2.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Sid": "AllowListInstanceProfiles",
            "Effect": "Allow",
            "Action": "iam:ListInstanceProfiles",
            "Resource": "arn:aws:iam::[アカウントIDの12桁数字]:instance-profile/*"
        }
    ]
}
```
※上記ポリシーでは[前述のベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#追加セキュリティに対するポリシー条件を使用する)で登場した`Condition`要素によるアクセス条件の限定(PassRoleによるアタッチ対象をEC2に絞る)が行われています。

※PassRoleだけでなく、ロール一覧を表示するための`iam:ListInstanceProfiles`への権限も付与されています。これがないとEC2へのロールアタッチ時に対象ロールが表示されず、以下のようなエラーが発生します
<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b3adaa44-b96b-fe22-6d61-67b81fa7ae44.png">

名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です

作成したポリシーを以下のようにパワーユーザ用のグループ(あるいはユーザ)にアタッチすると、本来はPassRole権限を持たないパワーユーザからも、EC2へのロールアタッチが実行できるようになります
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/14960637-59d6-5c33-0ec6-c7b1d6036077.png">
<img width=540 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/545f9ecd-a2f2-bbff-7bbd-ef1b9de1b469.png">

PassRole権限はIAMの中でもよく使用する機能の一つなので、セキュリテイリスクを抑えつつ管理者以外のユーザでもPassRoleできるよう、上記のようなポリシーを準備しておくと便利です。


## AWSアカウント内での権限移譲
上例では**ポリシーを直接グループにアタッチ**することで、PassRole権限をパワーユーザに付与することができました。

同様の権限付与は、[前述の**AssumeRoleによる権限移譲**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#一時的に権限を付与する方法-権限移譲)によっても実現できます。
上例のように同アカウント内のユーザであれば、直接ポリシーをロールやユーザにアタッチできるので、わざわざ権限移譲する必要性は低いですが、練習や直接アタッチした場合との比較も兼ねて、PassRoleの権限移譲を実施してみます。

### 権限移譲の手順
少し複雑ですが、権限移譲は以下の手順で実施します

**1. 権限移譲用ロールの作成** (「権限を**渡す**側」の設定)
**2. 権限引受用ポリシーの作成** (「権限を**渡される**側」の設定)
**3. 権限引受用ポリシーのアイデンティティへの適用**
**4. スイッチロールの実行**

※手順1〜3はIAMへのアクセス権限を持ったアカウント(管理者アカウント等)で実施する必要があります。

以下詳説します

### 1. 権限移譲用のロール作成
**渡したい権限を記述したポリシーをアタッチ**した、**権限移譲用ロールを作成**します。

先ほどの通常の[「ロールの作成」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールの作成)と同様に、
IAMの左側のタブから「ロール」 → 「ロールを作成」をクリックします
<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b58a4e56-134f-8b93-7be3-0e9db52640d3.png">
- 信頼されたエンティティタイプ → AWSアカウント
- 別のAWSアカウント → このアカウント（同アカウント内のアイデンティティに権限移譲するため）
を選択します。

<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3e0d59a2-2138-b5e9-b96f-7851a75902ce.png">

[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールの作成)、信頼されたエンティティタイプに「AWSのサービス」以外が選択されているので、この時点でAssumeRoleが適用されます。

許可ポリシーに、先ほど作成したPassRole用およびEC2へのフルアクセス用ポリシーを指定します。

<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/9bfcad2b-0b05-6675-d87c-14b41640e264.png">

**※EC2へのフルアクセス用ポリシーも追加する理由**
後の手順で**スイッチロール**して権限移譲すると、**スイッチロール前のユーザが持っていた権限は失われて**しまいます。
今回のケースでは元のパワーユーザが持っていたEC2へのアクセス権限が失われるため、EC2を操作するためにPassRoleの権限だけでなくEC2へのフルアクセス権限も付与する必要があります。

以下の画面でロール名と説明を記載し、「ロールを作成」をクリックするとロールの作成が完了します
(AssumeRoleが適用されている事がここで確認できます)

<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/5be3a24d-871e-e3b3-a162-5f1118b61096.png">

作成したロールをIAMコンソールから以下のように選択し、ARNをメモします(引受用ロール作成時に使用します)

<img width=640 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/ed149ec7-325f-fdd7-1aea-5658c009a80f.png">


### 2. 権限引受用ポリシーの作成
権限を受け取るためのポリシーを作成します。

IAMコンソール左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/0990bac4-640f-4e77-1c78-ba2fdeec3de7.png">

「JSON」タブをクリックし、JSONでの編集モードに入ります

<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/c60cbcd6-dbf2-2a9d-1fac-57944eec2eaf.png">

以下のように、先ほど作成した権限移譲用ロールを引き受けるポリシーを記述します
(例えば、`AssumeRoleFromPassRoleEC2`というポリシー名を付けます)

```json:作成するAssumeRoleFromPassRoleEC2ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "先ほどメモした権限移譲用ロールのARN"
        }
    ]
}
```
名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です


### 3. 権限引受用ポリシーのアイデンティティへの適用
権限引受用ポリシーを、権限移譲先のアイデンティティ(ユーザ、グループ、ロール)にアタッチします。
今回はパワーユーザ用のグループにアタッチします。

以下のようにパワーユーザ用のグループ(あるいはユーザ)をIAMコンソールから選択し、「許可」→「アクセス許可を追加」→「ポリシーをアタッチ」を選択します
<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/14960637-59d6-5c33-0ec6-c7b1d6036077.png">

先ほど作成した権限引受用ポリシーを選択し、「アクセス許可を追加」をクリックします
<img width=600 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/9f6b80ae-1e65-fbee-8acb-80f5a757969d.png">

### 4. スイッチロールの実行
「スイッチロール」とは、[前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#スイッチロール)権限移譲用ロールを引き受けた仮想的なユーザでコンソールにログインすることを指します。
これにより、**移譲された権限を保持した状態でコンソールを操作**する事ができます。
([前述のように](https://qiita.com/c60evaporator/items/0121399880625cc1de51#1-権限移譲用のロール作成)、**スイッチ前の権限は消えてしまう**ことにご注意ください)

まずは、[手順3](https://qiita.com/c60evaporator/items/0121399880625cc1de51#3-権限引受用ポリシーのアイデンティティへの適用)で権限を引き受けたユーザでログインし、コンソール右上のユーザ名をクリックして、「ロールの切り替え」を選択します

<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2dba6939-78ab-f22a-84ea-b6f0affea55b.png">

アカウントIDと権限移譲用ロールの名称を記載し、「ロールの切り替え」をクリックします。

<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/bd7b6cb6-2b7d-91c0-eff7-4551e4d8d478.png">

スイッチしたユーザで、[前述の「EC2へのロールのアタッチ」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ec2へのロールのアタッチ)が実行できれば権限移譲成功です。
(本来パワーユーザーに実行できないロールのアタッチが、権限移譲により実行できるようになった)

なお、スイッチロール前のユーザに戻るにはコンソール右上のユーザ名から「スイッチバック」を選択します
<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/b0217504-23e9-e5f3-b028-5ff06a93d0f2.png">



## 別のAWSアカウントへの権限移譲
**権限移譲**を利用することで、**別アカウントのAWSユーザやアプリケーション**に、**自アカウントのAWSリソースへのアクセス権限を付与**する事ができます。

これにより複数アカウント間でリソースを共有できるため、**複数組織を跨いだ開発の利便性**をUPさせられます

### 権限移譲の手順
権限移譲は以下の手順で実施します

**1. 権限移譲用ロールの作成** → 「権限を**渡す**側」のアカウントの管理者ユーザが実施
**2. 権限引受用ポリシーの作成** → 「権限を**渡される**側」のアカウントの管理者ユーザが実施
**3. 権限引受用ポリシーのアイデンティティへの適用** → 「権限を**渡される**側」のアカウントの管理者ユーザが実施
**4. スイッチロールの実行** → 実際に**権限を移譲されるユーザ**(またはアプリケーション)が実施

詳細手順は先ほどの「**AWSアカウント内での権限移譲**」とほぼ同様のため、**差分に絞って解説**します


### 1. 権限移譲用のロール作成
「権限を**渡す**側」のアカウントの管理者ユーザが実施します。

基本的には前述の[AWSアカウント内での「1. 権限移譲用のロール作成」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#1-権限移譲用のロール作成)と同様の手順で実施しますが、「信頼されたエンティティを選択」時に以下のように「別のAWSアカウント」→権限移譲先のアカウントIDを入力する必要があります。

<img width=720 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/86249200-e5ae-b89d-d008-a3c1e6710266.png">

なお、ここで指定した権限移譲先のアカウントIDは、信頼ポリシーの`Principal`フィールドに記載されます。
ここから、**信頼ポリシーで権限を移譲する先**を[**Principal要素**](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_principal.html)で指定している事が分かります。


### 2. 権限引受用ポリシーの作成
「権限を**渡される**側」のアカウントの管理者ユーザが実施します。

基本的には前述の[AWSアカウント内での「2. 権限引受用ポリシーの作成」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#2-権限引受用ポリシーの作成)と同様の手順で実施してください。

### 3. 権限引受用ポリシーのアイデンティティへの適用
「権限を**渡される**側」のアカウントの管理者ユーザが実施が実施します。

基本的には前述の[AWSアカウント内での「3. 権限引受用ポリシーのアイデンティティへの適用」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#3-権限引受用ポリシーのアイデンティティへの適用)と同様の手順で実施してください。

### 4. スイッチロールの実行
実際に**権限を移譲されるユーザ**(またはアプリケーション)が実施します。

基本的には前述の[AWSアカウント内での「4. スイッチロールの実行」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#4-スイッチロールの実行)と同様の手順で実施しますが、「ロールの切り替え」画面の「アカウント」には「権限を**渡す**側」アカウントのアカウントIDを入力する必要が分かります。

<img width=480 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/325ba221-cedb-2aaa-61de-4dd434b6b840.png">

上記操作により、別アカウントのロールを使用してコンソールにログインできてしまいます。

権限移譲はアカウント間を跨げる非常に自由度の高い機能です。
あくまで「一時的な権限の付与」を想定した機能ではありますが、[ベストプラクティス](https://qiita.com/c60evaporator/items/0121399880625cc1de51#ロールを使用してアクセス許可を委任する)ではアクセスキーよりも使用の推奨度が高いため、使用できる場面では**積極活用**していきましょう


## AWS外アプリの権限設定
AWS外のアプリにAWS内のリソースへのアクセス権限を付与する方法を考えます。

前述の[**SAMLやウェブアイデンティティに対応したアプリケーション**](https://qiita.com/c60evaporator/items/0121399880625cc1de51#権限を移譲できる対象)であれば、[前述の「別のAWSアカウントへの権限移譲」](https://qiita.com/c60evaporator/items/0121399880625cc1de51#別のawsアカウントへの権限移譲)と同様、**権限移譲によるアクセス権限の付与**が推奨されます。

上記が使用できない場合、**アクセスキーによる権限付与**を実施します。
実例があった方が分かりやすいと思うので、アクセスキーを使用してPythonのライブラリ[MLflow](https://mlflow.org/)にS3へのアクセス権限を与えた例のリンクを下記します。

https://qiita.com/c60evaporator/items/e1fd57a0263a19b629d1#awsのアクセス権限設定