

# MFA を使用した安全な API アクセス
<a name="id_credentials_mfa_configure-api-require"></a>

IAM ポリシーを使用して、ユーザーが呼び出すことができる API オペレーションを指定できます。特に重要なアクションの実行をユーザーに許可する前に、多要素認証 (MFA) で認証するように求めることで、セキュリティを強化できます。

たとえば、ユーザーにAmazon EC2 `RunInstances`、`DescribeInstances`、および `StopInstances` アクションの実行を許可するポリシーがすでに存在する可能性があります。ただし `TerminateInstances` のような有害なアクションを制限し、AWS MFA デバイスによって認証される場合に限り、ユーザーがそのアクションを実行できるように管理することもできます。

**Topics**
+ [概要:](#MFAProtectedAPI-overview)
+ [シナリオ: クロスアカウントの委任の MFA 保護](#MFAProtectedAPI-cross-account-delegation)
+ [シナリオ: 現在のアカウントの API オペレーションへのアクセスに対する MFA 保護](#MFAProtectedAPI-user-mfa)
+ [シナリオ: リソースベースのポリシーを持つリソースの MFA 保護](#MFAProtectedAPI-resource-policies)

## 概要:
<a name="MFAProtectedAPI-overview"></a>

API オペレーションに MFA 保護を追加する場合、次のタスクが関連します:

1. 管理者は、MFA 認証が求められる API リクエストを行うユーザーごとに AWS MFA デバイスを設定します。詳細については、「[IAM の AWS 多要素認証](id_credentials_mfa.md)」を参照してください。

1. 管理者はユーザーに対し、ユーザーが AWS MFA デバイスで認証されているかどうかを確認する `Condition` 要素を含むポリシーを作成します。

1. ユーザーは、MFA パラメータをサポートする AWS STS API オペレーションである [AssumeRole](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) または [GetSessionToken](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html) のいずれかを呼び出します。この呼び出しの一部としてユーザーは、このユーザーに関連付けられるデバイスのデバイス識別子を含めます。また、ユーザーは、デバイスが生成する時間ベースのワンタイムパスワード (TOTP) も含めます。そのつど、ユーザーは一時的な認証情報を取り戻し、その情報を使用して AWS に追加リクエストを行うことができます。
**注記**  
サービスの API オペレーションの MFA 保護は、サービスが一時的なセキュリティ認証情報をサポートする場合にのみ使用できます。サポートするサービスの一覧については、「[一時的セキュリティ認証情報を使用して AWS にアクセスする](https://docs.aws.amazon.com/STS/latest/UsingSTS/UsingTokens.html)」を参照してください。

承認が失敗した場合、AWS は他の承認されていないアクセスと同様に "Access Denied" というエラーメッセージを返します。MFA 保護 API ポリシーが存在する場合、ユーザーが有効な MFA 認証なしで API オペレーションを呼び出す場合に、AWS はポリシーで指定される API オペレーションへのアクセスを拒否します。また、API オペレーションへのリクエストのタイムスタンプがポリシーで指定される許可範囲外である場合にも、そのオペレーションは拒否されます。ユーザーは、MFA コードとデバイスのシリアルナンバーを使って新しい一時的な認証情報をリクエストすることで、再度、MFA の認証を受ける必要があります。

### MFA 条件を指定した IAM ポリシー
<a name="MFAProtectedAPI-policies"></a>

MFA 条件を指定したポリシーは、次にアタッチすることができます:
+ IAM ユーザーまたはグループ
+ Amazon S3 バケット、Amazon SQS キュー、または Amazon SNS トピックなどのリソース
+ ユーザーが引き受けることのできる IAM ロールの信頼ポリシー

ポリシーの MFA 条件を使用して、次のプロパティを確認することができます。
+ 存在 — ユーザーが MFA を使って認証されたことを単に確認するには、`Bool` 条件で `aws:MultiFactorAuthPresent` キーが `True` であることを確認します。ユーザーが短期的な認証情報で認証した場合に限りキーが表示されます。アクセスキーのような長期的な認証情報に、このキーは含まれません。
+ 期間 - MFA 認証後、指定された期間内のみアクセス権を与える場合、数値条件タイプを使用して `aws:MultiFactorAuthAge` キーの有効期間を値 (3600 秒など) と比較します。MFA が使用されなかった場合、`aws:MultiFactorAuthAge` キーは存在しません。

以下の例は、MFA 認証の存在をテストする MFA 条件が含まれる、IAM ロールの信頼ポリシーを示します。このポリシーにより、`Principal` 要素 (`ACCOUNT-B-ID` を有効な AWS アカウント ID に置き換えます) で指定された AWS アカウント のユーザーは、このポリシーがアタッチされたロールを引き受けることができます。ただし、このようなユーザーは、MFA を使用して認証されたユーザーの場合のみ、ロールを引き受けることができます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": {
    "Effect": "Allow",
    "Principal": {"AWS": "ACCOUNT-B-ID"},
    "Action": "sts:AssumeRole",
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }
}
```

------

MFA の条件種別の詳細については、「[AWS グローバル条件コンテキストキー](reference_policies_condition-keys.md)」、「[数値条件演算子](reference_policies_elements_condition_operators.md#Conditions_Numeric)」、および「[条件キーの有無をチェックする条件演算子](reference_policies_elements_condition_operators.md#Conditions_Null)」を参照してください。

### GetSessionToken または AssumeRole を選択する
<a name="scenarios"></a>

AWS STS には、ユーザーが MFA 情報を渡す際に使用できる 2 つの API オペレーションである `GetSessionToken` と `AssumeRole` があります。ユーザーが一時的な認証情報を取得するために呼び出す API オペレーションは、以下のどのシナリオがあてはまるかによって異なります。

**以下のシナリオでは、`GetSessionToken` を使用します。**
+ リクエストを作成する IAM ユーザーと同じ AWS アカウント のリソースにアクセスする API オペレーションの呼び出し。 `GetSessionToken`リクエストによる一時的な認証情報で IAM および AWS STS API にアクセスできるのは、認証情報のリクエストに MFA 情報を含めた場合*のみ*である点に注意してください。`GetSessionToken` によって返される一時的な認証情報には MFA 情報が含まれているので、認証情報によって実行される各 API オペレーションで MFA を確認できます。
+ リソースに基づくポリシー (MFA 条件を含む) で保護されているリソースへのアクセス。

`GetSessionToken` オペレーションの目的は、MFA を使用してユーザーを認証することです。認証オペレーションを制御するためにポリシーを使用することはできません。

**以下のシナリオでは、`AssumeRole` を使用します。**
+ 同じまたは異なる AWS アカウント のリソースにアクセスする API オペレーションの呼び出し。API コールには、任意の IAM または AWS STS API を含めることができます。アクセスを保護するには、ユーザーがロールを引き受けた時点で MFA を強制する必要があります。`AssumeRole` によって返される一時的な認証情報のコンテキストには MFA 情報が含まれていないので、MFA に対する個別の API オペレーションを確認できません。このため、リソースベースのポリシーで保護されたリソースへのアクセスを制限するために、`GetSessionToken` を使用する必要があります。

**注記**  
IAM ユーザーが MFA でサインインするとき、AWS CloudTrail ログには MFA 情報が含まれます。IAM ユーザーが IAM ロールを引き受けると、CloudTrail は引き受けたロールを使用して実行されたアクションの `sessionContext` 属性も `mfaAuthenticated: true` をログに記録します。ただし、CloudTrail ログ記録は、引き受けたロールの認証情報を使用して API コールが行われたときに IAM で必要になるものとは異なります。詳細については、「[CloudTrail userIdentity 要素](https://docs.aws.amazon.com//awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html)」を参照してください。

これらのシナリオの実行方法に関する詳細は、本書で後から提供されます。

### MFA 保護された API アクセスについて重要な点
<a name="MFAProtectedAPI-important-points"></a>

API オペレーションの MFA 保護の次の点に注意してください:
+ MFA 保護は、一時的なセキュリティ認証情報を使用した場合のみ利用できます。この認証情報は、`AssumeRole` または `GetSessionToken` を使用して取得する必要があります。
+ AWS アカウントのルートユーザー 認証情報で MFA 保護 API アクセスを使用することはできません。
+ U2F セキュリティキーで MFA 保護 API アクセスを使用することはできません。
+ フェデレーションユーザーに AWS サービス利用のために MFA デバイスを割り当てることはできませんので、そのようなユーザーは MFA が管理する AWS リソースへアクセスできません。(次のポイントを参照してください。) 
+ 一時的な認証情報を返す他の AWS STS API オペレーションは、MFA をサポートしていません。`AssumeRoleWithWebIdentity` と `AssumeRoleWithSAML` の場合、ユーザーは外部プロバイダーによって認証されており、プロバイダーが MFA を要求したかどうかを AWS が判断することはできません。`GetFederationToken` については、MFA は必ずしも特定のユーザーに関連付けられていません。
+ 同様に、長期的な認証情報 (IAM ユーザーアクセスキーと ルートユーザーアクセスキー) は失効しないため、MFA 保護 API アクセスでは使用できません。
+ `AssumeRole` と `GetSessionToken` は、MFA 情報がない状態でも呼び出すことができます。この場合、発信者は一時的な認証情報を取り戻しますが、その一時的認証情報のセッション情報では、ユーザーが MFA を使用して認証されたことが示されません。
+ API オペレーションに対する MFA 保護を確立するには、ポリシーに MFA 条件を追加します。MFA の使用を適用するには、ポリシーに `aws:MultiFactorAuthPresent` 条件キーが含まれている必要があります。クロスアカウントの委任では、ロールの信頼ポリシーに条件キーが含まれている必要があります。
+ 別の AWS アカウント に自分のアカウントのリソースへのアクセスを許可する場合、リソースのセキュリティは、信頼されたアカウント (つまりお客様のアカウントではない他のアカウント) の設定によって決まります。これは、多要素認証を要求する場合にも当てはまります。仮想 MFA デバイスを作成するアクセス許可がある、信頼されるアカウント内のアイデンティティは、ロールの信頼ポリシーのその部分を満たすために MFA クレームを作成できます。他のアカウントのメンバーに多要素認証を必要とする自身の AWS リソースへのアクセスを許可する前に、信頼されるアカウントの所有者がセキュリティのベストプラクティスを取り入れていることを確認する必要があります。たとえば、信頼されるアカウントは、MFA デバイス管理 API オペレーションなどの機密性の高い API オペレーションへのアクセスを指定する信頼できるアイデンティティに制限する必要があります。
+ ポリシーに MFA の条件が含まれている場合、ユーザーが MFA 認証済みでないか、無効な MFA デバイス識別子または無効な TOTP を入力すると、リクエストは拒否されます。

## シナリオ: クロスアカウントの委任の MFA 保護
<a name="MFAProtectedAPI-cross-account-delegation"></a>

このシナリオでは、ユーザーが AWS MFA デバイスを使用して認証された場合にのみ、別のアカウントの IAM ユーザーにアクセスを委任します。クロスアカウントの委任に関する詳細については、「[ロールに関する用語と概念](id_roles.md#id_roles_terms-and-concepts)」を参照してください。

アカウント A (アクセス対象のリソースを所有している信頼するアカウント) があり、このアカウントに管理者権限を持つ IAM ユーザー Anaya がいると仮定します。Anaya は、アカウント B (信頼されたアカウント) のユーザー Richard にアクセス許可を付与するつもりですが、Richard がロールを引き受ける前に、MFA によって認証されていることを確認する必要があります。

1. 信頼するアカウント A で、Anaya は `CrossAccountRole` という IAM ロールを作成し、ロールの信頼ポリシーのプリンシパルをアカウント B のアカウント ID に設定します。この信頼ポリシーは、AWS STS `AssumeRole` アクションに対するアクセス許可を付与します。Anaya は、次の例に示すように、信頼ポリシーに MFA の条件も追加します。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": {
       "Effect": "Allow",
       "Principal": {"AWS": "ACCOUNT-B-ID"},
       "Action": "sts:AssumeRole",
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }
   }
   ```

------

1. Anaya は、ロールが実行できることを指定するアクセス許可ポリシーを、ロールに追加します。MFA 保護を使用するロールのアクセス許可ポリシーは、他のロールアクセス許可ポリシーと同じです。次の例では、Anaya がこのロールに追加するポリシーを示しています。これによって、引き受けるユーザーがアカウント A のテーブル `Books` で任意の Amazon DynamoDB アクションを実行することを許可します。また、このポリシーは、コンソールでアクションを実行するときに必要となる `dynamodb:ListTables` アクションも許可します。
**注記**  
アクセス許可ポリシーに MFA 条件は含まれません。ユーザーがロールを引き受けることができるかどうかを決定するためにのみ MFA 認証が使用されていることに注意してください。ユーザーがロールを引き受けた場合、それ以上の MFA の確認は行われません。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "TableActions",
               "Effect": "Allow",
               "Action": "dynamodb:*",
               "Resource": "arn:aws:dynamodb:*:111122223333:table/Books"
           },
           {
               "Sid": "ListTables",
               "Effect": "Allow",
               "Action": "dynamodb:ListTables",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 信頼されたアカウント B で管理者は、IAM ユーザー Richard が AWS MFA デバイスを使用して設定されていること、および Richard がデバイスの ID を知っていることを確認します。ハードウェア MFA デバイスの場合には、デバイス ID はシリアル番号であり、仮想 MFA デバイスの場合には、デバイス ID はデバイスの ARN です。

1. アカウント B で、管理者は、`AssumeRole` アクションを呼び出すことを許可する次のポリシーを、ユーザー Richard (または彼が属するグループ) にアタッチします。リソースは、Anaya がステップ 1 で作成したロールの ARN に設定されます。このポリシーに MFA 条件が含まれないことに注意してください。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "sts:AssumeRole"
               ],
               "Resource": [
                   "arn:aws:iam::111122223333:role/CrossAccountRole"
               ]
           }
       ]
   }
   ```

------

1. アカウント B で、Richard (または Richard が実行中のアプリケーション) が `AssumeRole` を呼び出します。API コールには、引き受けるロールの ARN (`arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole`)、MFA デバイスの ID、Richard がデバイスから取得した現在の TOTP が含まれます。

   Richard が `AssumeRole` を呼び出すと、AWS は Richard に有効な認証情報 (MFA の要件など) があるかどうかを確認します。その場合、Richard は正常にロールを引き受け、ロールの一時的な認証情報を使用して、アカウント A の `Books` という名前のテーブルで DynamoDB アクションを実行できます。

   `AssumeRole` を呼び出すプログラムの例については、「[MFA 認証での AssumeRole の呼び出し](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-assumerole)」を参照してください。

## シナリオ: 現在のアカウントの API オペレーションへのアクセスに対する MFA 保護
<a name="MFAProtectedAPI-user-mfa"></a>

このシナリオでは、使用する AWS アカウント でユーザーが AWS MFA デバイスを使用して認証された場合のみ、機密性の高い API オペレーションにアクセスできるようにする必要があります。

アカウント A があり、そこに EC2 インスタンスの作業を必要としている開発者グループが存在すると仮定します。通常の開発者は、インスタンスの作業を実行できますが、`ec2:StopInstances` または `ec2:TerminateInstances` アクションへのアクセス許可を付与されていません。このようなの「有害な」特権的アクションをいくつかの信頼されたユーザーに制限するために、これらの機密性の高い Amazon EC2 アクションを許可するポリシーに MFA 保護を追加します。

このシナリオでは、信頼されたユーザーの 1 人がユーザー Sofía です。ユーザー Anaya は、アカウント A の管理者です。

1. Anaya は、Sofía が AWS MFA デバイスで設定されていること、および Sofía がこのデバイスの ID を知っていることを確認します。ハードウェア MFA デバイスの場合には、デバイス ID はシリアル番号であり、仮想 MFA デバイスの場合には、デバイス ID はデバイスの ARN です。

1. Anaya は `EC2-Admins` という名のグループを作成し、ユーザー Sofía をグループに追加します。

1. Anaya は、次のポリシーを `EC2-Admins` グループにアタッチします。このポリシーは、ユーザーが MFA を使用して認証された場合にのみ、ユーザーに Amazon EC2 `StopInstances` アクションと `TerminateInstances` アクションを呼び出すアクセス許可を与えます。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
       "Action": [
         "ec2:StopInstances",
         "ec2:TerminateInstances"
       ],
       "Resource": ["*"],
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }]
   }
   ```

------

1. 
**注記**  
このポリシーを有効にするために、ユーザーはまずサインアウトして、再度サインインする必要があります。

   ユーザー Sofía が Amazon EC2 インスタンスを停止または終了する必要がある場合、Sofía (または Sofía が実行しているアプリケーション) は `GetSessionToken` を呼び出します。この API オペレーションは、MFA デバイスの ID と Sofía がデバイスから取得した現在の TOTP を渡します。

1. ユーザー Sofía (または Sofía が使用しているアプリケーション) は、`GetSessionToken` から提供される一時的な認証情報を使用して Amazon EC2 の `StopInstances` または `TerminateInstances` アクションを呼び出します。

   `GetSessionToken` を呼び出すプログラムの例については、本書で後から説明する「[MFA 認証での GetSessionToken の呼び出し](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-getsessiontoken)」を参照してください。

## シナリオ: リソースベースのポリシーを持つリソースの MFA 保護
<a name="MFAProtectedAPI-resource-policies"></a>

このシナリオでは、S3 バケット、SQS キュー、または SNS トピックの所有者であるとします。リソースにアクセスする任意の AWS アカウント の任意のユーザーが AWS MFA デバイスによって認証されていることを確認する必要があります。

このシナリオは、最初にユーザーにロールを引き受けることを要求せずに、クロスアカウント MFA 保護を提供する方法を説明します。この場合、ユーザーは次の 3 つの条件を満たしている場合にリソースにアクセスできます。これは、ユーザーが MFA によって認証される必要があること、`GetSessionToken` から一時的なセキュリティ認証情報を取得できること、および、リソースのポリシーによって信頼されているアカウントにいることです。

アカウント A に存在し、S3 バケットを作成すると仮定します。さまざまな AWS アカウント に存在するユーザーが、MFA を使って認証されている場合にのみ、このバケットへのアクセスを許可します。

このシナリオでは、ユーザー Anaya はアカウント A の管理者です。ユーザー Nikhil は、アカウント C の IAM ユーザーです。

1. アカウント A で、Anaya が `Account-A-bucket` という名前のバケットを作成します。

1. Anaya はバケットにバケットポリシーを追加します。このポリシーは、アカウント A、アカウント B、またはアカウント C のユーザーに、バケット内の Amazon S3 `PutObject` および `DeleteObject` アクションの実行を許可します。ポリシーは、MFA 条件を含みます。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
       "Principal": {"AWS": [
         "ACCOUNT-A-ID",
         "ACCOUNT-B-ID",
         "ACCOUNT-C-ID"
       ]},
       "Action": [
         "s3:PutObject",
         "s3:DeleteObject"
       ],
       "Resource": ["arn:aws:s3:::ACCOUNT-A-BUCKET-NAME/*"],
       "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
     }]
   }
   ```

------
**注記**  
Amazon S3 により MFA 削除機能が *ルート*アカウントアクセス (のみ)に提供されています。バケットのバージョニング状態を設定する際に、Amazon S3 MFA 削除機能を有効にできます。IAM ユーザーでは Amazon S3 MFA 削除機能を使うことはできず、また MFA 保護 API とは別のアクセス管理となっています。バケットの削除権限を持つ IAM ユーザーであっても、Amazon S3 MFA 削除機能を使用してバケットの削除を行うことはできません。Amazon S3 MFA 削除機能の詳細については、[MFA Delete](https://docs.aws.amazon.com/AmazonS3/latest/dev/MultiFactorAuthenticationDelete.html) を参照してください。

1. アカウント C で管理者は、ユーザー Nikhil が AWS MFA デバイスを使用して設定されていること、および Nikhil がデバイスの ID を知っていることを確認します。ハードウェア MFA デバイスの場合には、デバイス ID はシリアル番号であり、仮想 MFA デバイスの場合には、デバイス ID はデバイスの ARN です。

1. アカウント C で、Nikhil (または Nikhil が実行中のアプリケーション) が `GetSessionToken` を呼び出します。呼び出しには、MFA デバイスの ID または ARN、および Nikhil がデバイスから取得する現在の TOTP が含まれます。

1. Nikhil (または Nikhil が使用中のアプリケーション) は、`GetSessionToken` から返された一時的な認証情報を使用して Amazon S3 の `PutObject` アクションを呼び出し、ファイルを `Account-A-bucket` にアップロードします。

   `GetSessionToken` を呼び出すプログラムの例については、本書で後から説明する「[MFA 認証での GetSessionToken の呼び出し](id_credentials_mfa_sample-code.md#MFAProtectedAPI-example-getsessiontoken)」を参照してください。
**注記**  
この場合、`AssumeRole` が返す一時的認証情報は機能しません。ユーザーはロールを引き受けるために MFA 情報を提供できますが、`AssumeRole` が返す一時的認証情報には MFA 情報は含まれません。この情報は、このポリシーの MFA 条件を満たすために必要です。