Skip to content

Commit fdb7c24

Browse files
authored
Merge pull request #613 from iterate-ch/issue/349-s3-role-mfa
Add tutorial to access S3 by assuming role with MFA requirement.
2 parents 397d1f7 + 0dd81bd commit fdb7c24

File tree

7 files changed

+313
-5
lines changed

7 files changed

+313
-5
lines changed

protocols/s3/index.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,11 @@ Configure a bookmark with the field titled *Profile Name in` ~/.aws/credentials`
227227
`~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows. The properties `aws_access_key_id`,
228228
`aws_secret_access_key` and `aws_session_token` are supported.
229229

230-
You might be interested in scripts maintained by third parties to facilitate managing credentials
230+
:::{admonition} Tutorial
231+
:class: tip
231232

232-
- [Utilities for easy management of AWS MFA and role sessions and virtual MFA devices](https://github.com/vwal/awscli-mfa)
233+
Follow the [step-by-step instructions](../../tutorials/s3_iam_role_mfa.md) to require MFA by assuming a role to access S3.
234+
:::
233235

234236
#### AWS IAM Identity Center
235237

@@ -253,15 +255,29 @@ profile for both steps.
253255

254256
- [Configuring the AWS CLI to use AWS Single Sign-On](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html)
255257

256-
#### Connecting Using AssumeRole from AWS Security Token Service (STS)
258+
### Connecting Using AssumeRole from AWS Security Token Service (STS)
259+
260+
:::{admonition} Tutorial
261+
:class: tip
262+
263+
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.
264+
:::
265+
266+
:::{admonition} Tutorial
267+
:class: tip
268+
269+
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).
270+
:::
257271

258272
Instead of providing Access Key ID and Secret Access Key, authenticate using temporary credentials from AWS Security
259273
Token Service (STS) with optional Multi-Factor Authentication (MFA). Refer
260274
to [Using IAM Roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).
261275

262276
![MFA Token Prompt](_images/MFA_Token_Prompt.png)
263277

264-
You must provide configuration in the standard credentials property file `~/.aws/credentials` on macOS or
278+
- {download}`Download<https://profiles.cyberduck.io/AWS%20S3%20(STS%20Assume%20Role).cyberduckprofile>` the *AWS S3 (STS AssumeRole)* profile for preconfigured settings
279+
- {download}`Download<https://profiles.cyberduck.io/AWS%20S3%20(MFA%20Session%20Token).cyberduckprofile>` the *AWS S3 (MFA Session Token)* profile for preconfigured settings
280+
- {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
265281
`%USERPROFILE%\.aws\credentials` on Windows
266282
from [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html).
267283
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
284300
### Read Credentials from `~/.aws/credentials`
285301

286302
When editing a bookmark, the *Access Key ID* is set from the `default` profile in the credentials file located at
287-
`~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows if such a profile exists.
303+
`~/.aws/credentials` on macOS or `%USERPROFILE%\.aws\credentials` on Windows if such a profile exists or the profile name matching the .
288304

289305
### Connecting Without Using AWS credentials
290306

236 KB
Loading
209 KB
Loading
197 KB
Loading

tutorials/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Tutorials
66
:titlesonly:
77
hidden_properties
88
custom_oauth_client_id
9+
s3_iam_role_mfa
10+
s3_iam_getsessiontoken_bucketpolicy_mfa
911
iam
1012
vault_localdisk
1113
sftp_publickeyauth
@@ -23,6 +25,12 @@ Workaround to register your own Custom OAuth 2.0 Client ID for [Google Cloud Sto
2325
## [Add Hidden Configuration Options to Mountain Duck and Cyberduck](hidden_properties.md)
2426
Configure hidden preferences.
2527

28+
## [Connect to S3 with assuming role requiring MFA input](s3_iam_role_mfa.md)
29+
Require user to use MFA when connecting to S3 by connecting with IAM role assumed with AWS Security Token Service (STS).
30+
31+
## [Connect to S3 with temporary session token and MFA input](s3_iam_role_mfa.md)
32+
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).
33+
2634
## [AWS Identity & Access Management (IAM)](iam.md)
2735
IAM allows you to create credentials for third parties accessing your S3 account with permission constraints.
2836

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
Configure a user in AWS IAM that is required to use MFA to connect to a bucket in S3 with a policy requiring MFA
2+
====
3+
4+
> You want an IAM user with permissions to access S3 to require input from a MFA device when opening a specific bucket.
5+
> Create a configuration for AWS CLI that is supported in Cyberduck and Mountain Duck using
6+
> the [S3 (Credentials from AWS Command Line Interface) connection profile](../protocols/s3/index.md#connecting-using-credentials-from-aws-command-line-interface)
7+
> or use
8+
> the [AWS S3 (MFA Session Token) connection profile](../protocols/s3/index.md#connecting-using-assumerole-from-aws-security-token-service-sts)
9+
> with no additional configuration.
10+
11+
12+
:::{important}
13+
14+
* Cyberduck [8.3.0](https://cyberduck.io/changelog/) or later required
15+
* Mountain Duck [5.2.0](https://mountainduck.io/changelog/) or later required
16+
:::
17+
18+
## Create a bookmark in Cyberduck or Mountain Duck
19+
20+
1. Open _Preferences… → Profiles_ in Cyberduck or Mountain Duck.
21+
2. Enable the *AWS S3 (MFA Session Token)* connection profile.
22+
3. Add a new [Bookmark](../cyberduck/bookmarks.md) in Cyberduck or Mountain Duck and choose *AWS S3 (MFA Session Token)*
23+
connection profile in the protocol dropdown.
24+
25+
## Create IAM user with access keys and MFA enabled
26+
27+
1. In AWS [IAM console](https://console.aws.amazon.com/iam/) create a new user.
28+
2. In _Security Credentials_, choose _Assign MFA device_
29+
3. In _Security Credentials_, choose _Create access key_
30+
31+
Ensure the attached policy for the user has S3 access IAM [
32+
`GetSessionToken`](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html) permissions.
33+
34+
## Add bucket policy to deny access to bucket with no MFA
35+
36+
1. In AWS [S3 console](https://console.aws.amazon.com/s3/) for a new or existing bucket, choose _Permissions_ and then
37+
_Bucket Policy_.
38+
2. Edit the bucket policy to require MFA for access.
39+
40+
```{code-block} json
41+
{
42+
"Version": "2012-10-17",
43+
"Id": "RequireMFAForS3Access",
44+
"Statement": [
45+
{
46+
"Sid": "DenyAllAccessWithoutMFA",
47+
"Effect": "Deny",
48+
"Principal": "*",
49+
"Action": "s3:*",
50+
"Resource": [
51+
"arn:aws:s3:::<BUCKET_NAME>",
52+
"arn:aws:s3:::<BUCKET_NAME>/*"
53+
],
54+
"Condition": {
55+
"BoolIfExists": {
56+
"aws:MultiFactorAuthPresent": "false"
57+
}
58+
}
59+
}
60+
]
61+
}
62+
```
63+
64+
## Connect to S3 using the bookmark
65+
66+
Using the AWS Security Token Service (STS) `GetSessionToken` API, temporary credentials are generated for the user from
67+
static access keys and a MFA device.
68+
69+
1. When not already configured in the bookmark, enter the static _Access Key ID_ and _Secret Access Key_ configured for
70+
the user.
71+
72+
2. Enter the MFA device identification when prompted.
73+
74+
:::{image} _images/S3_MFA_Device_Prompt.png
75+
:alt: MFA Device Prompt
76+
:width: 400px
77+
:::
78+
79+
:::{tip}
80+
Enter the identification number of the MFA device that is associated with the user. The value is either the serial
81+
number for a hardware device
82+
(such as `<code>GAHT12345678</code>`) or an Amazon Resource Name (ARN) for a virtual device (such as
83+
`<code>arn:aws:iam::123456789012:mfa/device</code>`)
84+
:::
85+
86+
3. Enter the one-time MFA code from your device when prompted.
87+
88+
:::{image} _images/S3_MFA_Code_Prompt.png
89+
:alt: MFA Code Prompt
90+
:width: 400px
91+
:::
92+
93+
:::{admonition} Troubleshooting
94+
:class: warning
95+
96+
### `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.`
97+
Attempted to connect to the bucket with access keys not obtained using `GetSessionToken` and MFA code.
98+
99+
### `The security token included in the request is invalid.`
100+
The access keys used to obtain temporary credentials from AWS Security Token Service (STS) are not valid.
101+
:::
102+
103+
104+
## References
105+
106+
- [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)
107+
- [Requiring MFA](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-MFA)

tutorials/s3_iam_role_mfa.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
Configure a user in AWS IAM that is required to use MFA to connect to S3
2+
====
3+
4+
> 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.
5+
6+
:::{important}
7+
* Cyberduck [8.3.0](https://cyberduck.io/changelog/) or later required
8+
* Mountain Duck [5.2.0](https://mountainduck.io/changelog/) or later required
9+
:::
10+
11+
:::{note}
12+
No custom configuration required with *AWS S3 (STS Assume Role)* connection profile available from _Preferences… → Profiles_.
13+
:::
14+
15+
## Create a bookmark in Cyberduck or Mountain Duck
16+
17+
1. Open _Preferences… → Profiles_ in Cyberduck or Mountain Duck.
18+
2. Enable the *AWS S3 (STS Assume Role)* connection profile.
19+
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.
20+
21+
## Create a user with both access keys and a MFA device configured
22+
23+
1. In AWS [IAM console](https://console.aws.amazon.com/iam/) create a new user. Do *not* grant this user any permissions for S3.
24+
2. In the _Security credentials_ tab, choose _Create access key_ and copy to the clipboard.
25+
3. Enter access key ID and secret access key in the bookmark.
26+
4. Assign a MFA device to the user in _Multi-factor authentication (MFA)_.
27+
28+
:::{tip}
29+
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.
30+
:::
31+
5. Copy the MFA device ARN to the clipboard.
32+
33+
## Create IAM role allowing access to S3 enforcing the MFA requirement
34+
35+
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.
36+
37+
```{code-block} json
38+
{
39+
"Version": "2012-10-17",
40+
"Statement": [
41+
{
42+
"Effect": "Allow",
43+
"Principal": {
44+
"AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<S3_USER>"
45+
},
46+
"Action": "sts:AssumeRole",
47+
"Condition": {
48+
"Bool": { "aws:MultiFactorAuthPresent": "true" }
49+
}
50+
}
51+
]
52+
}
53+
```
54+
55+
2. Copy the Role ARN to the clipboard.
56+
3. Attach a permission policy to the role that grants access to S3 such as the managed policy `AmazonS3FullAccess`.
57+
58+
```{code-block} json
59+
{
60+
"Version": "2012-10-17",
61+
"Statement": [
62+
{
63+
"Effect": "Allow",
64+
"Action": [
65+
"s3:*"
66+
],
67+
"Resource": "*"
68+
}
69+
]
70+
}
71+
```
72+
73+
Restrict the permissions as necessary.
74+
75+
## Add inline policy to allow the user to assume the role with `sts:AssumeRole`
76+
77+
1. Navigate to the previously added IAM user to attach the `sts:AssumeRole` permission as an inline policy.
78+
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.
79+
80+
```{code-block} json
81+
{
82+
"Version": "2012-10-17",
83+
"Statement": [
84+
{
85+
"Effect": "Allow",
86+
"Action": "sts:AssumeRole",
87+
"Resource": "arn:aws:iam::<Account ID>:role/S3-ROLE-NAME"
88+
}
89+
]
90+
}
91+
```
92+
93+
## Connect to S3 using the bookmark
94+
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.
95+
96+
:::{image} _images/S3_AssumeRole_Login_Prompt.png
97+
:alt: Login Prompt
98+
:width: 400px
99+
:::
100+
101+
2. Enter the MFA device identification when prompted.
102+
103+
:::{image} _images/S3_MFA_Device_Prompt.png
104+
:alt: MFA Device Prompt
105+
:width: 400px
106+
:::
107+
108+
:::{tip}
109+
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
110+
(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>`)
111+
:::
112+
113+
3. Enter the one-time MFA code from your device when prompted.
114+
115+
:::{image} _images/S3_MFA_Code_Prompt.png
116+
:alt: MFA Code Prompt
117+
:width: 400px
118+
:::
119+
120+
121+
:::{admonition} Troubleshooting
122+
:class: warning
123+
### `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.`
124+
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.
125+
126+
### `The security token included in the request is invalid.`
127+
The AWS access key ID and secret access key set for the bookmark are invalid.
128+
129+
### `MultiFactorAuthentication failed with invalid MFA one time pass code.`
130+
The one-time MFA code already expired or is invalid.
131+
:::
132+
133+
## Alternative: Using AWS CLI Configuration
134+
135+
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.
136+
137+
1. Copy the Access Key ID and Secret Access Key to a profile in `~/.aws/credentials`
138+
139+
```{code-block} properties
140+
[<S3_USER>]
141+
aws_access_key_id=AKIA…
142+
aws_secret_access_key=…
143+
```
144+
145+
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.
146+
```{code-block} properties
147+
[<S3-ROLE-NAME>]
148+
source_profile=<S3_USER>
149+
role_arn=arn:aws:iam::<Account ID>:role/<S3-ROLE-NAME>
150+
mfa_serial=arn:aws:iam::<Account ID>:mfa/<MFA-DEVICE-NAME>
151+
```
152+
153+
3. Enter the alias `<S3-ROLE-NAME>` for the role configuration from your AWS CLI configuration in _Server_ of the bookmark.
154+
155+
156+
## Alternative: Use Custom Connection Profile
157+
158+
1. Add the `role_arn` and `mfa_serial` to a [custom connection profile](../protocols/profiles/index.md) to skip the prompts on connect.
159+
```{code-block}
160+
<key>Role Configurable</key>
161+
<true/>
162+
<key>Multi Factor Configurable</key>
163+
<true/>
164+
<key>Properties</key>
165+
<dict>
166+
<!-- Can be left blank to require Role ARN input from user -->
167+
<key>role_arn</key>
168+
<string>arn:aws:iam::<Account ID>:role/<S3-ROLE-NAME></string>
169+
<!-- Can be left blank to require MFA ARN input from user when assuming role requires token from MFA -->
170+
<key>mfa_serial</key>
171+
<string>arn:aws:iam::<Account ID>:mfa/<MFA-DEVICE-NAME></string>
172+
</dict>
173+
```
174+
175+
## References
176+
177+
- [Assuming a Role](https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html).

0 commit comments

Comments
 (0)