Minimum permissions required by AWS role
I am using the new --awsEc2ProfileArn option to specify the AWS role when launching a cluster (thanks to @arostamianfar). I have a policy that's working, but would like to tighten it down further if possible. I also suggest that the set of required permissions when specifying a pre-created role would be a useful addition to the documentation. Has anyone already explored what the minimum set is? Below is what I have so far for the policy. I will almost certainly have to tighten this down further by specifying specific resources rather than "Resource": "*", but this set is at least working.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:CancelSpotInstanceRequests",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteSecurityGroup",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeKeyPairs",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeVolumes",
"ec2:RequestSpotInstances",
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"iam:PassRole"
"s3:AbortMultipartUpload",
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectVersionTagging",
"s3:HeadBucket",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
"s3:ListMultipartUploadParts",
"s3:PutBucketTagging",
"s3:PutBucketVersioning",
"s3:PutObject",
"s3:PutObjectTagging",
"s3:PutObjectVersionTagging",
"s3:ReplicateTags",
"sdb:*",
],
"Resource": "*"
}
]
}
┆Issue is synchronized with this Jira Task ┆Issue Number: TOIL-375
@tthyer glad to hear you found the new feature useful! I owe a documentation on the new flag (I was originally planning to add it as part of other changes, but got distracted). Will prioritize adding docs soon.
Regarding the minimum permission set: I think your set is already much tighter than what was previously set by default! I'm not sure if anyone has looked into the absolute minimum permission set. @DailyDreaming do you know? If not, I think we could actually publish yours, @tthyer?
If @DailyDreaming doesn't have a minimal list, I believe I can find the time to experiment with what I posted above and eliminate more prior to publishing.
@arostamianfar I don't have a minimum list unfortunately.
@tthyer I'd be very interested in your results. Please keep us updated and thank you for experimenting. :)
Hi, I'd like to give an update on this. This isn't "the" minimum list as there are different ways of solving this problem, but I have narrowed down the permissions considerably. Some of the permissions are only necessary if using spot instances. Also, the way I approached the S3 permissions is to give the role access only to buckets that are named with a certain prefix. That's fine for the buckets created by the toil leader node, but means the output bucket must also follow that naming convention, or one could just add an additional entry to the Resource list for any other buckets. A similar strategy was followed for SDB permissions.
We have been actively using this for the last several months. It's used in conjunction with another policy that has "ec2:Describe*", but based on what I see in CloudTrail, I think all the necessary Describe permissions are in the current ClusterPolicy.
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ClusterName:
Description: Name of the cluster that will use these resources.
Type: String
Resources:
ClusterRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- !Ref ClusterPolicy
ClusterInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref ClusterRole
ClusterPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: Minimal permissions for toil instances.
Path: "/"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ec2:AuthorizeSecurityGroupIngress
- ec2:CancelSpotInstanceRequests
- ec2:CreateSecurityGroup
- ec2:CreateTags
- ec2:DeleteSecurityGroup
- ec2:DescribeAvailabilityZones
- ec2:DescribeImages
- ec2:DescribeInstances
- ec2:DescribeInstanceStatus
- ec2:DescribeKeyPairs
- ec2:DescribeSecurityGroups
- ec2:DescribeSpotInstanceRequests
- ec2:DescribeSpotPriceHistory
- ec2:DescribeVolumes
- ec2:ModifyInstanceAttribute
- ec2:RequestSpotInstances
- ec2:RunInstances
- ec2:StartInstances
- ec2:StopInstances
- ec2:TerminateInstances
- iam:PassRole
Resource: "*"
- Effect: Allow
Action:
- s3:*
Resource:
- !Sub "arn:aws:s3:::${ClusterName}*"
- !Sub "arn:aws:s3:::${ClusterName}*/*"
- Effect: Allow
Action:
- sdb:*
Resource:
- !Sub "arn:aws:sdb:${AWS::Region}:${AWS::AccountId}:domain/${ClusterName}*"
- !Sub "arn:aws:sdb:${AWS::Region}:${AWS::AccountId}:domain/toil-registry"
Outputs:
ToilClusterRole:
Description: Role for toil instances.
Value: !Ref ClusterRole
Export:
Name: !Sub "${AWS::Region}-${AWS::StackName}-ToilClusterRole"
ToilClusterRoleArn:
Description: Role for toil instances.
Value: !GetAtt ClusterRole.Arn
Export:
Name: !Sub "${AWS::Region}-${AWS::StackName}-ToilClusterRoleArn"
ToilClusterInstanceProfile:
Description: Instance Profile for toil instances.
Value: !Ref ClusterInstanceProfile
Export:
Name: !Sub "${AWS::Region}-${AWS::StackName}-ToilClusterInstanceProfile"
ToilClusterInstanceProfileArn:
Description: Instance Profile for toil instances.
Value: !GetAtt ClusterInstanceProfile.Arn
Export:
Name: !Sub "${AWS::Region}-${AWS::StackName}-ToilClusterInstanceProfileArn"
We currently have a list of permissions we sniff for having when launching clusters, and a list of permissions we grant to the cluster nodes, but it looks like we could tighten the permissions (and also grant each cluster only access to manipulate its own resources) if we adopted a policy template like this.
It's not clear to me how we would go about applying the YAML (and substituting in the cluster name permission) from within the Python Boto 3 IAM API. Someone would need to work that out.