IAM permissions¶
ray-vast uses two AWS identities:
- Your AWS user runs
ray-vast upandray-vast downon your laptop. - The head role is an IAM role that
upmakes for the EC2 head.
Your AWS user¶
You can use your own AWS credentials, for example an admin profile. Then the only setup is the boundary policy. Read Getting started.
For a restricted user, attach the policy ray-vast-user. It is in the package, in ray_vast/iam/ray-vast-user.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Read",
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"ec2:DescribeInstances",
"ec2:DescribeSecurityGroups",
"ec2:DescribeImages",
"ec2:DescribeKeyPairs"
],
"Resource": "*"
},
{
"Sid": "CreateTaggedSecurityGroups",
"Effect": "Allow",
"Action": "ec2:CreateSecurityGroup",
"Resource": "arn:aws:ec2:*:*:security-group/*",
"Condition": {"Null": {"aws:RequestTag/ray-vast-cluster": "false"}}
},
{
"Sid": "CreateSecurityGroupsInAnyVpc",
"Effect": "Allow",
"Action": "ec2:CreateSecurityGroup",
"Resource": "arn:aws:ec2:*:*:vpc/*"
},
{
"Sid": "CreateTaggedKeyPairs",
"Effect": "Allow",
"Action": "ec2:CreateKeyPair",
"Resource": "arn:aws:ec2:*:*:key-pair/ray-vast-*",
"Condition": {"Null": {"aws:RequestTag/ray-vast-cluster": "false"}}
},
{
"Sid": "RunTaggedInstances",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": ["arn:aws:ec2:*:*:instance/*", "arn:aws:ec2:*:*:volume/*"],
"Condition": {"Null": {"aws:RequestTag/ray-vast-cluster": "false"}}
},
{
"Sid": "RunInstancesWithTheseResources",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*::image/*",
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*:*:key-pair/ray-vast-*"
]
},
{
"Sid": "RunInstancesInRayVastGroups",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:security-group/*",
"Condition": {"Null": {"aws:ResourceTag/ray-vast-cluster": "false"}}
},
{
"Sid": "TagOnCreate",
"Effect": "Allow",
"Action": "ec2:CreateTags",
"Resource": "arn:aws:ec2:*:*:*/*",
"Condition": {"StringEquals": {"ec2:CreateAction": ["CreateSecurityGroup", "CreateKeyPair", "RunInstances"]}}
},
{
"Sid": "ChangeAndDeleteTaggedResources",
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:TerminateInstances",
"ec2:DeleteKeyPair"
],
"Resource": [
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:key-pair/ray-vast-*"
],
"Condition": {"Null": {"aws:ResourceTag/ray-vast-cluster": "false"}}
},
{
"Sid": "HeadRoleOnlyWithTheBoundary",
"Effect": "Allow",
"Action": ["iam:CreateRole", "iam:PutRolePolicy", "iam:DeleteRolePolicy", "iam:DeleteRole"],
"Resource": "arn:aws:iam::*:role/ray-vast-*",
"Condition": {"StringEquals": {"iam:PermissionsBoundary": "arn:aws:iam::${aws:PrincipalAccount}:policy/ray-vast-head-boundary"}}
},
{
"Sid": "HeadRoleReadAndTag",
"Effect": "Allow",
"Action": ["iam:GetRole", "iam:ListRolePolicies", "iam:TagRole"],
"Resource": "arn:aws:iam::*:role/ray-vast-*"
},
{
"Sid": "PassHeadRoleToEc2",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::*:role/ray-vast-*",
"Condition": {"StringEquals": {"iam:PassedToService": "ec2.amazonaws.com"}}
},
{
"Sid": "HeadInstanceProfile",
"Effect": "Allow",
"Action": [
"iam:CreateInstanceProfile",
"iam:TagInstanceProfile",
"iam:GetInstanceProfile",
"iam:AddRoleToInstanceProfile",
"iam:RemoveRoleFromInstanceProfile",
"iam:DeleteInstanceProfile"
],
"Resource": "arn:aws:iam::*:instance-profile/ray-vast-*"
}
]
}
The user (or the profile in --profile) needs these actions:
| Area | Actions | Used by | Limit in ray-vast-user |
|---|---|---|---|
| Account | sts:GetCallerIdentity |
up |
none |
| Read EC2 | ec2:DescribeInstances, ec2:DescribeSecurityGroups, ec2:DescribeImages, ec2:DescribeKeyPairs |
all commands | none (these actions have no resource limit) |
| Security groups | ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:DeleteSecurityGroup |
up, down |
tag ray-vast-cluster |
| Key pair | ec2:CreateKeyPair, ec2:DeleteKeyPair |
up, down |
name ray-vast-* and tag ray-vast-cluster |
| Instances | ec2:RunInstances, ec2:TerminateInstances |
up, down |
tag ray-vast-cluster on the instance, its disk and its security groups |
| Tags | ec2:CreateTags |
up (tags at creation) |
only in CreateSecurityGroup, CreateKeyPair and RunInstances |
| IAM role | iam:CreateRole, iam:PutRolePolicy, iam:DeleteRolePolicy, iam:DeleteRole |
up, down |
name ray-vast-* and the boundary ray-vast-head-boundary |
| IAM role, other | iam:GetRole, iam:ListRolePolicies, iam:TagRole |
up, down |
name ray-vast-* |
| Pass the role | iam:PassRole |
up |
name ray-vast-*, only to EC2 |
| Instance profile | iam:CreateInstanceProfile, iam:TagInstanceProfile, iam:GetInstanceProfile, iam:AddRoleToInstanceProfile, iam:RemoveRoleFromInstanceProfile, iam:DeleteInstanceProfile |
up, down |
name ray-vast-* |
up uses the default VPC of the region.
All resources have the name ray-vast-<cluster_name> (the groups add -0 … -4) and the tag ray-vast-cluster=<cluster_name>.
ray-vast-user has no iam:CreatePolicy. So a restricted user cannot make a role with more permissions than the boundary. A live test on 2026-10-16 proved it: iam:CreateRole without the boundary, or with another boundary, was denied.
The head role¶
up makes the role ray-vast-<cluster_name>, with the permissions boundary ray-vast-head-boundary. Only EC2 can assume it:
{
"Version": "2012-10-17",
"Statement": [
{"Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole"}
]
}
It has one inline policy, head:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ec2:DescribeSecurityGroups", "ec2:DescribeInstances"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["ec2:AuthorizeSecurityGroupIngress", "ec2:RevokeSecurityGroupIngress"],
"Resource": [
"arn:aws:ec2:<region>:<account>:security-group/<group 0 id>",
"arn:aws:ec2:<region>:<account>:security-group/<group 1 id>",
"arn:aws:ec2:<region>:<account>:security-group/<group 2 id>",
"arn:aws:ec2:<region>:<account>:security-group/<group 3 id>",
"arn:aws:ec2:<region>:<account>:security-group/<group 4 id>"
]
}
]
}
So the head can only add and remove rules in the 5 groups of its cluster, and describe EC2. The provider on the head uses it to allow each worker IP.
The instance profile ray-vast-<cluster_name> holds the role. The head requires IMDSv2.
The boundary¶
The policy ray-vast-head-boundary is the permissions boundary of every head role. Create it once in your account. Read Getting started. It is in the package, in ray_vast/iam/ray-vast-head-boundary.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Describe",
"Effect": "Allow",
"Action": ["ec2:DescribeSecurityGroups", "ec2:DescribeInstances"],
"Resource": "*"
},
{
"Sid": "WorkerRulesInRayVastGroups",
"Effect": "Allow",
"Action": ["ec2:AuthorizeSecurityGroupIngress", "ec2:RevokeSecurityGroupIngress"],
"Resource": "arn:aws:ec2:*:*:security-group/*",
"Condition": {"Null": {"aws:ResourceTag/ray-vast-cluster": "false"}}
}
]
}
The head role can never do more than this policy allows: read EC2, and add and remove rules in security groups with the tag ray-vast-cluster.
down deletes the role policy, the role and the instance profile. It does not delete the boundary policy: all clusters use it.