Latch allows you to run computation without data leaving your cloud
Go to this [link](https://console.aws.amazon.com/cloudformation/home?#/stacks/quickcreate?templateURL=https://forch-deployment.s3.us-west-2.amazonaws.com/forch_agent_template.json&stackName=forch)
Log into the AWS account
You will be directed to an AWS CloudFormation 'Quick create stack' template.
Click on the checkbox to acknowledge that this stack will create an iam role.
Click 'Create Stack' and wait for it to be created.
Notify someone at Latch with the following details.
forch-agent
forch-agent
is created by the Cloudformation Stack from previous section. This role is used when provisioning cloud resources to setup the forch domain. The list of cloud resources created are as follows:
{
"Statement": [
{
"Action": [
"s3:CreateBucket",
"s3:GetBucket*",
"s3:ListBucket*",
"s3:PutBucketCORS",
"s3:GetAccelerateConfiguration",
"s3:PutBucketVersioning",
"s3:GetLifecycleConfiguration",
"s3:GetReplicationConfiguration",
"s3:GetEncryptionConfiguration",
"s3:PutEncryptionConfiguration",
"s3:PutBucketRequestPayment"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::forch-${aws_account_id}"
},
{
"Action": [
"iam:CreateRole",
"iam:GetRole",
"iam:AttachRolePolicy",
"iam:DeleteRole",
"iam:ListRolePolicies",
"iam:PutRolePolicy",
"iam:ListInstanceProfilesForRole",
"iam:ListAttachedRolePolicies",
"iam:GetRolePolicy",
"iam:CreateServiceLinkedRole"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::*:role/forch-orchestrator",
"arn:aws:iam::*:role/forch-node",
"arn:aws:iam::*:role/forch-nat-*",
"arn:aws:iam::*:role/forch-agent"
]
},
{
"Action": ["iam:CreateServiceLinkedRole"],
"Effect": "Allow",
"Resource": ["arn:aws:iam::*:role/forch-agent"],
"Condition": {
"StringEquals": {
"iam:AWSServiceName": "kms.amazonaws.com"
}
}
},
{
"Action": ["iam:PassRole"],
"Effect": "Allow",
"Resource": ["arn:aws:iam::*:role/forch-nat-*", "arn:aws:iam::*:role/forch-node"]
},
{
"Action": [
"iam:CreatePolicy",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:CreatePolicyVersion",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:ListPolicyVersions"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::*:policy/forch-orchestrator-base",
"arn:aws:iam::*:policy/forch-node-base",
"arn:aws:iam::*:policy/forch-agent-delete-permissions"
]
},
{
"Action": [
"iam:CreateInstanceProfile",
"iam:GetInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:AddRoleToInstanceProfile"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::*:instance-profile/forch-nat-*",
"arn:aws:iam::*:instance-profile/forch-node"
]
},
{
"Action": "ec2:CreateTags",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": ["ec2:CreateKeyPair", "ec2:DeleteKeyPair", "ec2:ImportKeyPair"],
"Resource": "arn:aws:ec2:*:*:key-pair/forch/debug-root",
"Effect": "Allow"
},
{
"Action": "ec2:DescribeKeyPairs",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": ["ec2:CreateVpc", "ec2:DescribeVpcs", "ec2:DescribeVpcAttribute"],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"ec2:CreateInternetGateway",
"ec2:AttachInternetGateway",
"ec2:DescribeInternetGateways"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:CreateSecurityGroup",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:security-group/*"
},
{
"Action": "ec2:CreateSecurityGroup",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:vpc/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created By": "Forch"
}
}
},
{
"Action": [
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": ["ec2:DescribeSecurityGroups", "ec2:DescribeSecurityGroupRules"],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:CreateSubnet",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:subnet/*"
},
{
"Action": "ec2:CreateSubnet",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:vpc/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created By": "Forch"
}
}
},
{
"Action": ["ec2:DescribeSubnets", "ec2:ModifySubnetAttribute"],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:CreateRouteTable",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:route-table/*"
},
{
"Action": "ec2:CreateRouteTable",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:vpc/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created By": "Forch"
}
}
},
{
"Action": "ec2:CreateRoute",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:DescribeRouteTables",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:CreateNetworkAcl",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:network-acl/*"
},
{
"Action": "ec2:CreateNetworkAcl",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:vpc/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created By": "Forch"
}
}
},
{
"Action": "ec2:DescribeNetworkAcls",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"ec2:DeleteNetworkAclEntry",
"ec2:CreateNetworkAclEntry",
"ec2:ReplaceNetworkAclAssociation"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:AllocateAddress",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:AssociateAddress",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:elastic-ip/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/forch/allow": "true"
}
}
},
{
"Action": "ec2:AssociateAddress",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:instance/*"
},
{
"Action": ["ec2:DescribeAddresses", "ec2:DescribeAddressesAttribute"],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:DescribeImages",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ec2:RunInstances",
"Condition": {
"ArnLike": {
"ec2:InstanceProfile": [
"arn:aws:iam::*:instance-profile/forch-node",
"arn:aws:iam::*:instance-profile/forch-nat-*"
]
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:instance/*"
},
{
"Action": "ec2:RunInstances",
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:subnet/*"
]
},
{
"Action": "ec2:RunInstances",
"Condition": {
"StringEquals": {
"ec2:Owner": "812206152185"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:image/*"
},
{
"Action": "ec2:RunInstances",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:key-pair/forch/debug-root"
},
{
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:volume/*",
"Effect": "Allow"
},
{
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:DescribeTags",
"ec2:DescribeInstanceAttribute"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": ["ec2:DescribeVolumes"],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": ["ec2:DescribeAvailabilityZones"],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ssm:GetParameters",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DescribeSecret",
"secretsmanager:PutSecretValue",
"secretsmanager:DeleteSecret",
"secretsmanager:GetSecretValue",
"secretsmanager:TagResource",
"secretsmanager:GetResourcePolicy"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:*:*:secret:forch/nat-jwt*",
"arn:aws:secretsmanager:*:*:secret:forch/ssh-forwarder/ssh_host_ecdsa_key*",
"arn:aws:secretsmanager:*:*:secret:forch/ssh-forwarder/ssh_host_rsa_key*",
"arn:aws:secretsmanager:*:*:secret:forch/ssh-forwarder/ssh_host_ed25519_key*"
]
},
{
"Action": [
"kms:CreateKey",
"kms:ReplicateKey",
"kms:DescribeKey",
"kms:TagResource",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListResourceTags",
"kms:PutKeyPolicy",
"kms:EnableKeyRotation",
"kms:CreateAlias",
"kms:ListAliases"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"kms:CreateGrant"
],
"Resource": "*"
}
],
"Version": "2012-10-17"
}
forch-orchestrator
forch-orchestrator
is assumed at runtime to schedule and manage tasks. It has permissions to:
{
"Statement": [
{
"Action": "ec2:RunInstances",
"Condition": {
"StringEquals": {
"ec2:InstanceProfile": "arn:aws:iam::${aws_account_id}:instance-profile/forch-node"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:instance/*",
"Sid": "ForchRunInstance"
},
{
"Action": "ec2:RunInstances",
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:${aws_region}:${aws_account_id}:vpc/${vpc_id}""ec2:Vpc": "${vpc_arn}"
}
},
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:network-interface/*"
],
"Sid": "ForchRunInstanceVpcPolicy"
},
{
"Action": "ec2:RunInstances",
"Condition": {
"StringEquals": {
"ec2:Owner": "812206152185"
}
},
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:image/*",
"Sid": "ForchRunInstanceImages"
},
{
"Action": "ec2:RunInstances",
"Effect": "Allow",
"Resource": "arn:aws:ec2:${aws_region}:${aws_account_id}:key-pair/forch/debug-root",
"Sid": "ForchRunInstanceKeyPair"
},
{
"Action": "ec2:RunInstances",
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:volume/*",
"Sid": "ForchRunInstanceVolumes"
},
{
"Action": "iam:PassRole",
"Effect": "Allow",
"Resource": "arn:aws:iam::${aws_account_id}:role/forch-node",
"Sid": "ForchNodePassRole"
},
{
"Action": "ssm:GetParameters",
"Effect": "Allow",
"Resource": "*",
"Sid": "SystemMangerParamters"
},
{
"Action": "ec2:TerminateInstances",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Created By": "Forch"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:instance/*",
"Sid": "ForchTerminateNode"
},
{
"Action": [
"ec2:AssignPrivateIpAddresses",
"ec2:AssignIpv6Addresses"
],
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:${aws_region}:${aws_account_id}:vpc/${vpc_id}"
}
},
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchNodeIps"
},
{
"Action": [
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchNodeDescribeInfo"
},
{
"Action": [
"ec2:ModifyVolume",
"ec2:DetachVolume",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:AttachVolume"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/CreatedBy": [
"nucleus/create_volume",
"nucleus/restore_snapshot",
"nucleus-workflows"
]
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:volume/*",
"Sid": "ForchNodeVolumes"
},
{
"Action": [
"ec2:DetachVolume",
"ec2:AttachVolume"
],
"Condition": {
"StringEquals": {
"ec2:InstanceProfile": "arn:aws:iam::${aws_account_id}:instance-profile/forch-node",
"ec2:ResourceTag/Created By": "Forch"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:instance/*",
"Sid": "ForchNodeVolumesAllowedInstances"
},
{
"Action": [
"ec2:DescribeVolumesModifications",
"ec2:DescribeVolumes"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchNodeDescribeVolumes"
},
{
"Action": [
"ec2:DisassociateAddress",
"ec2:AssociateAddress"
],
"Effect": "Allow",
"Resource": [
"arn:aws:ec2:${aws_region}:${aws_account_id}:elastic-ip/${eipalloc_id}",
"arn:aws:ec2:${aws_region}:${aws_account_id}:elastic-ip/${eipalloc_id}"
],
"Sid": "ForchElasticIp"
},
{
"Action": [
"ec2:DisassociateAddress",
"ec2:AssociateAddress"
],
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:${aws_region}:${aws_account_id}:vpc/${vpc_id}"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:network-interface/*",
"Sid": "ForchElasticIpNetworkInterface"
},
{
"Action": [
"ec2:DisassociateAddress",
"ec2:AssociateAddress"
],
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:instance/*",
"Sid": "ForchElasticIpInstances"
},
{
"Action": "ec2:DescribeAddresses",
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchDescribeElasticIp"
},
{
"Action": "ec2:CreateTags",
"Condition": {
"StringEquals": {
"ec2:InstanceProfile": "arn:aws:iam::${aws_account_id}:instance-profile/forch-node"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:instance/*",
"Sid": "ForchTagInstances"
},
{
"Action": "ec2:CreateTags",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Created By": "Forch"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:volume/*",
"Sid": "ForchTagVolumes"
},
{
"Action": "ec2:CreateTags",
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:${aws_region}:${aws_account_id}:vpc/${vpc_id}"
}
},
"Effect": "Allow",
"Resource": "arn:*:ec2:*:*:network-interface/*",
"Sid": "ForchNetworkInterfaces"
},
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::forch-${aws_account_id}/logs/*",
"arn:aws:s3:::forch-${aws_account_id}/logs"
],
"Sid": "ForchFluentdReadWrite"
},
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::forch-${aws_account_id}",
"Sid": "ForchFluentdList"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*",
"Sid": "AllowAssumeRole"
},
{
"Action": [
"secretsmanager:UpdateSecret",
"secretsmanager:CreateSecret"
],
"Condition": {
"StringEquals": {
"secretsmanager:ResourceTag/forch/allow": "true"
}
},
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:DescribeKey",
"kms:Decrypt",
"kms:CreateGrant"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
}
forch-node
forch-nat-*
role has permission to get the task secrets from secretsmanager, read and write logs to the s3 bucket and also assume the forch-node-shared
role to get access to ecr images and secrets from Latch’s aws account. This role’s can only be assumed by roles within the forch domains’ cloud account.
{
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::forch-${aws_account_id}/logs/*",
"arn:aws:s3:::forch-${aws_account_id}/logs"
],
"Sid": "ForchFluentdReadWrite"
},
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::forch-${aws_account_id}",
"Sid": "ForchFluentdList"
},
{
"Action": "ec2:DescribeAddresses",
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchDescribeAddresses"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*",
"Sid": "AllowAssumeRole"
},
{
"Action": "secretsmanager:BatchGetSecretValue",
"Effect": "Allow",
"Resource": "*",
"Sid": "BatchGetSecretValue"
},
{
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": "*",
"Sid": "GetSecretValue",
"Condition": {
"StringEquals": {
"aws:ResourceTag/forch/account_id": "${aws:PrincipalAccount}",
"aws:ResourceTag/forch/allow": "true"
}
}
}
],
"Version": "2012-10-17"
}
forch-nat-*
forch-nat-*
role has permission to get the nat-jwt-*
secret from secretsmanager and also assume the forch-node-shared
role to get access to ecr images and secrets from Latch’s aws account. This role’s can only be assumed by roles within the forch domains’ cloud account.
{
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::forch-${aws_account_id}/logs/*",
"arn:aws:s3:::forch-${aws_account_id}/logs"
],
"Sid": "ForchFluentdReadWrite"
},
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::forch-${aws_account_id}",
"Sid": "ForchFluentdList"
},
{
"Action": "ec2:DescribeAddresses",
"Effect": "Allow",
"Resource": "*",
"Sid": "ForchDescribeAddresses"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "*",
"Sid": "AllowAssumeRole"
},
{
"Action": "secretsmanager:BatchGetSecretValue",
"Effect": "Allow",
"Resource": "*",
"Sid": "BatchGetSecretValue"
},
{
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": "*",
"Sid": "GetSecretValue",
"Condition": {
"StringEquals": {
"aws:ResourceTag/forch/account_id": "${aws:PrincipalAccount}",
"aws:ResourceTag/forch/allow": "true"
}
}
}
],
"Version": "2012-10-17"
}
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "secretsmanager:GetSecretValue",
"Effect": "Allow",
"Resource": "arn:aws:secretsmanager:${aws_region}:${aws_account_id}:secret:forch/nat-jwt-*",
"Sid": "JwtSecret"
}
]
}
Was this page helpful?