AWS IAM Policies for Yarkon

AWS IAM policies can be a complex matter. There is a lot of power and flexibility, but things can get complicated.

Use this page as a reference for some of the basic and most commonly used policies for Yarkon. You can use them as-is, or as a starting point for your own customization.

In general, the IAM policies used by Yarkon are similar when using the shared Yarkon Cloud or the self-hosted Yarkon Server. The one notable difference is the IAM role used to run the Yarkon service. When using Yarkon Cloud, together with the Integrated Security model, you have to create that IAM role (see below for more details). The self hosted Yarkon Server will have the role automatically created for you by the one-click CloudFormation template used to set up Yarkon, and will also set the EC2 to run under this role.

Shared Security

Basic

Use this starter policy together with Yarkon Cloud and the Shared Security model. It gives all users access to all buckets, and allows all actions. It makes it good to get things going out of the gate, but after you see it in action, you'd probably want to lock things done and limit the permissions allowed to your end users.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

In all policies shown here, make sure to replace the <account-number> with your AWS account number. Your AWS account number is a 12 digit account ID. See this document from Amazon in case you do not have this ID handy.

Specific buckets

Use this policy together with Yarkon Cloud and the Shared Security model. It gives all users access to two specific buckets (in this sample, they are yarkons3-finance and yarkons3-sales), and allows all actions on objects in these two buckets. This approach is good for most organizations where you want to give all users the same level of access, to a set of buckets used for documents.

The CORS permissions are required by the Admin Console in case you need to enable CORS on some or all of the buckets.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowServerToListBuckets",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Sid": "AllowServerToListSpecificBuckets",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "OptionalAllowAdvancedOptions",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketTagging",
                "s3:PutBucketTagging",
                "s3:GetAccelerateConfiguration",
                "s3:PutAccelerateConfiguration"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "OptionalAllowServerToAutomaticallyUpdateCORS",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketCORS",
                "s3:PutBucketCORS"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "AllowUsersAllActionsInBuckets",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::yarkons3-finance/*",
                "arn:aws:s3:::yarkons3-sales/*"
            ]
        }
    ]
}

Limited permissions

In most cases, you would not want your end users to have permissions to allow all S3 actions. The below is a sample policy limiting the user permissions over buckets and objects (documents) to the bare minimum that is required by Yarkon.

Note: you still have to enable CORS on the buckets. For the Admin Console to be able to do it, the CORS permissions must be granted. You can do it and then remove the permissions to ensure the end users cannot do it. The CORS permissions are s3:GetBucketCORS and s3:PutBucketCORS and have to be given on any bucket you'd like to update.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowServerToListBuckets",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Sid": "AllowServerToListSpecificBuckets",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "OptionalAllowServerToAutomaticallyUpdateCORS",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketCORS",
                "s3:PutBucketCORS"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance",
                "arn:aws:s3:::yarkons3-sales"
            ]
        },
        {
            "Sid": "AllowUsersToUpdateDocumentsInBuckets",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::yarkons3-finance/*",
                "arn:aws:s3:::yarkons3-sales/*"
            ]
        }
    ]
}

Integrated/Federated Security

The following policies are meant to accompany a dedicated AWS user, created for the Yarkon Admin Console. See the Getting Started Guide for the details on how to use it. If you are using Yarkon Cloud, make sure to complete the guide on setting up the IAM role and policies for Yarkon Cloud.

Either the Integrated Security Model or the Federated Security Model allow you to set up different permissions to different users or groups. The aforementioned Yarkon Admin Console dedicated AWS user should be assigned its own IAM Role with the below permissions. Then, you grant permissions to end users using the standard IAM policies, through user and group policies (inline or attached).

IAM Role

When you set up Yarkon Server from an AMI, the AWS IAM policy for the IAM EC2 Machine Role required is automatically set up for you, so you can focus on the group and user policies. The role policy is available here for your reference only.

The SES permissions are only used by the Admin Console in case you use SES to send welcome and password reset emails. You can remove them if you are not planning to use SES to send email.

{
    "Version": "2012-10-17",
    "Statement": [{
            "Sid": "AllowAllS3Actions",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::*"
        }, {
            "Sid": "AllowUIToDisplayIAMOptions",
            "Effect": "Allow",
            "Action": [
                "iam:List*",
                "iam:Get*"
            ],
            "Resource": "arn:aws:iam::<account-number>:*"
        }, {
            "Sid": "AllowTheRoleToGetPermissions",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<account-number>:role/yarkon-console-role"
        }, {
            "Sid": "AllowTheRoleToFederate",
            "Effect": "Allow",
            "Action": [
                "sts:GetFederationToken"
            ],
            "Resource": "arn:aws:sts::<account-number>:*"
        }, {
            "Sid": "AllowUsingSESForEmail",
            "Effect": "Allow",
            "Action": "ses:SendRawEmail",
            "Resource": "*"
        }
    ]
}

When using Yarkon Cloud, you have to create this role yourself, and ensure the trust is set up correctly, as following. This was covered in the guide on setting up the IAM role and policies for Yarkon Cloud.

If you prefer to set the IAM permissions required for the admin console explicitly, instead of using IAM:List* and such, this is the minimal set of permissions required:

{
    "Version": "2012-10-17",
    "Statement": [{
            "Sid": "AllowAllS3Actions",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::*"
        }, {
            "Sid": "AllowUIToDisplayIAMOptions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListUserPolicies",
                "iam:ListAttachedUserPolicies",
                "iam:ListGroupsForUser",
                "iam:ListGroupPolicies",
                "iam:ListAttachedGroupPolicies",
                "iam:ListRoles",
                "iam:ListRolePolicies",
                "iam:ListAttachedRolePolicies",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:GetUserPolicy",
                "iam:GetGroupPolicy",
                "iam:GetRolePolicy"
            ],
            "Resource": "arn:aws:iam::<account-number>:*"
        }, {
            "Sid": "AllowTheRoleToGetPermissions",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<account-number>:role/yarkon-console-role"
        }, {
            "Sid": "AllowTheRoleToFederate",
            "Effect": "Allow",
            "Action": [
                "sts:GetFederationToken"
            ],
            "Resource": "arn:aws:sts::<account-number>:*"
        }, {
            "Sid": "AllowUsingSESForEmail",
            "Effect": "Allow",
            "Action": "ses:SendRawEmail",
            "Resource": "*"
        }
    ]
}

These IAM permissions are only used by the Admin Console to help the administrator set up user accounts. End users never get these permissions.

User policy

The below user policy is a sample showing how to limit the access of a user to a specific bucket - just rename the <bucket-name> place-holder in the policy to your bucket name. The policy can be inline or attached.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::<bucket-name>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        }
    ]
}

Group policy

The below group policy is a sample showing how to limit access of group members to a specific bucket - just rename the <bucket-name> place-holder in the policy to your bucket name. The policy can be inline or attached.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::<bucket-name>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        }
    ]
}

Folder level permissions

AWS IAM allows great flexibility. The following annotated example policy shows how to create a policy that allows a user full access to a specific folder only, while disallowing any access, not even listing, of any other folder. In this case, the folder was named based on the user name, and is placed in a shared home folder.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToSeeHomeBucket",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::<bucket-name>"
            ]
        },
        {
            "Sid": "AllowSeeingUserFolder",
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::<bucket-name>",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": "home/john/",
                    "s3:delimiter": [
                        "/"
                    ]
                }
            }
        },
        {
            "Sid": "AllowListingOfUserFolder",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::<bucket-name>"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "home/john/*"
                    ]
                }
            }
        },
        {
            "Sid": "AllowAllS3ActionsInUserFolder",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::<bucket-name>/home/john/*"
            ]
        }
    ]
}

Yarkon respects the standard AWS substitution for a user name ${aws:username}, so it you have AWS user names defined for the users, you can use a single policy to handle all users.

Shared bucket for B2B

Suppose you are using Yarkon for your business and your end users work for vendors that are clients of yours. You want to have all your vendors using a single bucket named acme-vendors, with each having their own folder in it, but without allowing one vendor to see, or even know, about any other vendor.

While completely fulfilling this requirement is actually not possible with IAM, it is definitely possible with Yarkon, thanks to the extra policy processing handled by the Yarkon server application. To illustrate how this would be done, consider the following sample structure:

  • acme-vendors (bucket)
    • acme-vendor-east (folder)
      • CT (folder)
      • NJ (folder)
      • NY (folder)
    • acme-vendor-central (folder)
      • CO (folder)
      • KY (folder)
      • TX (folder)
    • acme-vendor-west (folder)
      • CA (folder)
      • OR (folder)
      • WA (folder)

And suppose you need the following roles defined:

  • An administrator user to manage all vendors, with full access to all folders.
  • An administrator user for each vendor, with full access to the vendor folder and its sub-folders.
  • An end user for each vendor, with limited read only access to the vendor folder and its sub-folders.

The following policies will get the job done (shown for acme-vendor-east only, it is similar for the others).

The policy for the system administrator:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToSeeLocationOfBucket",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::acme-vendors"
            ]
        },
        {
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::acme-vendors"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::acme-vendors/*"
            ]
        }
    ]
}

The policy for the vendor's administrator:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToSeeLocationOfBucket",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::acme-vendors"
            ]
        },
        {
            "Sid": "AllowRootAndHomeListingOfVendorsBucket",
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::acme-vendors",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": "acme-vendor-east/",
                    "s3:delimiter": [
                        "/"
                    ]
                }
            }
        },
        {
            "Sid": "AllowListingOfUserFolder",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::acme-vendors"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "acme-vendor-east/*"
                    ]
                }
            }
        },
        {
            "Sid": "AllowAllS3ActionsInUserFolder",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::acme-vendors/acme-vendor-east/*"
            ]
        }
    ]
}

The policy for the vendor's end user:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToSeeLocationOfBucket",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::acme-vendors"
            ]
        },
        {
            "Sid": "AllowRootAndHomeListingOfVendorsBucket",
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::acme-vendors",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": "acme-vendor-east/",
                    "s3:delimiter": [
                        "/"
                    ]
                }
            }
        },
        {
            "Sid": "AllowListingOfUserFolder",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::acme-vendors"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "acme-vendor-east/*"
                    ]
                }
            }
        },
        {
            "Sid": "AllowReadOnlyS3ActionsInUserFolder",
            "Effect": "Allow",
            "Action": [
                "s3:head*",
                "s3:get*"
            ],
            "Resource": [
                "arn:aws:s3:::acme-vendors/acme-vendor-east/*"
            ]
        }
    ]
}

Note that the Yarkon Web Application, when used by an end user that belongs to this vendor, will see the folder acme-vendor-east as the root, and not the bucket.

You can use these policies as a basis for more advanced variations of this approach.

Home folder for Users

With AWS S3 conditional policies, you can set up a "home" folder for users, a folder where only they would have access, or maybe set up read-write permission for the owner user, and read-only access for anyone else.

To implement this structure, use the {aws:username} parameter, like so:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "",
                        "home/",
                        "home/${aws:username}/*"
                    ],
                    "s3:delimiter": "/"
                }
            },
            "Resource": "arn:aws:s3:::<bucket-name>"
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetBucketLocation",
            "Resource": "arn:aws:s3:::<bucket-name>"
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<bucket-name>/home/${aws:username}/*"
        }
    ]
}

Note that this policy is for Yarkon. It won't work as-is for AWS S3.