Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions protocols/s3/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -253,15 +255,29 @@ 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
to [Using IAM Roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).

![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<https://profiles.cyberduck.io/AWS%20S3%20(STS%20Assume%20Role).cyberduckprofile>` the *AWS S3 (STS AssumeRole)* profile for preconfigured settings
- {download}`Download<https://profiles.cyberduck.io/AWS%20S3%20(MFA%20Session%20Token).cyberduckprofile>` the *AWS S3 (MFA Session Token)* profile for preconfigured settings
- {download}`Download<https://profiles.cyberduck.io/S3%20(Credentials%20from%20AWS%20Command%20Line%20Interface).cyberduckprofile>` 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
Expand All @@ -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

Expand Down
Binary file added tutorials/_images/S3_AssumeRole_Login_Prompt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorials/_images/S3_MFA_Code_Prompt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorials/_images/S3_MFA_Device_Prompt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions tutorials/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.

Expand Down
107 changes: 107 additions & 0 deletions tutorials/s3_iam_getsessiontoken_bucketpolicy_mfa.md
Original file line number Diff line number Diff line change
@@ -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:::<BUCKET_NAME>",
"arn:aws:s3:::<BUCKET_NAME>/*"
],
"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 `<code>GAHT12345678</code>`) or an Amazon Resource Name (ARN) for a virtual device (such as
`<code>arn:aws:iam::123456789012:mfa/device</code>`)
:::

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/<username> is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::<bucket>" 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)
177 changes: 177 additions & 0 deletions tutorials/s3_iam_role_mfa.md
Original file line number Diff line number Diff line change
@@ -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::<ACCOUNT_ID>:user/<S3_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 `<S3-ROLE-NAME>` 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::<Account ID>: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 `<code>GAHT12345678</code>`) or an Amazon Resource Name (ARN) for a virtual device (such as `<code>arn:aws:iam::123456789012:mfa/device</code>`)
:::

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::<ACCOUNT_ID>:user/<USERNAME> 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
[<S3_USER>]
aws_access_key_id=AKIA…
aws_secret_access_key=…
```

2. Copy the MFA ARN and reference it in the `mfa_serial` parameter in the `<S3-ROLE-NAME>` 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
[<S3-ROLE-NAME>]
source_profile=<S3_USER>
role_arn=arn:aws:iam::<Account ID>:role/<S3-ROLE-NAME>
mfa_serial=arn:aws:iam::<Account ID>:mfa/<MFA-DEVICE-NAME>
```

3. Enter the alias `<S3-ROLE-NAME>` 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}
<key>Role Configurable</key>
<true/>
<key>Multi Factor Configurable</key>
<true/>
<key>Properties</key>
<dict>
<!-- Can be left blank to require Role ARN input from user -->
<key>role_arn</key>
<string>arn:aws:iam::<Account ID>:role/<S3-ROLE-NAME></string>
<!-- Can be left blank to require MFA ARN input from user when assuming role requires token from MFA -->
<key>mfa_serial</key>
<string>arn:aws:iam::<Account ID>:mfa/<MFA-DEVICE-NAME></string>
</dict>
```

## References

- [Assuming a Role](https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html).
Loading