Skip to main content
Version: 2.4.1

Permissions

To use Resoto with all it's features—including cleanup—it requires wide permissions. It needs to collect all the resources, do tag validations and updates as well as deleting resources.

To use Resoto in a read-only capacity you can limit access to your cloud provider accordingly.

info

Resoto will NOT delete resources marked for deletion by default, even with the neccessary permissions.

Resoto will silently ignore collecting specific resources if it does not have the required permissions.

AWS Permissions

To enable the full capabilities of Resoto it needs a PowerUser like role and then deny the ones we don't want it to have.

Discovery-Only

To use Resoto in a read-only capacity it needs the following IAM role permissions.

Read-only permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"acm:Describe*",
"acm:Get*",
"acm:List*",
"apigateway:GET",
"application-autoscaling:Describe*",
"appstream:Describe*",
"appstream:Get*",
"appstream:List*",
"athena:List*",
"athena:Batch*",
"athena:Get*",
"autoscaling:Describe*",
"batch:List*",
"batch:Describe*",
"clouddirectory:List*",
"clouddirectory:BatchRead",
"clouddirectory:Get*",
"clouddirectory:LookupPolicy",
"cloudformation:Describe*",
"cloudformation:Get*",
"cloudformation:List*",
"cloudformation:Estimate*",
"cloudformation:Detect*",
"cloudformation:Validate*",
"cloudfront:Get*",
"cloudfront:List*",
"cloudhsm:List*",
"cloudhsm:Describe*",
"cloudhsm:Get*",
"cloudsearch:Describe*",
"cloudsearch:List*",
"cloudtrail:LookupEvents",
"cloudtrail:ListPublicKeys",
"cloudtrail:ListTags",
"cloudtrail:GetTrailStatus",
"cloudtrail:GetEventSelectors",
"cloudtrail:DescribeTrails",
"cloudwatch:Describe*",
"cloudwatch:Get*",
"cloudwatch:List*",
"codebuild:BatchGet*",
"codebuild:List*",
"codecommit:BatchGet*",
"codecommit:Get*",
"codecommit:GitPull",
"codecommit:List*",
"codedeploy:BatchGet*",
"codedeploy:Get*",
"codedeploy:List*",
"codepipeline:List*",
"codepipeline:Get*",
"codestar:List*",
"codestar:Describe*",
"codestar:Get*",
"cognito-identity:List*",
"cognito-identity:Describe*",
"cognito-identity:Lookup*",
"cognito-sync:List*",
"cognito-sync:Describe*",
"cognito-sync:Get*",
"cognito-sync:QueryRecords",
"cognito-idp:AdminList*",
"cognito-idp:List*",
"cognito-idp:Describe*",
"cognito-idp:Get*",
"config:Deliver*",
"config:Describe*",
"config:Get*",
"config:List*",
"connect:List*",
"connect:Describe*",
"connect:Get*",
"compute-optimizer:Get*",
"datapipeline:Describe*",
"datapipeline:EvaluateExpression",
"datapipeline:Get*",
"datapipeline:List*",
"datapipeline:QueryObjects",
"datapipeline:Validate*",
"datasync:Describe*",
"datasync:List*",
"directconnect:Describe*",
"directconnect:Confirm*",
"devicefarm:List*",
"devicefarm:Get*",
"discovery:Describe*",
"discovery:List*",
"discovery:Get*",
"dms:Describe*",
"dms:List*",
"dms:Test*",
"ds:Check*",
"ds:Describe*",
"ds:Get*",
"ds:List*",
"ds:Verify*",
"dynamodb:BatchGet*",
"dynamodb:Describe*",
"dynamodb:Get*",
"dynamodb:List*",
"dynamodb:Query",
"dynamodb:Scan",
"ec2:Describe*",
"ec2:Get*",
"ec2messages:Get*",
"ecr:BatchCheck*",
"ecr:BatchGet*",
"ecr:Describe*",
"ecr:Get*",
"ecr:List*",
"ecs:Describe*",
"ecs:List*",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"eks:List*",
"eks:Describe*",
"elasticache:Describe*",
"elasticache:List*",
"elasticbeanstalk:Check*",
"elasticbeanstalk:Describe*",
"elasticbeanstalk:List*",
"elasticbeanstalk:Request*",
"elasticbeanstalk:Retrieve*",
"elasticbeanstalk:Validate*",
"elasticfilesystem:Describe*",
"elasticloadbalancing:Describe*",
"elasticmapreduce:Describe*",
"elasticmapreduce:List*",
"elasticmapreduce:View*",
"elastictranscoder:List*",
"elastictranscoder:Read*",
"es:Describe*",
"es:List*",
"es:ESHttpGet",
"es:ESHttpHead",
"events:Describe*",
"events:List*",
"events:Test*",
"firehose:Describe*",
"firehose:List*",
"gamelift:List*",
"gamelift:Get*",
"gamelift:Describe*",
"gamelift:RequestUploadCredentials",
"gamelift:ResolveAlias",
"gamelift:Search*",
"glacier:List*",
"glacier:Describe*",
"glacier:Get*",
"globalaccelerator:List*",
"globalaccelerator:Describe*",
"health:Describe*",
"iam:Generate*",
"iam:Get*",
"iam:List*",
"iam:Simulate*",
"importexport:Get*",
"importexport:List*",
"inspector:Describe*",
"inspector:Get*",
"inspector:List*",
"inspector:Preview*",
"iot:Describe*",
"iot:Get*",
"iot:List*",
"kinesisanalytics:Describe*",
"kinesisanalytics:Discover*",
"kinesisanalytics:List*",
"kinesis:Describe*",
"kinesis:Get*",
"kinesis:List*",
"kms:Describe*",
"kms:Get*",
"kms:List*",
"lambda:List*",
"lambda:Get*",
"lex:Get*",
"lightsail:Get*",
"lightsail:Is*",
"lightsail:Download*",
"logs:Describe*",
"logs:Get*",
"logs:FilterLogEvents",
"logs:ListTagsLogGroup",
"logs:TestMetricFilter",
"machinelearning:Describe*",
"machinelearning:Get*",
"mobileanalytics:Get*",
"mobilehub:Get*",
"mobilehub:List*",
"mobilehub:Validate*",
"mobilehub:Verify*",
"mobiletargeting:Get*",
"opsworks:Describe*",
"opsworks:Get*",
"opsworks-cm:Describe*",
"organizations:Describe*",
"organizations:List*",
"polly:Describe*",
"polly:Get*",
"polly:List*",
"polly:SynthesizeSpeech",
"pricing:Describe*",
"pricing:Get*",
"rekognition:CompareFaces",
"rekognition:Detect*",
"rekognition:List*",
"rekognition:Search*",
"rds:Describe*",
"rds:List*",
"rds:Download*",
"redshift:Describe*",
"redshift:View*",
"redshift:Get*",
"resource-explorer:List*",
"resource-groups:Get*",
"resource-groups:List*",
"resource-groups:Search*",
"route53:Get*",
"route53:List*",
"route53:Test*",
"route53domains:Check*",
"route53domains:Get*",
"route53domains:List*",
"route53domains:View*",
"s3:Get*",
"s3:List*",
"s3:Head*",
"sagemaker:DescribeTrainingJob",
"sagemaker:ListTags",
"sagemaker:DescribeNotebookInstance",
"sagemaker:DescribeModel",
"sagemaker:ListTrainingJobs",
"sagemaker:ListEndpointConfigs",
"sagemaker:DescribeEndpointConfig",
"sagemaker:CreatePresignedNotebookInstanceUrl",
"sagemaker:ListModels",
"sagemaker:DescribeEndpoint",
"sagemaker:ListNotebookInstances",
"sagemaker:ListEndpoints",
"sagemaker:InvokeEndpoint",
"sdb:Get*",
"sdb:List*",
"sdb:Select*",
"secretsmanager:List*",
"secretsmanager:Describe*",
"servicecatalog:List*",
"servicecatalog:Scan*",
"servicecatalog:Search*",
"servicecatalog:Describe*",
"servicequotas:Get*",
"servicequotas:List*",
"ses:Get*",
"ses:List*",
"shield:Describe*",
"shield:List*",
"sns:Get*",
"sns:List*",
"sns:Check*",
"sqs:Get*",
"sqs:List*",
"sqs:Receive*",
"ssm:Describe*",
"ssm:Get*",
"ssm:List*",
"states:List*",
"states:Describe*",
"states:GetExecutionHistory",
"storagegateway:Describe*",
"storagegateway:List*",
"sts:Get*",
"support:*",
"swf:Count*",
"swf:Describe*",
"swf:Get*",
"swf:List*",
"tag:Describe*",
"tag:Get*",
"trustedadvisor:Describe*",
"waf:Get*",
"waf:List*",
"waf-regional:List*",
"waf-regional:Get*",
"workdocs:Describe*",
"workdocs:Get*",
"workdocs:CheckAlias",
"workmail:Describe*",
"workmail:Get*",
"workmail:List*",
"workmail:Search*",
"workspaces:Describe*",
"xray:BatchGet*",
"xray:Get*"
],
"Resource": "*"
}
]
}

Full Capabilities

For production use—where Resoto also cleans up and validates tags—the needed permission role is a PowerUser that is locked down to not be able to create any resources or modify IAM settings.

The following three policies are needed for Resoto to run with full capabilities.

Resoto allow
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ResotoAllow",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Resoto deny
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ResotoDeny",
"Effect": "Deny",
"Action": [
"support:Create*",
"storagegateway:Create*",
"states:Create*",
"ssm:Create*",
"sqs:Create*",
"sns:Create*",
"ses:Create*",
"servicequotas:Request*",
"servicequotas:Put*",
"servicequotas:Disassociate*",
"servicequotas:Delete*",
"servicequotas:Associate*",
"servicecatalog:Create*",
"sagemaker:Create*",
"s3:Create*",
"route53domains:UpdateDomainNameservers",
"route53domains:UpdateDomainContactPrivacy",
"route53domains:UpdateDomainContact",
"route53domains:TransferDomain",
"route53domains:RetrieveDomainAuthCode",
"route53domains:ResendContactReachabilityEmail",
"route53domains:RenewDomain",
"route53domains:RegisterDomain",
"route53domains:EnableDomainTransferLock",
"route53domains:EnableDomainAutoRenew",
"route53:Create*",
"redshift:Create*",
"rds:Create*",
"logs:Create*",
"lambda:Create*",
"kms:Create*",
"kinesis:Create*",
"iotsitewise:Create*",
"iotevents:Create*",
"iotanalytics:Create*",
"iot:Create*",
"iot1click:Create*",
"importexport:Create*",
"glue:Create*",
"globalaccelerator:Create*",
"glacier:Create*",
"events:TagResource",
"events:PutTargets",
"events:PutRule",
"events:PutPermission",
"events:PutEvents",
"events:EnableRule",
"es:Create*",
"elasticmapreduce:Create*",
"elasticloadbalancing:Create*",
"elasticfilesystem:Create*",
"elasticache:Create*",
"eks:Create*",
"ecr:Create*",
"ec2messages:SendReply",
"ec2messages:FailMessage",
"ec2messages:AcknowledgeMessage",
"ec2:CreateVpnGateway",
"ec2:CreateVpnConnectionRoute",
"ec2:CreateVpnConnection",
"ec2:CreateVpcPeeringConnection",
"ec2:CreateVpcEndpoint",
"ec2:CreateVpc",
"ec2:CreateVolume",
"ec2:CreateSubnet",
"ec2:CreateSpotDatafeedSubscription",
"ec2:CreateSnapshot",
"ec2:CreateSecurityGroup",
"ec2:CreateRouteTable",
"ec2:CreateRoute",
"ec2:CreateReservedInstancesListing",
"ec2:CreatePlacementGroup",
"ec2:CreateNetworkInterface",
"ec2:CreateNetworkAclEntry",
"ec2:CreateNetworkAcl",
"ec2:CreateNatGateway",
"ec2:CreateKeyPair",
"ec2:CreateInternetGateway",
"ec2:CreateInstanceExportTask",
"ec2:CreateImage",
"ec2:CreateFlowLogs",
"ec2:CreateDhcpOptions",
"ec2:CreateCustomerGateway",
"dynamodb:Create*",
"ds:Create*",
"cognito-idp:Create*",
"cloudwatch:SetAlarmState",
"cloudwatch:PutMetricData",
"cloudwatch:PutMetricAlarm",
"cloudwatch:PutDashboard",
"cloudwatch:EnableAlarmActions",
"cloudtrail:Create*",
"cloudsearch:Create*",
"cloudfront:Create*",
"cloudformation:Create*",
"budgets:ViewBudget",
"batch:Create*",
"aws-portal:Modify*",
"aws-marketplace-management:uploadFiles",
"autoscaling:Create*",
"athena:Create*",
"application-autoscaling:RegisterScalableTarget",
"application-autoscaling:PutScheduledAction",
"application-autoscaling:PutScalingPolicy",
"apigateway:UpdateRestApiPolicy",
"apigateway:PUT",
"apigateway:POST",
"apigateway:PATCH",
"acm:UpdateCertificateOptions",
"acm:ResendValidationEmail",
"acm:RequestCertificate",
"acm:RenewCertificate",
"acm:ImportCertificate",
"acm:AddTagsToCertificate"
],
"Resource": "*"
}
]
}
Resoto deny IAM
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ResotoDenyIAM",
"Effect": "Deny",
"Action": [
"iam:UploadSigningCertificate",
"iam:UploadServerCertificate",
"iam:UploadSSHPublicKey",
"iam:UpdateUser",
"iam:UpdateSigningCertificate",
"iam:UpdateServiceSpecificCredential",
"iam:UpdateServerCertificate",
"iam:UpdateSSHPublicKey",
"iam:UpdateSAMLProvider",
"iam:UpdateRoleDescription",
"iam:UpdateOpenIDConnectProviderThumbprint",
"iam:UpdateLoginProfile",
"iam:UpdateGroup",
"iam:UpdateAssumeRolePolicy",
"iam:UpdateAccountPasswordPolicy",
"iam:UpdateAccessKey",
"iam:SimulatePrincipalPolicy",
"iam:SimulateCustomPolicy",
"iam:SetSecurityTokenServicePreferences",
"iam:SetDefaultPolicyVersion",
"iam:ResyncMFADevice",
"iam:ResetServiceSpecificCredential",
"iam:RemoveUserFromGroup",
"iam:RemoveClientIDFromOpenIDConnectProvider",
"iam:PutUserPolicy",
"iam:PutUserPermissionsBoundary",
"iam:PutRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:PutGroupPolicy",
"iam:PassRole",
"iam:GenerateServiceLastAccessedDetails",
"iam:GenerateCredentialReport",
"iam:EnableMFADevice",
"iam:DetachUserPolicy",
"iam:DetachGroupPolicy",
"iam:DeleteVirtualMFADevice",
"iam:DeleteUserPolicy",
"iam:DeleteUserPermissionsBoundary",
"iam:DeleteUser",
"iam:DeleteSigningCertificate",
"iam:DeleteServiceSpecificCredential",
"iam:DeleteServiceLinkedRole",
"iam:DeleteServerCertificate",
"iam:DeleteSSHPublicKey",
"iam:DeleteSAMLProvider",
"iam:DeleteOpenIDConnectProvider",
"iam:DeleteLoginProfile",
"iam:DeleteGroupPolicy",
"iam:DeleteGroup",
"iam:DeleteAccountPasswordPolicy",
"iam:DeleteAccountAlias",
"iam:DeleteAccessKey",
"iam:DeactivateMFADevice",
"iam:CreateVirtualMFADevice",
"iam:CreateUser",
"iam:CreateServiceSpecificCredential",
"iam:CreateServiceLinkedRole",
"iam:CreateSAMLProvider",
"iam:CreateRole",
"iam:CreatePolicyVersion",
"iam:CreatePolicy",
"iam:CreateOpenIDConnectProvider",
"iam:CreateLoginProfile",
"iam:CreateInstanceProfile",
"iam:CreateGroup",
"iam:CreateAccountAlias",
"iam:CreateAccessKey",
"iam:ChangePassword",
"iam:AttachUserPolicy",
"iam:AttachRolePolicy",
"iam:AttachGroupPolicy",
"iam:AddUserToGroup",
"iam:AddRoleToInstanceProfile",
"iam:AddClientIDToOpenIDConnectProvider"
],
"Resource": "*"
},
{
"Sid": "ResotoDenyIAMPredefinedRoles",
"Effect": "Deny",
"Action": [
"iam:UpdateRole",
"iam:UntagRole",
"iam:TagRole",
"iam:RemoveRoleFromInstanceProfile",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRolePermissionsBoundary",
"iam:DeleteRole",
"iam:DeleteInstanceProfile"
],
"Resource": [
"arn:aws:iam::*:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations",
"arn:aws:iam::*:role/TeamCity/TeamCity-PowerUser",
"arn:aws:iam::*:role/TeamCity/TeamCity-Agent",
"arn:aws:iam::*:role/OrganizationAccountAccessRole",
"arn:aws:iam::*:role/Mesosphere-ReadOnly",
"arn:aws:iam::*:role/Mesosphere-PowerUser",
"arn:aws:iam::*:role/Mesosphere-OneloginAccess",
"arn:aws:iam::*:role/Mesosphere-Admin",
"arn:aws:iam::*:role/Jenkins/Jenkins-S3-DOCS-Staging",
"arn:aws:iam::*:role/Jenkins/Jenkins-S3-DOCS-Production",
"arn:aws:iam::*:role/Jenkins/Jenkins-S3-DOCS-Development",
"arn:aws:iam::*:role/Jenkins/Jenkins-PowerUser"
]
},
{
"Sid": "ResotoDenyIAMPredefinedPolicies",
"Effect": "Deny",
"Action": [
"iam:SetDefaultPolicyVersion",
"iam:DeletePolicyVersion",
"iam:DeletePolicy"
],
"Resource": [
"arn:aws:iam::*:policy/OneLoginAccess",
"arn:aws:iam::*:policy/MesosphereReadOnlyPolicy",
"arn:aws:iam::*:policy/MesospherePowerUserPolicy"
]
}
]
}