AWS Setup
In the scope of an enterprise-level plan, the Webscale Control Plane can provision and manage resources in a customer-provided AWS account. This page describes setup necessary to allow the Control Plane to access an account. It is not necessary when using a plan that includes Webscale-provided AWS accounts.
How It Works
Setup the IAM Permissions Boundary: A customer-managed IAM policy defines the maximum permissions any role created by Webscale can possess. It explicitly denies actions that allow privilege escalation (e.g., creating IAM users, modifying policies without oversight, or creating access keys).
Setup the IAM Role: This is the cross-account role assumed by Webscale. Its policy contains an iam:PermissionsBoundary condition that permits role creation and policy attachment only if the target role has the boundary attached. The role must belong to the same AWS account that the Stack will be provisioned with.
Stacks: Provide the
permissions_boundary_arnand theprovisioner_role_nameas variables when creating a Stack. Stack definitions attach the customer’s boundary ARN to all child IAM roles. Any attempts to assume a role in the customer account without the boundary ARN reference will fail.
CloudFormation Template
The following template is a guideline for creating the IAM Permissions Boundary and IAM Role described in steps 1 and 2 above.
AWSTemplateFormatVersion: '2010-09-09'
Description: "Provisions the Webscale cross-account role and strictly enforces a permissions boundary on all infrastructure deployed by Webscale."
Resources:
# -------------------------------------------------------------------
# The Permissions Boundary
# -------------------------------------------------------------------
CustomerProvisioningBoundary:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: WebscaleProvisioningBoundary
Description: "Maximum allowed permissions for roles provisioned by the Webscale control plane."
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowAppAndInfrastructureServices
Effect: Allow
Action:
- ec2:*
- eks:*
- ecr:*
- elasticloadbalancing:*
- autoscaling:*
- logs:*
- cloudwatch:*
- secretsmanager:GetSecretValue
- secretsmanager:DescribeSecret
- secretsmanager:ListSecretVersionIds
- secretsmanager:BatchGetSecretValue
- kms:Decrypt
- kms:GenerateDataKey*
- kms:DescribeKey
- ssm:GetParameter
- pricing:GetProducts
Resource: "*"
- Sid: AllowKarpenterIAMReadsAndPassRole
Effect: Allow
Action:
- iam:ListInstanceProfiles
- iam:GetInstanceProfile
- iam:PassRole
- iam:CreateServiceLinkedRole
Resource: "*"
- Sid: ExplicitDenyPrivilegeEscalation
Effect: Deny
Action:
- iam:CreateUser
- iam:CreateRole
- iam:CreatePolicy
- iam:CreateAccessKey
- iam:CreateLoginProfile
- iam:PutRolePolicy
- iam:PutUserPolicy
- iam:AttachRolePolicy
- iam:AttachUserPolicy
- iam:DetachRolePolicy
- iam:DeleteRolePolicy
- iam:UpdateAssumeRolePolicy
- iam:AddUserToGroup
Resource: "*"
# -------------------------------------------------------------------
# The Provisioner Role
# -------------------------------------------------------------------
WebscaleCrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: AccountProvisioner
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: "arn:aws:iam::725084300153:root"
Action: sts:AssumeRole
Policies:
- PolicyName: EnforcePermissionsBoundary
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ReadOnlyActions
Effect: Allow
Action:
- ec2:Describe*
- iam:List*
- iam:Get*
- eks:Describe*
- eks:List*
- rds:Describe*
- rds:List*
- elasticache:Describe*
- elasticache:List*
- es:Describe*
- es:List*
- mq:Describe*
- mq:List*
- secretsmanager:Describe*
- secretsmanager:Get*
- secretsmanager:List*
- route53:Get*
- route53:List*
- dlm:Get*
- ecr:Describe*
- ecr:Get*
- ecr:List*
- kms:DescribeKey
- kms:ListGrants
Resource: "*"
- Sid: ManageInfrastructure
Effect: Allow
Action:
- ec2:*
- eks:*
- rds:*
- elasticache:*
- es:*
- mq:*
- secretsmanager:*
- route53:*
- dlm:*
- ecr:*
- kms:CreateGrant
- kms:RevokeGrant
- kms:Decrypt
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
Resource: "*"
- Sid: IAMRoleCreationWithBoundary
Effect: Allow
Action:
- iam:CreateRole
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/webscale-*"
Condition:
StringEquals:
iam:PermissionsBoundary: !Ref CustomerProvisioningBoundary
- Sid: IAMRolePolicyModificationsWithBoundary
Effect: Allow
Action:
- iam:PutRolePolicy
- iam:AttachRolePolicy
- iam:DetachRolePolicy
- iam:DeleteRolePolicy
- iam:PutRolePermissionsBoundary
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/webscale-*"
Condition:
StringEquals:
iam:PermissionsBoundary: !Ref CustomerProvisioningBoundary
- Sid: IAMRoleLifecycle
Effect: Allow
Action:
- iam:DeleteRole
- iam:UpdateAssumeRolePolicy
- iam:TagRole
- iam:UntagRole
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/webscale-*"
- Sid: IAMInstanceProfileManagement
Effect: Allow
Action:
- iam:CreateInstanceProfile
- iam:DeleteInstanceProfile
- iam:AddRoleToInstanceProfile
- iam:RemoveRoleFromInstanceProfile
- iam:TagInstanceProfile
- iam:UntagInstanceProfile
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:instance-profile/webscale-*"
- Sid: IAMOIDCProviderManagement
Effect: Allow
Action:
- iam:CreateOpenIDConnectProvider
- iam:DeleteOpenIDConnectProvider
- iam:TagOpenIDConnectProvider
- iam:UntagOpenIDConnectProvider
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:oidc-provider/*"
- Sid: IAMPassRoleRestricted
Effect: Allow
Action: iam:PassRole
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/webscale-*"
- Sid: AllowServiceLinkedRoleCreation
Effect: Allow
Action:
- iam:CreateServiceLinkedRole
Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/*"
Condition:
StringEquals:
iam:AWSServiceName:
- "eks.amazonaws.com"
- "eks-nodegroup.amazonaws.com"
- "elasticloadbalancing.amazonaws.com"
Outputs:
CrossAccountRoleName:
Description: "Provide this role name when creating Stacks so the provisioner can assume the role."
Value: !Ref WebscaleCrossAccountRole
PermissionsBoundaryArn:
Description: "Provide this ARN when creating Stacks to include the boundary."
Value: !Ref CustomerProvisioningBoundary
Last modified on September 4, 2026