- 新しい順
- 投票が多い順
- コメントが多い順
Hello,
Thank you for sharing additional details.
I would like to mention ${transfer:*}
variables are not supported within policies attached to IAM Roles. Therefore, if you have them there, I would suggest you remove them as they won't be substituted. And as they are not substituted, S3 considers them as is which leads to Access Denied errors. Those variables are only applicable to Session Policies associated directly to the Transfer User or as part of their HomeDirectory configuration (Only ${transfer:Username}
for this case).
To your use-case, the ask is to have some sort of dynamic mapping based on the UserName, specifically the domain section to a similar named prefix in S3. In this case, I would suggest the Logical Directories approach and eliminate Session Policy troubles. Please refer the following workflow -
- Client connects to the server and Lambda eventually receives a request for the same.
- Lambda performs the necessary authentication checks with Okta and then starts to build up the response back to the server. [Assuming authentication succeeded]
- Within this response, you build the Logical Directory based off the domain within the Username section. Lambda should have access to the Username as it received authentication request. [Attaching a reference snippet below]
- Server receives the User configuration and maps the User to the Logical Directory.
Sample reference code snippet:
# parsing domain from Username
username = 'abc@xyz.com'
domain = username.split('@')[-1]
# building logical directory structure
# e = Entry - represents what the client sees when they login
# t = Target - represents the actual map in S3
e = '/' + domain
t = '/bucket/' + domain
h = '[{"Entry":"' + e + '", "Target":"' + t + '"}]'
print(h)
'[{"Entry":"/xyz.com", "Target":"/bucket/xyz.com"}]'
# Include h as HomeDirectoryDetails within User Configuration as part of response to the server
Considering permissions with above use-case, the IAM Role associated to the User would need permissions with explicitly defined resources i.e - actual bucket names and paths (Only the Access Policy section from this document). With Logical Directories in place, even if you define permissions for the entire bucket, the User would only have visibility for the Logical Directory defined.
References:
[1] https://docs.aws.amazon.com/transfer/latest/userguide/users-policies.html
[2] https://docs.aws.amazon.com/transfer/latest/userguide/logical-dir-mappings.html
Let me know if you have further questions.
-- Sagar
All set, your solution worked! I will go ahead and it as accepted. I am working on cleaning up the code by attempting to have the request URLs in an array, but that is not working. It appears to be a limitation with urllib
; anyway, that's another story for another day. Thanks a lot for all your help!
Hello,
Thank you for sharing all details. To your question on Transfer variables not substituting, I have a few follow up questions -
-
Do your transfer variables reside within the policy attached to the IAM Role associated with the Transfer User?
- If so, this is not supported. The Policy attached to the IAM Role should be explicit in terms of defining resources. What you want to do is to create a stand-alone policy with the variables and associate it directly with the User rather than the IAM role.
- There are 2 policies within the documentation that you linked - [1]. The Access policy is what defines access to the back-end storage - S3 in your case. This policy is required and without it, your Users wouldn't be able to access S3 resources. Here, you have to define permissions to the bucket resources based on your requirements and attach it to the IAM Role. You cannot use Transfer variables for this policy.
The second policy is the Session policy which is associated to the Transfer user directly and is evaluated real-time when the User logs in. This is where you can assign Transfer variables such as${transfer:HomeBucket}
,${transfer:HomeDirectory}
and others to restrict further access on top of the Access policy.
-
Does your setup potentially include double substitution? As in - You have defined your HomeDirectory value as -
/bucket/${transfer:Username}
. And then within the Policy field, you define permissions to the resource asarn:aws:s3:::${transfer:HomeDirectory}
.- In this scenario, when policy evaluation takes place, the Resource section is substituted to -
arn:aws:s3:::bucket/${transfer:UserName}
, however it then doesn't go ahead and substitute it further to the Username used during the session (ex -arn:aws:s3:::bucket/abc
). As the policy is now incorrect, S3 will then expectedly throw errors when the User tries to access objects. - The resolution to this would be to avoid the double substitution scenario. It would be to use a combination of variables to achieve the use-case. Example -
arn:aws:s3:::${transfer:HomeBucket}/${transfer:UserName}
. Therefore, when this is evaluated, it translates to -arn:aws:s3:::bucket/abc
.
- In this scenario, when policy evaluation takes place, the Resource section is substituted to -
And, adding to your ask of restricting Users to their HomeDirectory, I would suggest using Logical Directories as the way to move forward. Logical Directories provide chroot functionality which allows you to map your Users to a particular directory and keeps them isolated. Also, utilizing Logical Directories would eliminate the requirement of using Session policies. [2]
References:
[1] https://docs.aws.amazon.com/transfer/latest/userguide/users-policies.html
[2] https://docs.aws.amazon.com/transfer/latest/userguide/logical-dir-mappings.html
Let me know if you have questions.
-- Sagar
Hi Sagar. Thank you very much for responding! Yes, I currently have the transfer variables residing within the policy attached of the IAM Role. I also tried this with Logical Directories and ran into the same issue; my apologies, I should have mentioned that in the original post.
Based on your response, I am not exactly sure how this can be scalable. Essentially, I need the directories - or folders within the S3 bucket - to be dynamic for each user that is associated with a particular company based on the domain in their email address (and the folder name will match their domain). As an example, a user with domain 'xyz' in their email address will have access only to the 'xyz' folder within the S3 bucket.
We are leaving it up to the clients to set up their own users for SFTP transfers, so we don't know who those users will be ahead of time, and they can also add/subtract users as time goes on. That is why I was hoping to rely on the IAM Role with the attached inline Policy to decide which users should have access to which folders based on the Transfer Family variables within the Policy.
So I guess the question now is, how can I make this scalable for our situation? It looks like one method is to utilize ${transfer:UserName}
, but I really don't care about their username since I don't want each user to have their own folder; instead, I would just like all of the users within that company to have access to their own company folder and no other company's folder.
I hope this clarifies the problem that I am facing, and please let me know if there are any additional details that I can provide. Hopefully there is a sensible solution to this. Thanks again for all your help!
Thanks again, Sagar! I will give your suggestion a try and get back to you. Please allow me a few days to respond, as I am currently out of the office. Your responses are greatly appreciated, and I will follow up in the near future with the outcome!
Sagar, I haven't forgotten about this. I got pulled onto another project, so this one is on hold for the moment (hopefully not for too much longer). I will definitely circle back as soon as I can. Thank you!
Hi Sagar. The other project is now complete, so I will be jumping back to this one. I will follow up once I've had a chance to follow your instructions. Thanks a lot!
関連するコンテンツ
- AWS公式更新しました 3年前
Glad to hear that things are working. Do reach out if you have follow-ups.