diff --git a/protocols/s3/index.md b/protocols/s3/index.md index dfb0f2a5..d91b75f5 100644 --- a/protocols/s3/index.md +++ b/protocols/s3/index.md @@ -227,9 +227,11 @@ Configure a bookmark with the field titled *Profile Name in` ~/.aws/credentials` `~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows. The properties `aws_access_key_id`, `aws_secret_access_key` and `aws_session_token` are supported. -You might be interested in scripts maintained by third parties to facilitate managing credentials +:::{admonition} Tutorial +:class: tip -- [Utilities for easy management of AWS MFA and role sessions and virtual MFA devices](https://github.com/vwal/awscli-mfa) +Follow the [step-by-step instructions](../../tutorials/s3_iam_role_mfa.md) to require MFA by assuming a role to access S3. +::: #### AWS IAM Identity Center @@ -253,7 +255,19 @@ profile for both steps. - [Configuring the AWS CLI to use AWS Single Sign-On](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) -#### Connecting Using AssumeRole from AWS Security Token Service (STS) +### Connecting Using AssumeRole from AWS Security Token Service (STS) + +:::{admonition} Tutorial +:class: tip + +Follow the [step-by-step instructions](../../tutorials/s3_iam_role_mfa.md) to require MFA with a user policy and connect by assuming a role from AWS Security Token Service (STS) granting access to S3. +::: + +:::{admonition} Tutorial +:class: tip + +Follow the [step-by-step instructions](../../tutorials/s3_iam_getsessiontoken_bucketpolicy_mfa.md) to require MFA with a bucket policy and connect using a session token from AWS Security Token Service (STS). +::: Instead of providing Access Key ID and Secret Access Key, authenticate using temporary credentials from AWS Security Token Service (STS) with optional Multi-Factor Authentication (MFA). Refer @@ -261,7 +275,9 @@ to [Using IAM Roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_u ![MFA Token Prompt](_images/MFA_Token_Prompt.png) -You must provide configuration in the standard credentials property file `~/.aws/credentials` on macOS or +- {download}`Download` the *AWS S3 (STS AssumeRole)* profile for preconfigured settings +- {download}`Download` the *AWS S3 (MFA Session Token)* profile for preconfigured settings +- {download}`Download` the *S3 (Credentials from AWS Command Line Interface) profile* to connect with settings from AWS CLI. You must provide configuration in the standard credentials property file `~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows from [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html). Configure a bookmark with the field titled *Profile Name in `~/.aws/credentials`* matching the profile name from @@ -284,7 +300,7 @@ mfa_serial=arn:aws:iam::123456789012:mfa/testuser ### Read Credentials from `~/.aws/credentials` When editing a bookmark, the *Access Key ID* is set from the `default` profile in the credentials file located at -`~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows if such a profile exists. +`~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows if such a profile exists or the profile name matching the . ### Connecting Without Using AWS credentials diff --git a/tutorials/_images/S3_AssumeRole_Login_Prompt.png b/tutorials/_images/S3_AssumeRole_Login_Prompt.png new file mode 100644 index 00000000..2861cc2b Binary files /dev/null and b/tutorials/_images/S3_AssumeRole_Login_Prompt.png differ diff --git a/tutorials/_images/S3_MFA_Code_Prompt.png b/tutorials/_images/S3_MFA_Code_Prompt.png new file mode 100644 index 00000000..44ec590f Binary files /dev/null and b/tutorials/_images/S3_MFA_Code_Prompt.png differ diff --git a/tutorials/_images/S3_MFA_Device_Prompt.png b/tutorials/_images/S3_MFA_Device_Prompt.png new file mode 100644 index 00000000..0e914b42 Binary files /dev/null and b/tutorials/_images/S3_MFA_Device_Prompt.png differ diff --git a/tutorials/index.md b/tutorials/index.md index 0c47e4fa..951601f9 100644 --- a/tutorials/index.md +++ b/tutorials/index.md @@ -6,6 +6,8 @@ Tutorials :titlesonly: hidden_properties custom_oauth_client_id +s3_iam_role_mfa +s3_iam_getsessiontoken_bucketpolicy_mfa iam vault_localdisk sftp_publickeyauth @@ -23,6 +25,12 @@ Workaround to register your own Custom OAuth 2.0 Client ID for [Google Cloud Sto ## [Add Hidden Configuration Options to Mountain Duck and Cyberduck](hidden_properties.md) Configure hidden preferences. +## [Connect to S3 with assuming role requiring MFA input](s3_iam_role_mfa.md) +Require user to use MFA when connecting to S3 by connecting with IAM role assumed with AWS Security Token Service (STS). + +## [Connect to S3 with temporary session token and MFA input](s3_iam_role_mfa.md) +Require user to use MFA when connecting to S3 bucket with policy requiring MFA by requesting temporary credentials obtained from IAM AWS Security Token Service (STS). + ## [AWS Identity & Access Management (IAM)](iam.md) IAM allows you to create credentials for third parties accessing your S3 account with permission constraints. diff --git a/tutorials/s3_iam_getsessiontoken_bucketpolicy_mfa.md b/tutorials/s3_iam_getsessiontoken_bucketpolicy_mfa.md new file mode 100644 index 00000000..3719c1f3 --- /dev/null +++ b/tutorials/s3_iam_getsessiontoken_bucketpolicy_mfa.md @@ -0,0 +1,107 @@ +Configure a user in AWS IAM that is required to use MFA to connect to a bucket in S3 with a policy requiring MFA +==== + +> You want an IAM user with permissions to access S3 to require input from a MFA device when opening a specific bucket. +> Create a configuration for AWS CLI that is supported in Cyberduck and Mountain Duck using +> the [S3 (Credentials from AWS Command Line Interface) connection profile](../protocols/s3/index.md#connecting-using-credentials-from-aws-command-line-interface) +> or use +> the [AWS S3 (MFA Session Token) connection profile](../protocols/s3/index.md#connecting-using-assumerole-from-aws-security-token-service-sts) +> with no additional configuration. + + +:::{important} + +* Cyberduck [8.3.0](https://cyberduck.io/changelog/) or later required +* Mountain Duck [5.2.0](https://mountainduck.io/changelog/) or later required + ::: + +## Create a bookmark in Cyberduck or Mountain Duck + +1. Open _Preferences… → Profiles_ in Cyberduck or Mountain Duck. +2. Enable the *AWS S3 (MFA Session Token)* connection profile. +3. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck or Mountain Duck and choose *AWS S3 (MFA Session Token)* + connection profile in the protocol dropdown. + +## Create IAM user with access keys and MFA enabled + +1. In AWS [IAM console](https://console.aws.amazon.com/iam/) create a new user. +2. In _Security Credentials_, choose _Assign MFA device_ +3. In _Security Credentials_, choose _Create access key_ + +Ensure the attached policy for the user has S3 access IAM [ +`GetSessionToken`](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html) permissions. + +## Add bucket policy to deny access to bucket with no MFA + +1. In AWS [S3 console](https://console.aws.amazon.com/s3/) for a new or existing bucket, choose _Permissions_ and then + _Bucket Policy_. +2. Edit the bucket policy to require MFA for access. + + ```{code-block} json + { + "Version": "2012-10-17", + "Id": "RequireMFAForS3Access", + "Statement": [ + { + "Sid": "DenyAllAccessWithoutMFA", + "Effect": "Deny", + "Principal": "*", + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::", + "arn:aws:s3:::/*" + ], + "Condition": { + "BoolIfExists": { + "aws:MultiFactorAuthPresent": "false" + } + } + } + ] + } + ``` + +## Connect to S3 using the bookmark + +Using the AWS Security Token Service (STS) `GetSessionToken` API, temporary credentials are generated for the user from +static access keys and a MFA device. + +1. When not already configured in the bookmark, enter the static _Access Key ID_ and _Secret Access Key_ configured for + the user. + +2. Enter the MFA device identification when prompted. + + :::{image} _images/S3_MFA_Device_Prompt.png + :alt: MFA Device Prompt + :width: 400px + ::: + + :::{tip} + Enter the identification number of the MFA device that is associated with the user. The value is either the serial + number for a hardware device + (such as `GAHT12345678`) or an Amazon Resource Name (ARN) for a virtual device (such as + `arn:aws:iam::123456789012:mfa/device`) + ::: + +3. Enter the one-time MFA code from your device when prompted. + + :::{image} _images/S3_MFA_Code_Prompt.png + :alt: MFA Code Prompt + :width: 400px + ::: + +:::{admonition} Troubleshooting +:class: warning + +### `User: arn:aws:iam::123456789012:user/ is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::" with an explicit deny in a resource-based policy.` +Attempted to connect to the bucket with access keys not obtained using `GetSessionToken` and MFA code. + +### `The security token included in the request is invalid.` +The access keys used to obtain temporary credentials from AWS Security Token Service (STS) are not valid. +::: + + +## References + +- [How do I require users from other AWS accounts to use MFA to access my Amazon S3 buckets?](https://repost.aws/knowledge-center/enforce-mfa-other-account-access-bucket) +- [Requiring MFA](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-MFA) \ No newline at end of file diff --git a/tutorials/s3_iam_role_mfa.md b/tutorials/s3_iam_role_mfa.md new file mode 100644 index 00000000..5aace5e6 --- /dev/null +++ b/tutorials/s3_iam_role_mfa.md @@ -0,0 +1,177 @@ +Configure a user in AWS IAM that is required to use MFA to connect to S3 +==== + +> You want an IAM user who cannot directly access S3, but instead must assume a role (with MFA required) to access S3 buckets in the same AWS account. Create a configuration for AWS CLI that is supported in Cyberduck and Mountain Duck using the [S3 (Credentials from AWS Command Line Interface) connection profile](../protocols/s3/index.md#connecting-using-credentials-from-aws-command-line-interface) or use the [S3 (STS Assume Role) connection profile](../protocols/s3/index.md#connecting-using-assumerole-from-aws-security-token-service-sts) with no additional configuration. + +:::{important} +* Cyberduck [8.3.0](https://cyberduck.io/changelog/) or later required +* Mountain Duck [5.2.0](https://mountainduck.io/changelog/) or later required + ::: + +:::{note} +No custom configuration required with *AWS S3 (STS Assume Role)* connection profile available from _Preferences… → Profiles_. +::: + +## Create a bookmark in Cyberduck or Mountain Duck + +1. Open _Preferences… → Profiles_ in Cyberduck or Mountain Duck. +2. Enable the *AWS S3 (STS Assume Role)* connection profile. +3. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck or Mountain Duck and choose *AWS S3 (STS Assume Role)* connection profile in the protocol dropdown. + +## Create a user with both access keys and a MFA device configured + +1. In AWS [IAM console](https://console.aws.amazon.com/iam/) create a new user. Do *not* grant this user any permissions for S3. +2. In the _Security credentials_ tab, choose _Create access key_ and copy to the clipboard. +3. Enter access key ID and secret access key in the bookmark. +4. Assign a MFA device to the user in _Multi-factor authentication (MFA)_. + + :::{tip} + To allow entering the code in Cyberduck or Mountain Duck when connecting, make sure to choose _Authenticator app_ or _Hardware TOTP token_ as a MFA device. Using Passkey MFA does not allow getting a numeric MFA code. + ::: +5. Copy the MFA device ARN to the clipboard. + +## Create IAM role allowing access to S3 enforcing the MFA requirement + +1. In AWS [IAM console](https://console.aws.amazon.com/iam/) create a new IAM role that has S3 permissions and requires MFA. The IAM role must have the trusted entity set to the previously created user's ARN. + + ```{code-block} json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam:::user/" + }, + "Action": "sts:AssumeRole", + "Condition": { + "Bool": { "aws:MultiFactorAuthPresent": "true" } + } + } + ] + } + ``` + +2. Copy the Role ARN to the clipboard. +3. Attach a permission policy to the role that grants access to S3 such as the managed policy `AmazonS3FullAccess`. + + ```{code-block} json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": "*" + } + ] + } + ``` + + Restrict the permissions as necessary. + +## Add inline policy to allow the user to assume the role with `sts:AssumeRole` + +1. Navigate to the previously added IAM user to attach the `sts:AssumeRole` permission as an inline policy. +2. Add a permission policy for the user by choosing _Add permissions → Create inline policy_ in the _Permissions_ tab. In the policy editor opened, add the action `sts:AssumeRole` for the resource ARN referencing the IAM role `` created previously allowing access to S3 with MFA. + + ```{code-block} json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRole", + "Resource": "arn:aws:iam:::role/S3-ROLE-NAME" + } + ] + } + ``` + +## Connect to S3 using the bookmark +1. When not already configured in the bookmark, enter the static AWS credentials for the user with the permission to assume the IAM role when prompted. + + :::{image} _images/S3_AssumeRole_Login_Prompt.png + :alt: Login Prompt + :width: 400px + ::: + +2. Enter the MFA device identification when prompted. + + :::{image} _images/S3_MFA_Device_Prompt.png + :alt: MFA Device Prompt + :width: 400px + ::: + + :::{tip} + Enter the identification number of the MFA device that is associated with the user. The value is either the serial number for a hardware device + (such as `GAHT12345678`) or an Amazon Resource Name (ARN) for a virtual device (such as `arn:aws:iam::123456789012:mfa/device`) + ::: + +3. Enter the one-time MFA code from your device when prompted. + + :::{image} _images/S3_MFA_Code_Prompt.png + :alt: MFA Code Prompt + :width: 400px + ::: + + +:::{admonition} Troubleshooting +:class: warning +### `User: arn:aws:iam:::user/ is not authorized to perform: s3:ListAllMyBuckets because no identity-based policy allows the s3:ListAllMyBuckets action.` +This error occurs when the user does not have permission to list all buckets in the account. Possibly no attempt to assume the role was made. + +### `The security token included in the request is invalid.` +The AWS access key ID and secret access key set for the bookmark are invalid. + +### `MultiFactorAuthentication failed with invalid MFA one time pass code.` +The one-time MFA code already expired or is invalid. +::: + +## Alternative: Using AWS CLI Configuration + +Alternatively use the *[S3 (Credentials from AWS Command Line Interface) profile](../protocols/s3/index.md#connecting-using-credentials-from-aws-command-line-interface)* to read values from the AWS CLI `~/aws/credentials` file. + +1. Copy the Access Key ID and Secret Access Key to a profile in `~/.aws/credentials` + + ```{code-block} properties + [] + aws_access_key_id=AKIA… + aws_secret_access_key=… + ``` + +2. Copy the MFA ARN and reference it in the `mfa_serial` parameter in the `` profile in `~/.aws/credentials`. This will require the user to enter a MFA code when assuming a role with a S3 access policy attached when connecting. + ```{code-block} properties + [] + source_profile= + role_arn=arn:aws:iam:::role/ + mfa_serial=arn:aws:iam:::mfa/ + ``` + +3. Enter the alias `` for the role configuration from your AWS CLI configuration in _Server_ of the bookmark. + + +## Alternative: Use Custom Connection Profile + +1. Add the `role_arn` and `mfa_serial` to a [custom connection profile](../protocols/profiles/index.md) to skip the prompts on connect. + ```{code-block} + Role Configurable + + Multi Factor Configurable + + Properties + + + role_arn + arn:aws:iam:::role/ + + mfa_serial + arn:aws:iam:::mfa/ + + ``` + +## References + +- [Assuming a Role](https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html).