はじめに
AWSのアクセス制御サービスであるIAMについて、2022年7月時点での機能および使用法を、初学者でも理解しやすいことを心掛けてまとめました。
IAMをよく分からないまま適当に設定するとセキュリティ的にまずいので、これを機に設定を見直して頂き、セキュリティレベル向上に貢献できれば幸いです。
特に、後述するIAM設定手順は、AWSに登録して最初に実施すべき設定に相当するため、セキュリティに興味がなくとも一度は実施することをお勧めします。
また公式のベストプラクティスは丁寧にまとめたつもりなので、初学者以外でもAWSのセキュリティ確保に興味がある方は、ぜひご一読頂けると嬉しいです。
IAMとは
「Identity and Access Management」の略です。
公式ドキュメントによると、IAMは「誰」が「どのAWSのサービスやリソース」に「どのような条件」でアクセスできるかを指定できるサービスです。
同様に以下のAWS公式概念図では、"Who"(誰), "Can access"(アクセス条件), "What"(サービスやリソース) の3要件が提示されており、本記事でもこの3要件に則って解説を進めます
IAMはAWSのセキュリティ確保において不可欠な仕組みであり、知らずに使っているとセキュリティリスクを増大させる事も多いサービスのため、クラウド利用において最初に学ぶべき分野の一つと言えます。
※セキュリティ的にまずい使用例は、以下の方が丁寧にまとめられています
AWSにおけるセキュリティサービス
IAM以外にも、AWSにはセキュリティに関係したサービスが多く存在します。
その中でのIAMの位置付けを考えてみます。
セキュリティの3要素
セキュリティ対策で求められる要件として、一般的に以下の3種類が挙げられます(英語での頭文字を取ってCIA
と呼ばれます)
- 機密性 → 許可されたものだけが情報にアクセスできる
- 完全性 → 情報の改ざん、欠落が起こらない
- 可用性 → 必要なときにいつでもサービスが提供されている
この中でも機密性を確保するためには、許可されていないアクセスを遮断するアクセス制御が必要となります。
ネットワークとホスト
アクセス制御は対策が行われる位置に応じて、以下のように分類されます。
- ネットワーク上でのアクセス制御 → ネットワーク経路上でアクセスを制限
- ホスト上でのアクセス制御 → ホスト(PCやサーバ)上の情報資産に対するアクセスを制限
AWSのようなクラウドにおいて「ホスト」はEC2を始めとした仮想サーバ(VM)の事を表しており、サーバ上で動作するSaaSのような多くのサービスや、サーバ上に保存されるS3のデータのようなリソースも、ホスト上でのアクセス制御と同様の仕組みで管理されることが多いです。
IAMもこのホスト上でのアクセス制御を設定するサービスに該当します。
認証と認可
アクセス制御は、一般的に以下の2手順で実施されます
- 認証 → アクセスしたのが「誰」であるかを識別する
- 認可 → 識別した「誰」に「どの情報資産」を「どのような条件」でアクセスを許可するか、ルールに基づき決定する
認可の「誰」に「どの情報資産」を「どのような条件」でアクセスを許可するか
の部分は、IAMのサービスの定義と非常に近い事がわかります。
以上から明らかなように、IAMは認可のルールを定めるためのサービスとなります。
IAMの位置付け
以上まとめるとIAMは
機密性
確保のためにホスト(サービス、リソース)
における認可
を実行するサービス
と位置付けることができます。
AWSの主なセキュリティサービス一覧
参考までに、AWS各種セキュリティサービスの分類を下表に一覧化しました
(分類には筆者の主観が入っていることをご容赦ください)
サービス名 | 3要素 | ネットワーク or ホスト | 認証, 認可 or 暗号化 | 概要 |
---|---|---|---|---|
IAM | 機密性 | ホスト | 認可 | 各種AWSリソースへのアクセス認可を管理する |
Resource Access Manager | 機密性 | ホスト | 認可 | 複数AWSアカウントのリソース共有を管理する |
Organizations | 機密性 | ホスト | 認可 | 複数AWSアカウントの請求情報やSCP(複数アカウントへのアクセス制限設定)を一括管理する |
KMS | 機密性, 完全性 | ホスト | 認証, 暗号化 | 暗号化や認証に使用する鍵を管理する |
Certificate Manager | 機密性 | ホスト | 認証 | サーバ・クライアント認証に使用する公開鍵証明書を管理する |
Directory Service | 機密性 | ホスト | 認証 | Microsoft Active Directory(AD)による認証管理をAWS上で実現&オンプレADとの連携 |
Single Sign-On | 機密性 | ホスト | 認証 | 複数のAWS アカウントやアプリケーションへの認証情報を一元管理する |
Cognito | 機密性 | ホスト | 認証 | Webアプリおよびモバイルアプリへの認証情報を一元管理する |
Network Firewall | 機密性 | ネットワーク | 認可 | サブネットに対するアクセスルールを設定する |
WAF | 機密性 | ネットワーク | - | Webアプリに対する一般的な攻撃パターンをブロックする |
Cloud Front | 可用性 | ネットワーク | - | CDNによるアクセス速度向上と過負荷防止 |
※上表は独立したサービスのみを記載していますが、VPCのセキュリティグループやS3のバケット暗号化等、各サービス内にも重要なセキュリティ機能が実装されています
※上表ではIAMを"Who"に対してアクセス権限を与える認可サービスとして定義しましたが、実際には"Who"が正しいかどうかを判定(なりすまし防止)する認証を強化する機能(MFA等)も一部含まれています。
※ホストの機密性確保という観点で類似するSingle Sign-OnとCognitoは、IAMと密接に関わっています。前者は後述のSAML2.0による認証、後者はウェブアイデンティティによる認証等、AWS以外の認証情報との連携には両者の利用が不可欠です。
上記のようにまとめてみると、認証に関連したサービスが多く、これらのサービスで得られた認証情報を元に認可を付与するサービスはIAMにほぼ一本化されている(Resource Access ManagerやOrganizationsもIAMの延長線上の1機能)という意味で、AWSのセキュリティにおけるIAMの重要性が非常に高いことが分かります。
IAMの仕組み
前述のようにIAMは、「誰」(Who)が「どのAWSのサービスやリソース」(What)に「どのような条件」(Can access)でアクセスできるかを管理するためのシステムです。
具体的には、以下の2種類の要素(プリンシパルとポリシー)を設定する事で、この管理を実現します
- 「誰」(Who)の管理 → プリンシパル
- 「対象サービス」(What),「条件」(Can access)の管理 → ポリシー
プリンシパルとポリシーについて詳細を解説します。
"Who"の管理 (プリンシパル)
アクセスの主体となる「誰」(Who)を、AWSではプリンシパルと呼びます。
プリンシパルを管理するための構成要素をIAMエンティティ (あるいは単にエンティティ)と呼び、以下のように分類されます。
名称 | 使用する場面 |
---|---|
ユーザー | アクセス主体が人(アカウント)のとき |
ロール | アクセス主体がサービス(アプリケーション)のとき |
また、複数のユーザーをまとめて管理しやすくしたものをグループと呼びます。
これら「ユーザー」、「ロール」、「グループ」の3つをまとめてIAMアイデンティティ (あるいは単にアイデンティティ)と呼びます。
※「プリンシパル」「IAMエンティティ」「IAMアイデンティティ」は紛らわしいですが、いずれも「誰」を表す構成要素をまとめた呼び方となります。参考までに、各種別に含まれる対象を下記します。
ユーザー | ロール | グループ | |
---|---|---|---|
プリンシパル | ○ | ○ | ○ |
IAMエンティティ | ○ (ルートユーザー以外) | ○ | × |
IAMアイデンティティ | ○ (ルートユーザー以外) | ○ | ○ |
これら「ユーザー」、「ロール」、「グループ」の概要について、以下で解説します。
ユーザー
アクセス主体である"Who"が人のとき、これを定義する基本単位です。
基本的にはAWS上で作成したアカウントと紐付きます
ユーザーは
- ルートユーザー
- IAMユーザー
に分けられ、IAMユーザーは大まかに以下のように分類できます。
- 管理者ユーザー
- パワーユーザー
- 個別に権限付与するユーザー
以上まとめると以下のようになります。
課金情報等へのアクセス | IAM操作権限 | 各種AWSサービスへのアクセス | 想定される職責 | |
---|---|---|---|---|
ルートユーザー | ○ | ○ | ○ | IT管理者 |
管理者ユーザー | × | ○ | ○ | IT管理者 |
パワーユーザー | × | × | ○ | 開発責任者、多数のサービスを利用する開発者 |
個別に権限付与するユーザー | × | × | △ (個々に設定) | 開発者 |
ユーザーを登録する際はこれら大まかな分類をまず定めたのち、細かなアクセス権限(例:その他のユーザーへの各種AWSサービス権限付与)をポリシにより逐次設定していきます。
以下、各ユーザー分類の概要を解説します。
・ルートユーザー
AWSへの最初の登録時に作成されるユーザーであり、最も強い権限を持っています。
全てのAWSサービスとリソースにアクセス可能であることに加え、IAMユーザーにはない以下の権限を持ちます。
- IAMユーザへの課金情報アクセス権限付与
- 複数アカウント請求情報の統合
- AWSアカウントの停止
- 逆引きDNS申請、ドメイン登録の移行
お金に関する情報へのアクセスやアカウントの停止、ドメイン登録の操作ができるため、乗っ取られるとトンデモない事になってしまいます。
このようなリスクを防ぐため、ルートユーザーを日常的な開発に使用することは推奨されません
個人開発であっても、管理用のIAMユーザー(管理者ユーザー)を作成し、こちらを日常的に使用した方が良いでしょう
・IAMユーザー (管理者ユーザー)
IAM自身の操作権限を持つユーザーです。
後述のAdministratorAccess
と呼ばれるポリシーを付与する事で作成できます。
前述のように、IAMを操作すればアクセス権限を自由に付与する事ができるため、管理者ユーザーは
「認可に関しては万能の存在」
となることができます。よって不必要に増やすとセキュリティリスクが増えることから、管理者ユーザーの数は必要最小限に絞ることが望ましいです。
(後述のベストプラクティスにおける「最小限の特権を認める」に相当)
組織においては、組織内のAWSアカウントを統括するIT管理者を管理者ユーザーとすることが一般的です。
・IAMユーザー (パワーユーザー)
管理者ユーザーとの差はIAM自身の操作権限を持たない事で、IAM以外の大半のサービスへのアクセス権限を持つユーザーです。
後述のPowerUserAccess
と呼ばれるポリシーを付与する事で作成できます。
元々はこちらの記事で言及されているように、セキュリティと利便性(サービスを利用するたびに逐一権限付与するのは手間が掛かる)のバランスを取るために誕生したユーザーですが、強い権限を持つ事には変わらず、むやみにパワーユーザーの数を増やす事は推奨されません。
組織においては、開発を統括する責任者や多くのサービスを継続的に利用する開発者に付与されることが多いですが、セキュリティリスクのあるパワーユーザーを置かずに、後述の「個別に権限付与するユーザ」のみを使用することも多いです。
・IAMユーザー(個別に権限付与するユーザー)
後述のベストプラクティスに「最小限の特権を認める」という項目があることから分かるように、セキュリティを高めるためには必要な権限のみを付与する事が有効です。
よって管理者やパワーユーザー等の特殊なユーザーを除くと、AWSのユーザには使用するサービスの権限(EC2, S3等へのアクセス権限)を個別に付与する事が一般的です。
権限を付与するためには、後述の「サービスごとの管理ポリシー」を必要に応じて複数選択し、ユーザー(またはグループ)にアタッチします。
なお、上記のように複数の「サービスごとの管理ポリシー」を個々に付与する方法では、サービス数が増えた際に管理が煩雑となってしまいます。そこで「ネットワーク管理者」「データサイエンティスト」等の職責を想定し、必要な複数サービスへの権限を一括付与できる
「ジョブ機能のポリシー」
という仕組みも、AWS側が用意してくれています(詳細は後述)
グループ
組織が大きくなると、全てのIAMユーザーの権限を個々に管理するのは大変です。
そこで同じ権限を持つ複数のIAMユーザーをまとめて管理できる仕組みが、グループです。
グループに設定された権限は、グループに所属する全てのIAMユーザーに適用されます。
例えば、パワーユーザー用ポリシーを付与したグループを作成すれば、このグループに所属させたユーザーは全てパワーユーザーとなるため、個別のユーザーにポリシーを付与する手間が省け、管理の複雑さやそれに伴う設定ミスを防ぐ事が出来ます。
設定ミスはセキュリティリスクの主要因の一つなので、チームでの運用時はグループを積極的に活用する事をお勧めします (後述のIAM設定手順でもグループを使用して権限付与します)
ロール
AWS上でアプリケーションを動作させる場合、ユーザーが直接寄与する事なくあるサービスから他のサービスへのアクセスが生じることがあります。
例えばEC2上のプログラムで出力されたデータをS3に保存する場合、「EC2 → S3への書き込み権限」が必要となります。
このようにサービスから他のサービスへのアクセスが生じる際に、アクセス元のサービス(上例でのEC2)に権限を付与するための仕組みを、ロールと呼びます。
ロールもユーザーやグループと同様にポリシーを付与してアクセス権限を与える事ができますが、ユーザーやグループとは異なりアクセス権限の主体が人ではなくサービスであることにご注意ください。
"Can access", "What"の管理 (ポリシー)
アクセス権限を適用する「対象サービス」(What)と「アクセス条件」(Can access)の管理をするのが、ポリシーです
ポリシーの分類
ポリシーは以下のように、管理ポリシーとインラインポリシーに分類できます。
- 管理ポリシー → スタンドアロン(ユーザーやロールとは別個に作成する)ポリシー
- インラインポリシー → 1つのアイデンティティ(ユーザー、ロール、グループ)に埋め込まれたポリシー
上記だけでは分かりづらいですが、管理ポリシーは「複数のユーザーやグループ、ロール(アイデンティティ)で使い回し」できるのに対し、インラインポリシーはアイデンティティと1対1で紐づいているため、使い回しできない事が最大の差となります
管理ポリシーはさらに、以下の2種類に分類できます
- AWS管理ポリシー → AWSがデフォルトで準備しているIAM管理ポリシー
- カスタマー管理ポリシー → 利用者が独自に作成、管理する管理ポリシー
以上のように、ポリシーには「AWS管理ポリシー」、「カスタマー管理ポリシー」 、「インラインポリシー」の3種類が存在します。
使用するポリシーの優先順位
後述のベストプラクティスでは、
AWS管理ポリシーを使用 → 必要に応じてカスタマー管理ポリシーを追加
の順で選択・運用する事が推奨されています (インラインポリシーは推奨度低)
選択方法の詳細は後述のベストプラクティスおよびIAM設定手順を参照ください
AWS管理ポリシーの概要
第一の選択肢として利用が推奨されるAWS管理ポリシーですが、実際の選択画面は以下のようになっています。
大きく分けると、「タイプ」の列の内容に合わせて
- ジョブ機能の管理ポリシー
- サービスごとの管理ポリシー
の2種類に分類されます。
・ジョブ機能の管理ポリシー
ジョブ機能の管理ポリシーは前述の職責ごとに割り振られた管理ポリシーであり、管理者ユーザー用のAdministratorAccess
やパワーユーザー用のPowerUserAccess
を始めとし、職責に応じて複数のサービスをまとめた管理ポリシーが定められています。
指定できる職責は以下のページでまとめられているので、これらジョブ機能の職責に該当する開発者(一般的には多くのサービスにアクセスするメイン開発者が該当)となるユーザーはこちらを参考にポリシーを選択すると良いでしょう。
なお、ベストプラクティス的には最小限の特権を詳細設定できる「サービスごとの管理ポリシー」の方が望ましいので、どちらを選択するかはセキュリティと利便性のバランスを見て判断してください。
・サービスごとの管理ポリシー
サービスごとの管理ポリシーは、AWSのサービスごとに書込、読取などの権限を個別設定できるポリシーです。
前述の「個別に権限付与するユーザー」に相当する一般ユーザーは、特権を最小限にする原則に基づいてこちらを選択するのが良いでしょう。
ポリシーの構造
上記3種類のポリシーはいずれも、JSONファイルで記述されています。
例えば、S3の読取のみが許可されるAWS管理ポリシー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設定手順」ではGUIでの作成方法を紹介します)
また、JSONからの作成方法として、以下のサイトでAWS管理ポリシーをベースにカスタマー管理ポリシーを作成する方法を分かりやすく紹介されています、
例外的なポリシー
今まで解説した内容は
- IAMは「誰」(プリンシパル/アイデンティティ)が「どのAWSのサービスやリソース」に「どのような条件」(ポリシー)でアクセスできるかを管理
- 上記アクセス制御を、ポリシーをプリンシパルに付与する事で実現
- アクセス主体が人なら「ユーザー」、アクセス主体がサービスやアプリケーションなら「ロール」
を前提としていましたが、これらが成り立たない例外的なポリシーも存在するので、解説します。
特に「バケットポリシー」や「信頼ポリシー」は例外と呼ぶのがはばかられるほどよく使用されるので、覚えておいて損はないかと思います。
リソースベースのポリシー
ここまで解説したように、IAMでは通常、アクセスする側であるプリンシパル (アイデンティティ)にポリシーを付与する事でアクセス制御を実現します。この方法を「アイデンティティベースのポリシー」と呼びます
一方で一部サービスには、アクセスされる側である「リソース」を主体としてアクセス権限を設定する「リソースベースのポリシー」という手法も存在します。
例えばS3のバケットには、独自のリソースベースのポリシー(バケットポリシー)を設定する事ができます。これにより、アクセスされる側であるバケットへのアクセス制御を実現する事ができます。
リソースベースのポリシーは使用できるサービス(S3、SQS、VPC等)が限られていますが、特定のリソース(例:S3内の特定のバケットに保存された機密データ)のセキュリティを選択的に高めたい場合に役立つでしょう。
なお、公式ドキュメントによるとアイデンティティベースとリソースベース両方のポリシーが設定された場合、両方のポリシーで許可されている主体のみがアクセスを許可されるようです。
上記のようにAND条件で厳しくアクセス条件を縛ることで、S3等のサービスでは強固なセキュリティを実現する事ができます。
信頼ポリシー
リソースベースのポリシーの一種としてよく使用されるものに信頼ポリシーが挙げられます。
信頼ポリシーはコンソール上では信頼関係とも呼ばれ、このポリシーを使用する事で、あるロールが持っている権限を他のプリンシパル(ユーザー、グループ、ロール)に移譲することができます
先ほど「ロールはアクセス主体がサービスやアプリケーションの場合に使用される」と述べましたが、信頼ポリシーによるロール権限移譲は、移譲先が人(ユーザー、グループ)であってもサービスであっても実施可能で、主に移譲元ロールとは別のAWSアカウント、またはAWS外のSSO対応サービスへの権限移譲に用いられます。
・信頼ポリシーを意識する必要がある場面
ロールをAWSサービスに付与する際は基本的に信頼ポリシーが必要となりますが、EC2やLambda等の主要サービスではロール作成時のユースケース選択に応じて自動で信頼ポリシーが付与されるため、意識する必要性は低いです。
意識する必要がある (手動設定が必要な)場面の代表例として、後述の一時的に権限を付与する場合や、以下のVPCフローログ (自動付与されるユースケースに含まれないサービス)の例が参考になるかと思います
Perminssions boundary (アクセス許可境界)
通常のIAMでの権限設定(下図のIdentity-based policy)に加えて、Permissions boundaryと呼ばれるサービスにポリシーを設定することで、IAMで付与できる権限に制限を設ける事ができます。
Permissions boundaryを設定すると、上図で示されたように
- 通常のIAMでの権限設定
- Permissions boundaryで設定したアクセス許可境界
- 組織側で設定したアクセス許可境界であるSCP(AWS Organizationsサービスで設定可能)
の全てで共通して設定された権限のみが、実際に付与される権限となります。
(上のベン図で全てが重なった部分のみ権限が付与される)
これらPermissions boundary, SCPによる制限は、権限を付与したくないサービスに誤って権限が付与されることを防いだり、各アカウントで付与できる権限を組織側からコントロールすることを主な目的として使用されるようです。
アクセスキーによる認証
Pythonのようなプログラム言語で書かれたアプリケーションからAWSのサービスにアクセスしたい場合、アプリケーションの動作場所がEC2のようなAWSサービス、あるいはウェブアイデンティティやSAML2.0に対応したサービスの場合、後述のロールと権限移譲によるアクセス権限の付与が推奨されています。
(2022/7以降は後述のIAM Roles Anywhereも選択肢に追加)
一方で上記に該当しない場合(例:オンプレサーバ上で動作するアプリケーション)、ロールによるアクセス権限の付与は困難です。
このようなロール非対応のアプリケーションから、AWSリソースへのアクセスを実現する方法がアクセスキーです。
IAMユーザーに紐づいたアクセスキーをAWS側で発行し、プログラムが動作するデバイスに保持することで、アクセス主体がプログラムの場合でも「ユーザー」と同様の認証情報を使用する事ができます。
アクセス主体がプログラム(アプリケーション)であるという点で、「アクセスキー」と「ロール」は紛らわしいですが、前者はAWS外部のプログラム、後者はAWS内のサービスを主に対象にしています(前述の記事でも触れられていますが、AWSサービス内からアクセスキーを使用することは推奨されません)
アクセスキーはIDとシークレットから構成され、この両者をプログラム側からAWSに提供することで、認証が成立します。シークレットは作成時にしか閲覧・ダウンロードできないので、忘れてしまったら再度アクセスキーを作成し直す必要があります(これによりセキュリティを確保しているとも言えます)
アクセスキーは便利な機能ですが、通常の認証をすっ飛ばすセキュリティリスクの塊と言える存在でもあるため、取り扱いに注意が必要です。
例えばGitHubにアップロードしてしまうと、以下のような恐怖体験を味わう事ができます
以下のAWS公式にベストプラクティスが記載されているので、使用前に一読をお勧めします。
一時的に権限を付与する方法 (権限移譲)
IAMで特に理解が難しいのがこの部分です。
後述のベストプラクティスには「一時的な権限の付与にはアクセスキーでなくロールを使うべき」と記載されていますが、ロールを簡単に付与できる同アカウントのAWSサービス以外では、
「何使えばええねん!」
と思って公式ドキュメントや他のWebページを検索し、以下のように多数のサービスの名前がヒットし、混乱して使用を諦めた方も多くいるでしょう
- 信頼ポリシー(信頼関係)
- AssumeRole
- STS
実際には上記を組み合わせることで権限移譲を実現できるので、相互関係を整理する事でイメージが掴めるかと思います。
以下の記事が非常に分かりやすいので、リンクを貼らせていただきます
権限を移譲できる対象
上記の信頼ポリシー+AssumeRole+STSを組み合わせて権限移譲用のロールを作成することで、様々なユーザやサービスに権限を移譲する事ができます。
詳しくは後述の「IAM設定手順」で解説しますが、現状のAWSコンソールからは大きく分けて以下の3種類の対象に権限を移譲する事ができます
権限の移譲先 | AWSコンソールからの指定方法 (後述) |
---|---|
同アカウントor別アカウントのAWSユーザやサービス | AWSアカウント |
Amazon,Facebook,GoogleなどのOpenID Connect互換のIdPと連携して認証したいとき(参考) | ウェブアイデンティティ |
SAMLシングルサインオンでAD等と連携して認証したいとき | SAML2.0フェデレーション |
IAM Roles Anywhere
上記3種類の対象以外にも、一時的なAWSアクセス権限を公開鍵証明証に渡す、IAM Roles Anywhereという機能が、2022/7に追加されました。
今まではセキュリティリスクのあるアクセスキーを使用せざるを得なかった用途の一部で、IAM Roles Anywhereを使用する事で一時的な権限付与を実現する事ができ、ベストプラクティスに則った運用が可能となります。
詳細は以下の記事を参照下さい。
スイッチロール
上記の権限移譲用ロールを付与した仮想的なユーザで、AWSコンソール上でログインする事ができます。
この仕組みを「スイッチロール」と呼び、対象ユーザが本来権限を持たないサービスにアクセスしたい時、一時的に権限を付与したい場合に便利です。
具体的な方法は後述の「IAM設定手順」で解説します。
IAMコンソール画面の見方
AWSコンソールにログインしてIAMのサービスに入ると、以下のような画面が表示されます。
IAMの操作は基本的に上図の「左側のタブ」(ナビゲーションペイン)と「IAMダッシュボード」を使用するため、それぞれ簡単に解説します
左側のタブ(ナビゲーションペイン)
前述したIAMの基本構成要素であるユーザー、グループ、ロール、ポリシーを中心とした、各種リソースの管理画面に移動できるタブです
User groups
グループの作成や、許可するポリシー、所属するユーザー等を管理する画面です。
ユーザー
ユーザーの作成や、許可するポリシー、所属するグループ、認証情報等を管理する画面です
ロール
ロールの作成や、信頼ポリシーの設定等を管理する画面です。
ポリシー
ポリシーの作成や、ポリシーが許可されたグループ、ユーザー等を管理する画面です。
IDプロバイダ
AWS外の認証情報(WindowsのActive Directory等)と紐づけるためのシングルサインオン情報を管理する画面です
アカウント設定
パスワードポリシーやAWS STSを管理する画面です
Access Analyzer
アクセスアナライザーは、後述のポリシーの検証やアクセス監視に使用されるツールで、端的に言うと外部からアクセスできる状態となっているリソースがないか検知する機能を持ちます。
具体的には、以下のリソースが検知の対象となります。
- S3 (ブロックパブリックアクセスが無効のバケット等)
- IAMロール (外部からアクセスできる信頼ポリシーが付与されたロール)
- KMS (外部エンティティに対してアクセスが許可されたキー)
- Lambda (外部エンティティに対して関数へのアクセスを許可するポリシー)
- SQS (外部エンティティに対してキューへのアクセスを許可するポリシー)
いずれもセキュリティリスクが高めの状態であるため、これらを簡易的に検知することはセキュリティ診断の一種としての役割を果たすでしょう。
Access Adviserと名前が紛らわしいですが、差異を理解するために以下の記事が参考になります
認証情報レポート
認証情報を簡略化したレポートをCSV形式でダウンロードすることができます。
IAMダッシュボード
重要度の高い情報を簡略化して表示してくれる便利な画面です
セキュリティに関するレコメンデーション
重要な設定が、後述のベストプラクティス等のAWS推奨設定に合致しているかを判定・表示してくれます。
ここが赤色になっていたらセキュリティリスクが高い状態となっているので、指示に従って設定変更しましょう
IAMリソース
現在のAWSアカウントに含まれるリソース(ユーザー、グループ、ロール、ポリシー、IDプロバイダ)の数を一覧表示します。
クリックすると、前述の左側のタブと同様にこれらのリソースの設定画面にアクセスすることができます。
AWSアカウント
後述のアカウントIDやエイリアス等、アカウントへのログイン情報を表示します
クイックリンク
現在ログインしているユーザーの認証情報(自分の認証情報)が確認できます
ツール
IAMに関連した以下2ツールのリンクに飛べます(使用法はリンク先を参照ください)
- ポリシーシミュレータ → 設定したポリシーが想定通り動作しているかを確認するためのシミュレータ
- Web Identity Federation Playground → シングルサインオンのアクセストークンにAWSの一時認証情報を付与できるツール
IAMセキュリティのベストプラクティス
AWS公式に記載されているベストプラクティスでは、以下の項目に従って権限設定することが推奨されています。
後述のIAM設定手順においても、これらの推奨項目を満たすよう設定を進めていきます
上記項目名だけでは内容が分かりづらい(公式ドキュメントも自動翻訳のためか非常に難解な)ので、それぞれを簡単に解説します
AWSアカウントルートユーザーのアクセスキーをロックする
前述のようにAWSでは、アクセスキーを使用してプログラム経由での認証が可能となっていますが、認証情報を保持したアクセスキーは流出時のセキュリティリスクが大きいとも言えます。
特にルートユーザーの認証情報が流出すると、文字通り「何でもできてしまう」事となるため、このリスクを防ぐためルートユーザーのアクセスキーはそもそも作成しない事が望ましいです。
デフォルトではルートユーザーのアクセスキーは作成されないので、ルートユーザーでログインした状態でコンソールからIAMにアクセスし、ダッシュボードに以下のように表示されていればOKです
MFAの有効化
MFAとは、多要素認証(Multi-Factor Authentication)の事を指します。
多要素認証とは、文字通り複数の認証方法を組み合わせる方法で、一般名詞としては様々な方法が考えられますが、AWSにおいては「通常のパスワード認証」+「スマホアプリ(Google Authenticator)による時刻同期型ワンタイムパスワード(OTP)認証」を組み合わせる方法が最も一般的です。
ベストプラクティスでは、全てのユーザーにMFAを設定する事が推奨されています。
具体的な設定方法は後述しますが、MFAが設定されているかどうかは、各ユーザーでAWSコンソールにログインしてIAMにアクセスした際の、ダッシュボードに表示されます。
以下のように「MFAが設定されている」と表示されていればOKです
ユーザーのために強度の高いパスワードポリシーを設定する
詳細は後述しますが、パスワードポリシー(IAMユーザー作成時のパスワード設定に必須となるルール)は、ある程度厳しく設定することが推奨されています。
デフォルトでは以下のパスワードポリシーが適用されていますが、組織のルールと適合性を確認しながら、適宜より厳しいルールを適用してください
最小限の特権を認める
アクセス制御を運用する際の手順として、以下の2通りの方法が考えられます
- 最小限のアクセス許可から開始し、必要に応じて追加のアクセス許可を付与
- 余分にアクセス許可を与えた状態から開始し、必要ないアクセス許可を後から削除
ベストプラクティスでは、前者の最小限のアクセス許可からスタートする事が推奨されています。
後者の方法は開始時点のセキュリティが弱い(アカウントが乗っ取られた際のリスクが大きい)事が理由です。
基本的には、「アクセス権限は必要になったときに付与する」(必要になるまで付与しない)ことを心掛けてください。
特に前述の記事で触れられていたように、むやみに管理者権限を付与する事は避けるべきです。
AWS管理ポリシーを使用したアクセス許可の使用開始
前述のように、ポリシーには「AWS管理ポリシー」、「カスタマー管理ポリシー」 、「インラインポリシー」の3種類が存在しますが、初期状態ではデフォルトで用意されているAWS管理ポリシーの使用が推奨されています。
公式にも
チームに必要な許可のみを提供するIAMカスタマーマネージドポリシーを作成するには、時間と専門知識が必要です
と記載されているように、カスタマー管理ポリシーの作成は難易度が高く、初心者が独自にカスタマー管理ポリシーを作るとミスや勘違いでセキュリティリスクを作る原因となるので、まずはAWSが準備してくれているAWS管理ポリシーを使用するのが良いでしょう。
(ただし、カスタマー管理ポリシーの方が権限範囲を柔軟に絞れるので、慣れてきたらこちらの方が「最小限の特権」に合致したポリシーを作成できます)
前述のようにAWS管理ポリシーは「ジョブ機能の管理ポリシー」と「サービスごとの管理ポリシー」が存在しますが、
・ジョブ機能の職責に該当する開発者(管理者ユーザー、パワーユーザー等) → 以下に基づき「ジョブ機能の管理ポリシー」を選択
・ジョブ機能の職責に該当しない開発者(個別に権限付与するユーザー) → 「サービスごとの管理ポリシー」を必要なものだけ選択
すると良いでしょう
インラインポリシーではなくカスタマー管理ポリシーを使用する
AWS管理ポリシーでは設定しきれない細かな権限を設定したい場合、カスタマー管理ポリシーまたはインラインポリシーを使用する必要があります。
この場合先ほど触れたように、ベストプラクティスでは、カスタマー管理ポリシーの使用が推奨されています。
カスタマー管理ポリシーを使用すべき理由ですが、以下を見ると「コンソール内のすべての管理ポリシーを1か所で確認できること」や「設定を使い回せる事(再利用可能性)」が挙げられています。
ポリシーの検証
新しくポリシー(カスタマー管理ポリシーまたはインラインポリシー)を作成した際には、作成したポリシーにエラーやセキュリティリスクがないか検証することが推奨されています。
簡易的な方法として「IAMコンソールでのポリシーの検証」が推奨されており、本記事でも実際の使用法を後述します
また、上記に加えて前述のAccess Analyzerで外部アカウントと共有しているリソースを検出することも、ベストプラクティスでは推奨されています。
Access Analyzerの使用方法は以下の方がわかりやすく解説されています。
アクセスレベルを使用して、IAMのアクセス許可を確認する
前述のように、ポリシーはJSONで記述されますが、これだけでは内容が直感的に分かりづらく、ミスの原因となってしまいます。
ミスを防ぐための仕組みとして前述のポリシーの検証が挙げられますが、これ以外にもポリシーの概要を分かりやすく表示するアクセスレベルと呼ばれる指標が存在します
アクセスレベルは、List
(リソースのリスト表示)、Read
(読取)、Write
(書込)、Permissions management
(権限設定)、Tagging
(リソースのタグ付け)の5つの分類からなり、テーブル表示されたポリシー概要を直感的に確認することができます。
例えば前述のAmazonS3ReadOnlyAccess
というAWS管理ポリシーでは、アクセスレベルは以下のように表示されます
(表示方法は後述)
S3およびLambdaからS3へのリスト表示と読取が許可されていることが分かり、JSONよりも直感的にポリシーの内容が確認できる事が分かります。
Amazon EC2 インスタンスで実行するアプリケーションに対し、ロールを使用する
前述したように、アプリケーションからAWSへのアクセス権限を与える方法には「ロール」と「アクセスキー」の2通りが存在しますが、アクセス元がAWS内のサービスである場合は「ロール」が推奨されます。
EC2は「AWS内のサービス」に相当するため、EC2上で動作するアプリケーションにはロールで権限を与える必要があります
(具体的な方法は後述します)
ロールを使用してアクセス許可を委任する
他のAWSアカウントやアプリケーションに一時的にアクセス権限を与える際の手法として、セキュリティリスクの大きいアクセスキーの使用は避け、前述の信頼ポリシーによる権限移譲が推奨されています。
アクセスキーの使用が推奨されるのは、AWS外かつシングルサインオンに対応していないアプリケーション等、権限移譲に対応していない場合のみです。
詳細は「一時的に権限を付与する方法」を参照ください
アクセスキーを共有しない
「同一のアクセスキーを複数人で使い回すな」という趣旨の項目です。
代わりにロールを使用して一時的に権限を付与する方法が推奨されています。
前節と同様、詳細は前述の「一時的に権限を付与する方法」を参照ください
追加セキュリティに対するポリシー条件を使用する
タイトルだけでは何のことやらといった感じですが、前述の「ポリシーの構造」で述べたStatement
フィールドのCondition
要素を記載することで、ポリシーにアクセスできる条件を限定してセキュリティを向上させることを推奨する内容となっています。
Condition
要素への条件指定方法は以下を参照ください
また、後述の「IAM設定手順」でも、実際にCondition
要素への条件を指定する例を紹介しています。
認証情報を定期的にローテーションする
公式ドキュメントの記載が端的にまとまっているので、そのまま引用します。
パスワードとアクセスキーを定期的に変更し、アカウント内のすべての IAM ユーザーにも変更を促してください。そうすることにより、知らない間にパスワードまたはアクセスキーが漏れた場合でも、その認証情報を使ってお客様のリソースにアクセスされる期間を制限できます。
上記のように、ユーザのパスワードとアクセスキーを定期的に変更してください
不要な認証情報の削除
公式ドキュメントに記載の通り、長期間にわたって使用していないアクセスキーやパスワードはセキュリティホールの原因となるため、削除が推奨されます。
何をもって「使用していない」とするかは難しいところですが、調査には以下の「使用していない認証情報の検索」が役に立ちます
また、AWSにはポリシーやロールを自動作成するサービス(例:S3のレプリケーション設定)が多く、使用していないロールやポリシーが大量に溜まって管理が困難となるため、使用していないリソースは定期的に削除する事をお勧めします。
AWSアカウントのアクティビティのモニタリング
セキュリティの基本として「ログを取って後で調査できるようにする」ことは重要です。
公式ドキュメントでは、以下のサービスによる取得が推奨されています。
サービス名 | ログ取得対象 |
---|---|
Amazon CloudFront | CloudFront が受信したユーザーリクエストを記録 |
AWS CloudTrail | AWS APIコールおよび関連イベント |
Amazon CloudWatch | AWS上のリソースおよび実行しているアプリケーションの動作を、定義したメトリクスに基づきモニタリング |
AWS Config | IAMユーザー、ユーザーグループ、ロール、およびポリシーを含む、AWSリソースの設定に関する詳細な履歴情報 |
Amazon S3 | AmazonS3バケットへのアクセスリクエスト |
取得方法は以下の公式ドキュメントを参照ください
IAM設定手順
ここからは実際のAWS画面(コンソール)において、IAMの設定手順を解説します。
前述のベストプラクティスを満たしつつ、基本的な操作法を網羅できることを目指します。
ユースケース
以下のような開発チームでAWSアカウントを運用する場合を考えます。
名称 | 使用する権限 | 人数 |
---|---|---|
IT管理者(兼支払管理者) | ルートユーザー+管理者ユーザー | 1名 |
開発責任者 | パワーユーザー | 1名 |
アプリ開発者 | EC2, ELB, RDS, S3, VPCを個別付与 | 2名 |
※以下の公式ドキュメントの構成を参考にしています
前述の通り、権限(ポリシー)はユーザー単位でもグループ単位でも設定することができますが、今回は人数が増えても管理しやすいグループ単位での管理を実施する事とします。
設定は以下の手順で実施します
- ルートユーザーの設定
- 管理者ユーザーの作成
- パワーユーザーの作成
- アプリ開発者ユーザーの作成
- AWS内サービスへの権限付与
- AWSアカウント内での権限移譲
- 別のAWSアカウントへの権限移譲
- AWS外アプリの権限設定
本設定手順に従えば、前述のベストプラクティスをあらかた網羅できることを目指して設定を進めたいと思います。
ルートユーザーの設定
まずはルートユーザーの設定を変更し、ベストプラクティスに基づいてセキュリティを強化します。
なお、本節の解説はAWSの登録とルートユーザの作成が完了した時点をスタートとしますが、完了していない方はこちらを参考にAWSの登録を実施してください。
MFAの有効化
まずはGoogle AuthenticatorによるMFA(多要素認証)を有効にします。
AWSのコンソールにログインすると、左上に以下のような検索ボックスが出てくるので、「IAM」と検索します
「IAM」を選択するとIAMダッシュボードが表示され、以下のような「rootユーザーのMFAを追加する」という注意書きが出るかと思います。注意に従い「MFAの追加」をクリックします。
MFAデバイスにGoogle Authenticatorを使用する場合、「仮想MFAデバイス」を選択します
スマホにGoogle Authenticatorをインストールし、こちらを参考に、AWS側の以下の画面に表示されているQRコードから2段階認証を登録し、アプリに表示されるワンタイムパスワードを2回連続(60秒で切り替わる)で以下の画面に入力します
ルートユーザーのアクセスキー無効を確認
デフォルトではルートユーザーのアクセスキーは作成されないので、IAMダッシュボードに以下のように表示されていればOKです
パスワードポリシーの設定
今後IAMユーザーを作成する際には、一緒にパスワードを設定します。
このパスワードに対して必須となるルールを設定します。
デフォルトでは以下の制限が適用されていますが、組織のルールと適合性を確認しながら、適宜より厳しいルールを適用してください
管理者ユーザーの作成
前述のように、セキュリティリスクを抑えるためにはルートユーザーの使用頻度を極力抑えるべきです。
よってIT管理者であっても、日常的に使用するためのIAMユーザーである、管理者ユーザをルートユーザーとは別に作成する必要があります。
管理者ユーザーの作成
ルートユーザーでコンソールにログインした状態でIAMに入り、「ユーザー」→「ユーザーの追加」をクリックします
作成したい管理者ユーザー名を入力し、「アクセスキー - プログラムによるアクセス」「パスワード - AWSマネジメントコンソールへのアクセス」をチェックし、カスタムパスワードを入力します
※「アクセスキー - プログラムによるアクセス」をチェックすると、アクセスキーが有効になります。前述のように、AWS外部のプログラムからAWSへのアクセスには多くの場合アクセスキーが必要となりますが、「外部から使わない」という場合は、チェックしない方がセキュリティが強くなります。管理者ユーザはかなり強い権限を持つため、不要であればチェックしないことをお勧めします)
※「パスワード - AWSマネジメントコンソールへのアクセス」をチェックすると、パスワードによるコンソールのアクセスが可能となります。チェックしなくともスイッチロールによるコンソールへのアクセス自体は可能ですが、イレギュラーな方法となるので基本的にはチェックしたほうが良いでしょう
※「パスワードのリセットが必要」をチェックすると、最初のログイン時にパスワードの再設定が必要となります。基本的にはユーザー作成者と実際の使用者が一致しない場合(後述のパワーユーザーや開発者ユーザーが該当します)にチェックします
管理者用グループの作成
以下のような画面が表示されますが、今回はグループ単位で権限を設定するので、「グループの作成」をクリックします
(ユーザー単位で権限を設定したい場合は「既存のポリシーを直接アタッチ」を使用します)
管理者向けのポリシーとして、ジョブ機能ごとに定義されたAWS管理ポリシーであるAdministratorAccess
を選択します。
以下の手順でAdministratorAccess
を選択し、「グループの作成」をクリックします
管理者ユーザーの作成(続き)
後々管理しやすいようNameタグを指定します(何も指定せず「次のステップ」へ進んでもOKです)
今まで指定した内容が確認できるので、問題なければ「ユーザーの作成」をクリックします。
作成が完了したら以下の画面が表示されます。シークレットキーはこのタイミングでしか確認できないので、アクセスキーを使用する場合は流出に気を付けつつ「表示」を押してメモしてください
なお、作成したIAMユーザーでログインするためには、IAMダッシュボードに表示される以下赤塗り部分の「アカウントID」または「アカウントエイリアス」が必要となるのでご注意ください
ルートユーザーからログアウトし、ログイン画面にアカウントID、ユーザー名、パスワードを入力して作成したIAM管理者ユーザーにログインします
MFAの設定
管理者ユーザーにMFAを設定します。
IAMダッシュボードに移動すると、以下のような「MFAを自分用に追加」という注意書きが出るかと思います。注意に従い「MFAの追加」をクリックします。
多要素認証(MFA) → MFAデバイスの割り当てをクリックします
以降はルートユーザーのMFA設定の時と同様の手順で、MFAを適用してください
パワーユーザーの作成
開発責任者が使用するパワーユーザーを作成します。
パワーユーザーはIAM以外のほぼ全てのサービスにフルアクセス可能な強い権限を持ったユーザーで、注意して管理しないとセキュリティリスクを高める原因にもなるので、不要であればより弱い権限を設定してください(本記事ではひとまずパワーユーザー権限を使用する前提で設定を進めます)
パワーユーザーの作成
IT管理者が先ほど作成した管理者ユーザー(ルートユーザーではない)にログインしてIAMコンソールに入り、管理者ユーザー作成時と同様の手順でパワーユーザーを作成します。
なお、管理ユーザー作成時との違いとして、
・作成者と使用者が異なるので、「パスワードのリセットが必要」をチェックしてください
・作成したパスワード、ユーザー名およびアカウントIDは初回ログインに使用するので、実際に使用するユーザー(今回は「開発責任者」)に伝えてください
パワーユーザー用グループの作成
以下のような画面が表示されるので、「グループの作成」をクリックします
(ユーザー単位で権限を設定したい場合は「既存のポリシーを直接アタッチ」を使用します)
管理者向けのロールとして、ジョブ機能ごとに定義されたAWS管理ポリシーであるPowerUserAccess
を選択します。
以下の手順でPowerUserAccess
を選択し、「グループの作成」をクリックします
グループの作成が完了したら、管理者ユーザーの時と同様にNameタグを設定してユーザー作成を完了させます。
パワーユーザーの初回ログイン
以降はIT管理者でなく実際にパワーユーザーを使用する開発責任者が行う作業となります。
先ほどIT管理者から伝えられたユーザー名、パスワード、アカウントIDを使用してAWSコンソールにログインすると以下のような画面が表示されるので、パスワードを再設定します。
MFAの設定
パワーユーザーにMFAを設定します。
ですがこの設定、一筋縄ではいきません。
前述のようにパワーユーザーはIAMの操作権限を持たないため、そのままではMFAを登録することができません。
以下の記事のMFA設定用カスタマー管理ポリシーをパワーユーザに付与したのち、パワーユーザーを使用する本人にMFAを設定してもらってください (MFA設定操作自体は管理者ユーザの時と同様です)
上記MFA設定用カスタマー管理ポリシーは、MFA設定後にパワーユーザから削除した方がセキュリティレベルが高まりますが、MFAの再設定が煩雑となるので削除するかどうかは各組織で判断してください。
アプリ開発者ユーザーの作成
EC2, ELB, RDS, S3, VPCへのアクセス権限を持ったアプリ開発者ユーザーを作成します。
(実際は、使用するサービスに絞って与える権限を適宜変更してください)
アプリ開発者ユーザー用ポリシーの作成
アプリ開発者ユーザーに適用するポリシーをIT管理者が作成します。
管理者ユーザーやパワーユーザーではジョブ機能の管理ポリシーを使用して全サービス一括で権限設定しましたが、使用するサービスが限られたアプリ開発者ユーザでは、「最小限の特権を認める」の原則に則って
-サービスごとのAWS管理ポリシー
-カスタマー管理ポリシー
のいずれかを必要サービスに絞って設定します。
両者それぞれのポリシー作成方法を解説します。
※ベストプラクティスの「AWS管理ポリシーを使用したアクセス許可の使用開始」の原則に従うと、慣れないうちはサービスごとのAWS管理ポリシーを使用した方が良さそうです
※同じくベストプラクティスの「インラインポリシーではなくカスタマー管理ポリシーを使用する」に従うと、インラインポリシーは熟練者以外は使用を避けた方が良さそうです
1. サービスごとのAWS管理ポリシーを設定する場合
デフォルト状態でAWS管理ポリシーが準備されているので、新たにポリシーを作成する必要はありません
2. カスタマー管理ポリシーを作成する場合
管理者ユーザーでログインしてIAMコンソールに入り、左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
・サービス → EC2
・アクション → すべてのEC2アクション(権限を絞りたい場合(例:読取のみ)は適宜チェックを絞ってください)
を選択します
・リソース → すべてのリソース(リソースを絞りたい場合は適宜選択してください)
・リクエスト条件 → チェック不要(MFAやリクエスト元IPにフィルタを掛けたい場合は適宜チェックしてください)
を選択します
「さらにアクセス許可を追加する」をクリックし、EC2と同様にELB, RDS, S3も
・アクション → すべてのアクション(権限を絞りたい場合は適宜チェックを絞る)
・リソース → すべてのリソース(リソースを絞りたい場合は適宜選択)
・リクエスト条件 → チェック不要(MFAやリクエスト元IPにフィルタを掛けたい場合は適宜チェック)
を指定して追加してください(VPCはEC2アクションに権限が含まれるため追加不要)
後々管理しやすいようNameタグを指定します(何も指定せず「次のステップ」へ進んでもOKです)
付けたいポリシー名と説明を入力し、「ポリシーの作成」をクリックします
これでカスタマー管理ポリシーの作成完了です。
ポリシーの検証
前節で「2.カスタマー管理ポリシーの作成」を選択した場合、ベストプラクティスにも記載された
-「アクセスレベルを使用して、IAMのアクセス許可を確認する」
-「IAMコンソールでのポリシーの検証」
を実施する事で、アクセス権限が想定通り付与されているかや、文法等にミスがないかを確認できます。
IAMの左側のタブから「ポリシー」をクリックし、先ほど作成したポリシー名をクリックします
「アクセス権限」タブでアクセスレベルを表示できます。これにより与えられた権限をわかりやすく一括確認することができます。
ポリシーの検証を実施したい場合はさらに「ポリシーの編集」をクリックします
「JSON」タブをクリックすると、下側のタブにエラーや注意事項がないかの検証結果が表示されます
※下の画面ではエラー等が発生しておらず、構文上は問題なく作成できた事が分かります
アプリ開発者グループの作成
上記ポリシーを適用するグループを、IT管理者が作成します。
IAMの左側のタブから「User groups」 → 「グループを作成」をクリックします
ここからは先ほど「1.サービスごとの管理ポリシー」「2.カスタマー管理ポリシー」いずれを選択したかで処理が変わります
1. サービスごとの管理ポリシーを設定する場合
以下のアクセスポリシーを検索して全てチェックします
・EC2のフルアクセスポリシー → AmazonEC2FullAccess
・ELBのフルアクセスポリシー → ElasticLoadBalancingFullAccess
・RDSのフルアクセスポリシー → AmazonRDSFullAccess
・S3のフルアクセスポリシー → AmazonS3FullAccess
・VPCのフルアクセスポリシー → AmazonVPCFullAccess
2. カスタマー管理ポリシーを設定する場合
先ほど作成したカスタマー管理ポリシーを検索してチェックします
1と2いずれを選択した場合も、「グループを作成」をクリックしてグループ作成完了します
アプリ開発者ユーザーの作成
アプリ開発者ユーザを2名作成し、上記でポリシーを付与したグループに追加します。
IAMの左側のタブから「ユーザー」 → 「ユーザーを追加」をクリックします
パワーユーザと同様に、以下を選択、実施してください
・作成者と使用者が異なるので、「パスワードのリセットが必要」をチェックしてください
・作成したパスワード、ユーザー名およびアカウントIDは初回ログインに使用するので、実際に使用するユーザー(今回は「アプリ開発者」)に伝えてください
必要に応じてタグを追加し、確認画面を経て「ユーザの作成」をクリックすると、ユーザ作成が完了します。
同様に2人目の開発者ユーザーも作成します。
アプリ開発者ユーザーの初回ログイン
以降はIT管理者でなく実際にユーザーを使用するアプリ開発者が行う作業となります。
先ほどIT管理者から伝えられたユーザー名、パスワード、アカウントIDを使用してAWSコンソールにログインし、パスワードを再設定します。
MFAの設定
ベストプラクティスに従うのであれば、アプリ開発者ユーザーにもMFAを設定すべきです。
ただし、管理者ユーザーやパワーユーザーと比べると権限をある程度絞っているので、実際にMFAを設定するかは利便性とのバランスを見て各組織で判断頂ければと思います。
MFAを設定する場合、パワーユーザの時と同様にMFA設定用カスタマー管理ポリシーを付与してください。
AWS内サービスへの権限付与
サービスやアプリケーションからAWSへのアクセス権限を与える方法には、「ロール」と「アクセスキー」の2通りが存在しますが、前述したように、アクセス元がAWS内のサービスである場合は「ロール」が推奨されます。
例えば、AWS内のアプリケーションからAWS内のリソースにアクセスする例として、以下のようにEC2上のPythonスクリプトからCSVファイルをS3にアップロードする例を考えてみます。
上記の処理を実現するためには、ロールを使ってEC2にS3へのアクセス権限を付与する必要があります。具体的には
「S3へのアクセス権を持つポリシーを付与したロールを作成し、EC2にロールをアタッチする」
という処理を実行します。
以下手順を紹介します
EC2インスタンスとS3バケットの作成
EC2インスタンスを作成します(デフォルト設定のAmazonLinux + t2.micro + キーペアありで大丈夫です)
S3バケットを作成します(こちらもデフォルト設定でOKです)
EC2へのPythonスクリプトの作成
EC2内にPythonスクリプトを作成します。例としてVSCode+SSHでの作成例を紹介します。
まずはこちらを参考にVSCodeとRemote Developmentをインストールしてください。
VSCodeを開き、以下の手順で.ssh/config
を開きます
開いた.ssh/config
に、以下の内容を記載します
Host [VSCode上での表示名]
HostName [EC2のIPアドレス]
User [EC2インスタンスユーザ名]
IdentityFile [EC2のキーのパスを入力]
EC2インスタンスのIPアドレスはEC2の「インスタンス」コンソールの以下の位置に記載されています
例えば、以下のように記載します
Host ec2-test
HostName ***.***.***.***
User ec2-user
IdentityFile ~/.ssh/key.pem
先ほどのSSH Targetsの画面に以下のように接続先が表示されるので、赤枠部分をクリックするとEC2にSSH接続されます
今回はseaborn, pandas, boto3という3つのPythonパッケージを使用します。Amazon Linuxにはおそらくインストールのためのパッケージ管理ツールpipが入っていないので、VSCodeのターミナルから
pip list
と打って見つかりません的なメッセージが返ってきたら、
sudo yum -y install python-pip
と打ち、pipをインストールします。ここから以下コマンドで、必要パッケージをインストールします
pip install seaborn pandas boto3
インストールが終わったらEC2内に適当な作業用フォルダを作成し、以下の操作で作成したフォルダを開きます
開いたフォルダに以下のようなスクリプトを作成します。S3へのデータのアップロードにはboto3ライブラリを使用します
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')
上記を実行すると
という、クレデンシャル情報がありませんというエラーが出るかと思います。
これはEC2インスタンスにS3へのアクセス権限が与えられていないことに由来するため、ロールを使用して権限を与える必要があります。
ロールの作成
S3にアクセスするためのロールを作成します。
IAMの左側のタブから「ロール」 → 「ロールを作成」をクリックします
- 信頼されたエンティティタイプ → AWSのサービス
- ユースケース → EC2
を選択します。
※「信頼されたエンティティタイプ」は、以下のように用途に合わせて選択します。今回のように同一アカウント内のAWSサービスに権限を与える場合は「AWSのサービス」を選択して直接権限をアタッチできますが、別アカウントやWebアイデンティティ、SAML2.0対応のサービスの場合前述の信頼ポリシーとAssumeRoleを使用して権限を移譲します (具体的な権限移譲法も後述します)
信頼されたエンティティタイプ (権限の付与先) | 用途 |
---|---|
AWSのサービス | 同アカウントAWSサービスに権限を与えるとき |
AWSアカウント | 別アカウントのAWSユーザやサービスに権限を与えるとき (同アカウントも可) |
ウェブアイデンティティ | Amazon,Facebook,Google などの OpenID Connect互換のIdPと連携して認証したいとき(参考) |
SAML2.0フェデレーション | SAMLシングルサインオンでAD等と連携して認証したいとき |
※「ユースケース」は、アクセス元のAWSのサービスに合わせて選択してください(EC2, Lambda以外はプルダウンで選択)
「S3」で検索し、AmazonS3FullAccess
(S3へのフルアクセス)をチェックして「次へ」を押します
ロール名と説明を記載し、「ロールを作成」をクリックするとロールの作成が完了します
EC2へのロールのアタッチ
EC2インスタンスに作成したロールを付与します。
なお、ロールの付与には前述の権限移譲に関する記事でも登場したPassRole権限が必要となります。
PassRoleはIAM内の機能であるため、デフォルト設定では管理者権限を持つユーザでないと実施できません
ひとまず本節では管理者ユーザでロールを付与する前提で解説を進めますが、後ほど管理者権限を持たないユーザからロールを付与する場合も紹介します。
対象のEC2インスタンスをチェックして「アクション」→「セキュリティ」→「IAMロールを変更」をクリックし
先ほど作成したロールを選択して「保存」を押すと、ロールのアタッチが完了します。
先ほどのEC2内のPythonスクリプトを再度実行し、エラーを出さずにS3にデータをアップロードできれば成功です。
EC2へのロールのアタッチ (管理者権限を持たないユーザから実施する場合)
前述のように、デフォルト設定でははPassRole権限を持つ管理者ユーザでないとEC2へのロールのアタッチを実施できませんが、管理者ユーザ以外でもPassRole権限を付与することによりロールのアタッチを実現できます
以下の記事を参考に、パワーユーザにPassRole権限を付与し、EC2へのロールのアタッチを実行してみます。
まず、管理者ユーザーでログインしてIAMコンソールに入り、左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
「JSON」タブをクリックし、JSONでの編集モードに入ります
以下のようなPassRole権限を持つポリシーを記述します
(例えば、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/*"
}
]
}
※上記ポリシーでは前述のベストプラクティスで登場したCondition
要素によるアクセス条件の限定(PassRoleによるアタッチ対象をEC2に絞る)が行われています。
※PassRoleだけでなく、ロール一覧を表示するためのiam:ListInstanceProfiles
への権限も付与されています。これがないとEC2へのロールアタッチ時に対象ロールが表示されず、以下のようなエラーが発生します
名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です
作成したポリシーを以下のようにパワーユーザ用のグループ(あるいはユーザ)にアタッチすると、本来はPassRole権限を持たないパワーユーザからも、EC2へのロールアタッチが実行できるようになります
PassRole権限はIAMの中でもよく使用する機能の一つなので、セキュリテイリスクを抑えつつ管理者以外のユーザでもPassRoleできるよう、上記のようなポリシーを準備しておくと便利です。
AWSアカウント内での権限移譲
上例ではポリシーを直接グループにアタッチすることで、PassRole権限をパワーユーザに付与することができました。
同様の権限付与は、前述のAssumeRoleによる権限移譲によっても実現できます。
上例のように同アカウント内のユーザであれば、直接ポリシーをロールやユーザにアタッチできるので、わざわざ権限移譲する必要性は低いですが、練習や直接アタッチした場合との比較も兼ねて、PassRoleの権限移譲を実施してみます。
権限移譲の手順
少し複雑ですが、権限移譲は以下の手順で実施します
1. 権限移譲用ロールの作成 (「権限を渡す側」の設定)
2. 権限引受用ポリシーの作成 (「権限を渡される側」の設定)
3. 権限引受用ポリシーのアイデンティティへの適用
4. スイッチロールの実行
※手順1〜3はIAMへのアクセス権限を持ったアカウント(管理者アカウント等)で実施する必要があります。
以下詳説します
1. 権限移譲用のロール作成
渡したい権限を記述したポリシーをアタッチした、権限移譲用ロールを作成します。
先ほどの通常の「ロールの作成」と同様に、
IAMの左側のタブから「ロール」 → 「ロールを作成」をクリックします
- 信頼されたエンティティタイプ → AWSアカウント
- 別のAWSアカウント → このアカウント(同アカウント内のアイデンティティに権限移譲するため)
を選択します。
前述のように、信頼されたエンティティタイプに「AWSのサービス」以外が選択されているので、この時点でAssumeRoleが適用されます。
許可ポリシーに、先ほど作成したPassRole用およびEC2へのフルアクセス用ポリシーを指定します。
※EC2へのフルアクセス用ポリシーも追加する理由
後の手順でスイッチロールして権限移譲すると、スイッチロール前のユーザが持っていた権限は失われてしまいます。
今回のケースでは元のパワーユーザが持っていたEC2へのアクセス権限が失われるため、EC2を操作するためにPassRoleの権限だけでなくEC2へのフルアクセス権限も付与する必要があります。
以下の画面でロール名と説明を記載し、「ロールを作成」をクリックするとロールの作成が完了します
(AssumeRoleが適用されている事がここで確認できます)
作成したロールをIAMコンソールから以下のように選択し、ARNをメモします(引受用ロール作成時に使用します)
2. 権限引受用ポリシーの作成
権限を受け取るためのポリシーを作成します。
IAMコンソール左側のタブから「ポリシー」→「ポリシーの作成」をクリックします
「JSON」タブをクリックし、JSONでの編集モードに入ります
以下のように、先ほど作成した権限移譲用ロールを引き受けるポリシーを記述します
(例えば、AssumeRoleFromPassRoleEC2
というポリシー名を付けます)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "先ほどメモした権限移譲用ロールのARN"
}
]
}
名前と説明を記載し、「ポリシーの作成」をクリックすれば作成完了です
3. 権限引受用ポリシーのアイデンティティへの適用
権限引受用ポリシーを、権限移譲先のアイデンティティ(ユーザ、グループ、ロール)にアタッチします。
今回はパワーユーザ用のグループにアタッチします。
以下のようにパワーユーザ用のグループ(あるいはユーザ)をIAMコンソールから選択し、「許可」→「アクセス許可を追加」→「ポリシーをアタッチ」を選択します
先ほど作成した権限引受用ポリシーを選択し、「アクセス許可を追加」をクリックします
4. スイッチロールの実行
「スイッチロール」とは、前述のように権限移譲用ロールを引き受けた仮想的なユーザでコンソールにログインすることを指します。
これにより、移譲された権限を保持した状態でコンソールを操作する事ができます。
(前述のように、スイッチ前の権限は消えてしまうことにご注意ください)
まずは、手順3で権限を引き受けたユーザでログインし、コンソール右上のユーザ名をクリックして、「ロールの切り替え」を選択します
アカウントIDと権限移譲用ロールの名称を記載し、「ロールの切り替え」をクリックします。
スイッチしたユーザで、前述の「EC2へのロールのアタッチ」が実行できれば権限移譲成功です。
(本来パワーユーザーに実行できないロールのアタッチが、権限移譲により実行できるようになった)
なお、スイッチロール前のユーザに戻るにはコンソール右上のユーザ名から「スイッチバック」を選択します
別のAWSアカウントへの権限移譲
権限移譲を利用することで、別アカウントのAWSユーザやアプリケーションに、自アカウントのAWSリソースへのアクセス権限を付与する事ができます。
これにより複数アカウント間でリソースを共有できるため、複数組織を跨いだ開発の利便性をUPさせられます
権限移譲の手順
権限移譲は以下の手順で実施します
1. 権限移譲用ロールの作成 → 「権限を渡す側」のアカウントの管理者ユーザが実施
2. 権限引受用ポリシーの作成 → 「権限を渡される側」のアカウントの管理者ユーザが実施
3. 権限引受用ポリシーのアイデンティティへの適用 → 「権限を渡される側」のアカウントの管理者ユーザが実施
4. スイッチロールの実行 → 実際に権限を移譲されるユーザ(またはアプリケーション)が実施
詳細手順は先ほどの「AWSアカウント内での権限移譲」とほぼ同様のため、差分に絞って解説します
1. 権限移譲用のロール作成
「権限を渡す側」のアカウントの管理者ユーザが実施します。
基本的には前述のAWSアカウント内での「1. 権限移譲用のロール作成」と同様の手順で実施しますが、「信頼されたエンティティを選択」時に以下のように「別のAWSアカウント」→権限移譲先のアカウントIDを入力する必要があります。
なお、ここで指定した権限移譲先のアカウントIDは、信頼ポリシーのPrincipal
フィールドに記載されます。
ここから、信頼ポリシーで権限を移譲する先をPrincipal要素で指定している事が分かります。
2. 権限引受用ポリシーの作成
「権限を渡される側」のアカウントの管理者ユーザが実施します。
基本的には前述のAWSアカウント内での「2. 権限引受用ポリシーの作成」と同様の手順で実施してください。
3. 権限引受用ポリシーのアイデンティティへの適用
「権限を渡される側」のアカウントの管理者ユーザが実施が実施します。
基本的には前述のAWSアカウント内での「3. 権限引受用ポリシーのアイデンティティへの適用」と同様の手順で実施してください。
4. スイッチロールの実行
実際に権限を移譲されるユーザ(またはアプリケーション)が実施します。
基本的には前述のAWSアカウント内での「4. スイッチロールの実行」と同様の手順で実施しますが、「ロールの切り替え」画面の「アカウント」には「権限を渡す側」アカウントのアカウントIDを入力する必要が分かります。
上記操作により、別アカウントのロールを使用してコンソールにログインできてしまいます。
権限移譲はアカウント間を跨げる非常に自由度の高い機能です。
あくまで「一時的な権限の付与」を想定した機能ではありますが、ベストプラクティスではアクセスキーよりも使用の推奨度が高いため、使用できる場面では積極活用していきましょう
AWS外アプリの権限設定
AWS外のアプリにAWS内のリソースへのアクセス権限を付与する方法を考えます。
前述のSAMLやウェブアイデンティティに対応したアプリケーションであれば、前述の「別のAWSアカウントへの権限移譲」と同様、権限移譲によるアクセス権限の付与が推奨されます。
上記が使用できない場合、アクセスキーによる権限付与を実施します。
実例があった方が分かりやすいと思うので、アクセスキーを使用してPythonのライブラリMLflowにS3へのアクセス権限を与えた例のリンクを下記します。