Scalable S3 Fine Grain Access Control

Cloud Journey
7 min readMar 13, 2022

--

Overview

In this blog post, we will discuss:

  • Why we need AWS S3 fine grain access control
  • What are the available S3 IAM security features to support least privilege and separate duty
  • S3 FGAC in the context of AWS transfer for SFTP

Individual Level Data Access

We need fine grain access control to protect data, specific data would be used only for specific users, this is especially true for shared data sets for a centralized enterprise solution.

In centralized solution, typically we have following scenarios:

  • Subset of data is shared across multiple apps
  • Subset of data is scoped to a specific app only
  • Admin manages solution control plane only and no view on any data

S3 IAM Features

In terms of S3 access control, AWS provides rich features:

  • S3 access control lists (ACLs)
  • IAM Policy
  • Bucket Policy
  • S3 Access Point
  • S3 Access Point Alias
  • IAM Permission Boundary

S3 ACL is not recommended, Objects in this bucket can be owned by other AWS accounts. Access to this bucket and its objects can be specified using ACLs. AWS generally recommend to disable S3 ACL.

IAM policy can be attached to IAM user or IAM role. When you need to grant different permission for thousands of users, you could possibility utilize IAM policy, chances are you will use IAM policy to grant common services permission, and use resource policy for fine grain access control for the specific resource.

S3 bucket policy is resource policy, but bucket policy is limited to 20 KB in size. As an application set grows, the bucket policy becomes more complex, time consuming to manage, and needs to be audited to make sure that changes don’t have an unexpected impact on another application.

You can create access points with tailored read or write access for each team within the organization, or limit access to a bucket through access points that are restricted to a VPC.

So what’s the easiest and scalable way to do S3 fine grain access control? With Amazon S3 access points, you can create unique access control policies for each access point to easily control access to shared datasets.

Aliases for S3 Access Points are automatically generated and are interchangeable with S3 bucket names anywhere you use a bucket name for data access. You can use an Access Point alias anywhere a bucket name is used today to perform object-level operations such as PUT, GET, LIST, and more.

S3 Access Points Examples

Combined IAM role, bucket policy and access point policy together, we can effectively lock down the access through access point and each application team has its own customized access point policy.

S3 bucket policies and S3 Access Point policies result in an intersection of the permissions granted by the bucket policy and the Access Point policy.

Bucket Policy:

In this example S3 bucket policy, we lock down the access to a specific identity (role), a specific S3 prefix and access point only in <my account>.

Whoever assumes <my role> can only get object from folder <prefix> through access point.

{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<my account>:role/<my role>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<my bucket>/prefix/*",
"Condition": {
"StringEquals": {
"s3:DataAccessPointAccount": "<my account>"
}
}
}
]
}

Note: s3:DataAccessPointAccount

This is a string operator that you can use to match on the account ID of the owner of an access point. The above example matches all access points owned by AWS account <my account>.

S3 Access Point Policy:

This access point policy locks down access to a specific role, a specific access point and specific prefix.

That means when accessing through this access point’s alias, only <my role> is allowed to access <my prefix>.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<my account>:role/<my role>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:us-east-1:<my account>:accesspoint/<my access point>/object/<my prefix>/*"
}
]
}

Local Account IAM role:

In <my account> create <my role> with following permission and trust relationship.

Permission:{
"Version": "2012-10-17",
"Statement": {
"Action": [
"s3:GetAccessPoint",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListBucket",
"s3:HeadBucket"
],
"Resource": "*",
"Effect": "Allow"
}
}
Trusted entities:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<other account>:root"
},
"Action": "sts:AssumeRole"
}
]
}

Other Account IAM Role

In other account IAM role, you need allow to assume <my role> of <my account>.

Permissions:
{
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<my account>:role/<my role>",
"Effect": "Allow"
}
}

S3 Access Point Validation

In other account, you are authenticated and already assumed the “other account IAM role”, then you may select switch role, input <my account> and <my role>.

After switch the role, you may validate S3 access, when accessing from bucket name, the access is denied.

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>H4G9X3Q2PQ...</RequestId>
<HostId>VtHp88d3gM0+NT1rmuTZ0XWu/UglwHKsBOIKn97KvIenxSoUUD3yJJUmZ+ce....</HostId>
</Error>

When accessing from S3 access point, we are able to download.

AWS Transfer and S3 Access Points

When you choose to use shared S3 for your AWS transfer service, instead of bucket name, you can use S3 access point alias in AWS transfer for SFTP user logical directory.

You achieve customized S3 permission per SFTP user through access point, without managing multiple IAM roles or complex S3 bucket policy.

IAM Role for AWS Transfer

When create AWS transfer SFTP user, you associate an IAM role which grants S3 access. The IAM policy which is attached to the role requires S3 list access point permission.

Bucket Policy

In the bucket policy of the shared S3 for your AWS transfer service, you may lock down accessing only through S3 access point for the IAM roles.

The the option for forcing the access through access point is to use AWS transfer feature, AWS transfer user logical directory mapping. When create AWS transfer SFTP user, define logical directory mapping and points to S3 access point alias instead of bucket name.

S3 Access Point Policy

This is an example policy which denies put and delete permission on any S3 objects when accessing through read-only-ap access point.

{ 
"Version": "2012-10-17",
"Statement" : [
{
"Effect": "Deny",
"Principal" : {
"*"
},
"Action": ["s3:PutObject","s3:DeleteObject"],
"Resource":"arn:aws:s3:region:123456789012:accesspoint/read-only-ap/object/*"
}
]
}

AWS Transfer for SFTP Logical Directory

Ben is not allowed to write to “shared” folder, since Ben’s “shared” folder is mapped to alias of access point read-only-ap, and the access point policy denies the write permission.

aws transfer create-user --server-id server-id --user-name ben --ssh-public-
key-body key --role role --home-directory-type LOGICAL --home-directory-mapping
‘[{"Entry": "/", "Target": "/bucket-name/external/ben"},
{"Entry": "/ben", "Target": "/bucket-name/external/ben"},
{"Entry": "/shared", "Target": "/read-only-ap-METADATA-s3alias/shared"}]’

AWS Transfer for SFTP Logical Directly chroot

When use logical directory, some SFTP clients still allow the user to traverse up a folder, to protect bucket visibility, home directory is set to “Restricted”.

In AWS CLI, there is no specific option exactly like “restricted”, once you have entry ‘/’, it’s restricted.

aws transfer create-user — server-id <server-id> — user-name <username> — home-directory-type LOGICAL — home-directory-mappings Entry=’/’,Target=’/bucket/folder’ — role <iam-role-arn>

Permission Boundary

When delegate IAM role creation, but you want to control the excessive permission for the IAM role which is associated with AWS transfer SFTP user, you could utilize permission boundary.

You first create <pre-defined-boundary> customer managed IAM policy, which is the maximum IAM permission you want to enforce for the SFTP users.

The delegated user can only create IAM role MyTestApp* when <pre-defined-boundary> policy is attached to the new role, this is done through the string condition.

Even though you could attach other IAM policy with more permission, but the actual permission is the intersection of IAM policy and permission boundary.

Below is an example IAM policy for the delegated user, the user has permission to create IAM role for onboarding AWS transfer SFTP user, but the the new IAM role is mandatory to have the the permission boundary.

{
"Version" : "2012-10-17",
"Statement" : [
{
"Sid": "SetPermissionsBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy"
],
"Resource": "arn:aws:iam::<ACCOUNT_NUMBER>:role/MyTestApp*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary":
"arn:aws:iam::<ACCOUNT_NUMBER>:policy/<pre-defined-boundary>"}}
},
{
"Sid": "CreateAndEditPermissionsPolicy",
"Effect": "Allow",
"Action": [
"iam:CreatePolicy",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion"
],
"Resource": "arn:aws:iam::<ACCOUNT_NUMBER>:policy/MyTestApp*"
}
]
}

In <pre-defined-boundary> policy, you could apply the least privilege required by AWS transfer user and lock down to the specific AWS transfer S3 bucket only.

References

https://aws.amazon.com/about-aws/whats-new/2021/07/amazon-s3-access-points-aliases-allow-application-requires-s3-bucket-name-easily-use-access-point/

Easily Manage Shared Data Sets with Amazon S3 Access Points | AWS News Blog

Simplify your AWS SFTP Structure with chroot and logical directories | AWS Storage Blog (amazon.com)

Using AWS SFTP logical directories to build a simple data distribution service | AWS Storage Blog (amazon.com)

create-user — AWS CLI 2.4.25 Command Reference (amazonaws.com)

https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_iam-passrole-service.html

--

--

Cloud Journey
Cloud Journey

Written by Cloud Journey

All blogs are strictly personal and do not reflect the views of my employer. https://github.com/Ronnie-personal

Responses (2)