AWS Required Permissions

To provide full visibility into your account, Tenable One AI Exposure needs to collect relevant metadata using both an AWS-managed policy and an inline policy that are attached to the dedicated role you create for Tenable in IAM when you connect an account or organization:

  • Monitoring permissions:
    • SecurityAudit permissions. AWS-managed policy, which grants access to read security configuration metadata.
    • Custom Tenable Monitoring permissions (read-only). Inline policy, which grants Tenable additional read-only permissions not included in the SecurityAudit policy.

      To learn more about why Tenable needs both the SecurityAudit policy and a custom, inline policy, see Need for Both Custom Policy and SecurityAudit Policy.

  • (Optional) Custom Tenable Remediation permissions (read-write). Inline policy, which grants Tenable management permissions, allowing Tenable to make changes in your environment. For example, this allows Tenable to automatically remediate findings directly in AWS (If you choose not to grant management permissions, you can still manually remediate findings by providing one-time credentials on demand).
  • CloudTrail (S3) permissions. See AWS CloudTrail for more information.

If you use service control policies (SCPs) or resource control policies (RCPs) in your AWS organization, make sure to add exclusions to any existing SCP or RCP to ensure that the dedicated IAM role you create for AI Exposure is not included. See Access to Us-East-1 Region for more information.

Appendix I: AWS IAM Policies

Tenable Monitoring Policy (Read-Only)

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "acm:Describe*",
        "acm:List*",
        "aoss:BatchGet*",
        "aoss:List*",
        "appsync:List*",
        "athena:GetWorkGroup",
        "athena:List*",
        "autoscaling:Describe*",
        "batch:Describe*",
        "batch:List*",
        "bedrock:Get*",
        "bedrock:List*",
        "bedrock-agentcore:GetAgentRuntime",
        "bedrock-agentcore:GetAgentRuntimeEndpoint",
        "bedrock-agentcore:GetApiKeyCredentialProvider",
        "bedrock-agentcore:GetGateway",
        "bedrock-agentcore:GetGatewayTarget",
        "bedrock-agentcore:GetHarness",
        "bedrock-agentcore:GetMemory",
        "bedrock-agentcore:GetOauth2CredentialProvider",
        "bedrock-agentcore:GetPaymentCredentialProvider",
        "bedrock-agentcore:GetWorkloadIdentity",
        "bedrock-agentcore:ListWorkloadIdentities",
        "bedrock-agentcore:ListApiKeyCredentialProviders",
        "bedrock-agentcore:ListOauth2CredentialProviders",
        "cloudformation:Describe*",
        "cloudformation:Get*",
        "cloudformation:List*",
        "cloudfront:Get*",
        "cloudfront:ListDistributions*",
        "cloudtrail:Describe*",
        "cloudtrail:Get*",
        "cloudtrail:List*",
        "cloudtrail:LookupEvents",
        "cloudwatch:Describe*",
        "cloudwatch:GetMetric*",
        "cloudwatch:ListMetrics",
        "codebuild:BatchGet*",
        "codebuild:List*",
        "cognito-idp:ListResourcesForWebACL",
        "cognito-identity:Describe*",
        "cognito-identity:List*",
        "cognito-idp:List*",
        "cognito-sync:GetCognitoEvents",
        "config:Describe*",
        "dax:Describe*",
        "directconnect:Describe*",
        "dms:Describe*",
        "docdb-elastic:Get*",
        "docdb-elastic:List*",
        "dynamodb:Describe*",
        "dynamodb:GetResourcePolicy",
        "dynamodb:List*",
        "ec2:Describe*",
        "ec2:GetTransitGatewayRouteTablePropagations",
        "ec2:SearchTransitGatewayRoutes",
        "ecr:Describe*",
        "ecr:GetRegistryScanningConfiguration",
        "ecr:GetRepositoryPolicy",
        "ecr:List*",
        "ecr:StartImageScan",
        "ecr-public:Describe*",
        "ecr-public:GetRepositoryPolicy",
        "ecr-public:List*",
        "ecs:Describe*",
        "ecs:List*",
        "eks:Describe*",
        "eks:List*",
        "elasticache:Describe*",
        "elasticache:List*",
        "elasticbeanstalk:Describe*",
        "elasticbeanstalk:List*",
        "elasticfilesystem:Describe*",
        "elasticloadbalancing:Describe*",
        "elasticmapreduce:Describe*",
        "elasticmapreduce:List*",
        "es:Describe*",
        "es:List*",
        "events:ListRules",
        "firehose:Describe*",
        "firehose:List*",
        "glue:BatchGet*",
        "glue:Get*",
        "glue:List*",
        "guardduty:GetDetector",
        "guardduty:ListDetectors",
        "iam:Generate*",
        "iam:Get*",
        "iam:List*",
        "identitystore:Describe*",
        "identitystore:List*",
        "inspector2:List*",
        "iot:GetTopicRule",
        "kafka:ListClustersV2",
        "kms:Describe*",
        "kms:GetKey*",
        "kms:List*",
        "kinesis:Describe*",
        "kinesis:List*",
        "lambda:Get*Policy",
        "lambda:GetAccountSettings",
        "lambda:List*",
        "logs:Describe*",
        "mq:DescribeBroker",
        "mq:ListBrokers",
        "organizations:Describe*",
        "organizations:List*",
        "rds:Describe*",
        "rds:List*",
        "redshift:Describe*",
        "redshift:List*",
        "redshift-serverless:List*",
        "route53:Get*",
        "route53:List*",
        "route53domains:Get*",
        "route53domains:List*",
        "route53resolver:Get*",
        "route53resolver:List*",
        "s3:Describe*",
        "s3:GetAccessPoint*",
        "s3:GetAccountPublicAccessBlock",
        "s3:GetBucket*",
        "s3:GetEncryptionConfiguration",
        "s3:GetJobTagging",
        "s3:GetLifecycleConfiguration",
        "s3:ListAccessPoints",
        "s3:ListAllMyBuckets",
        "s3:ListBucketVersions",
        "s3:ListJobs",
        "s3:ListTagsForResource",
        "sagemaker:Describe*",
        "sagemaker:List*",
        "secretsmanager:Describe*",
        "secretsmanager:GetResourcePolicy",
        "secretsmanager:List*",
        "sns:Get*",
        "sns:List*",
        "sqs:Get*",
        "sqs:List*",
        "ssm:Describe*",
        "ssm:List*",
        "sso:Describe*",
        "sso:Get*",
        "sso:List*",
        "sso-directory:List*",
        "sso-directory:Search*",
        "states:List*",
        "sts:DecodeAuthorizationMessage",
        "tag:Get*",
        "timestream:List*",
        "timestream:Get*",
        "timestream:Describe*",
        "wafv2:Get*",
        "wafv2:List*"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::elasticbeanstalk-*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "apigateway:GET",
        "apigateway:ListRoutingRules"
      ],
      "Resource": [
        "arn:aws:apigateway:*::/apis",
        "arn:aws:apigateway:*::/apis/*/authorizers",
        "arn:aws:apigateway:*::/apis/*/integrations",
        "arn:aws:apigateway:*::/apis/*/routes",
        "arn:aws:apigateway:*::/domainnames",
        "arn:aws:apigateway:*::/domainnames/*/basepathmappings",
        "arn:aws:apigateway:*:*:/domainnames/*/routingrules/*",
        "arn:aws:apigateway:*::/restapis",
        "arn:aws:apigateway:*::/restapis/*/authorizers",
        "arn:aws:apigateway:*::/restapis/*/resources",
        "arn:aws:apigateway:*::/restapis/*/stages"
      ]
    }
  ]
}

Tenable Remediation Policy (Read-Write)

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteSecurityGroup",
        "ec2:ModifyInstanceMetadataOptions",
        "ec2:ModifyVpcEndpoint",
        "ec2:RevokeSecurityGroupEgress",
        "ec2:RevokeSecurityGroupIngress",
        "ecr:DeleteRepositoryPolicy",
        "ecr:SetRepositoryPolicy",
        "iam:AddUserToGroup",
        "iam:AttachGroupPolicy",
        "iam:AttachRolePolicy",
        "iam:AttachUserPolicy",
        "iam:CreatePolicy",
        "iam:CreatePolicyVersion",
        "iam:DeactivateMFADevice",
        "iam:DeleteAccessKey",
        "iam:DeleteGroup",
        "iam:DeleteGroupPolicy",
        "iam:DeleteLoginProfile",
        "iam:DeletePolicy",
        "iam:DeletePolicyVersion",
        "iam:DeleteRole",
        "iam:DeleteRolePermissionsBoundary",
        "iam:DeleteRolePolicy",
        "iam:DeleteServerCertificate",
        "iam:DeleteServiceSpecificCredential",
        "iam:DeleteSigningCertificate",
        "iam:DeleteSSHPublicKey",
        "iam:DeleteUser",
        "iam:DeleteUserPermissionsBoundary",
        "iam:DeleteUserPolicy",
        "iam:DetachGroupPolicy",
        "iam:DetachRolePolicy",
        "iam:DetachUserPolicy",
        "iam:PutGroupPolicy",
        "iam:PutRolePermissionsBoundary",
        "iam:PutRolePolicy",
        "iam:PutUserPermissionsBoundary",
        "iam:PutUserPolicy",
        "iam:RemoveRoleFromInstanceProfile",
        "iam:RemoveUserFromGroup",
        "iam:UpdateAccessKey",
        "iam:UpdateAssumeRolePolicy",
        "s3:DeleteBucketPolicy",
        "s3:PutBucketPolicy",
        "secretsmanager:DeleteResourcePolicy",
        "secretsmanager:PutResourcePolicy",
        "sso:DeleteAccountAssignment",
        "sso:DeleteInlinePolicyFromPermissionSet",
        "sso:DeletePermissionSet",
        "sso:DetachManagedPolicyFromPermissionSet",
        "sso:ProvisionPermissionSet",
        "sso:PutInlinePolicyToPermissionSet"
      ],
      "Resource": "*"
    }
  ]
}

CloudTrail Policy

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3LogAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::YOUR_CLOUDTRAIL_BUCKET_NAME",
        "arn:aws:s3:::YOUR_CLOUDTRAIL_BUCKET_NAME/*"
      ]
    },
    {
      "Sid": "AllowKMSDecrypt",
      "Effect": "Allow",
      "Action": "kms:Decrypt",
      "Resource": "arn:aws:kms:REGION:ACCOUNT_ID:key/KMS_KEY_UUID"
    }
  ]
}

Data Resources Scanning Policy (Data Protection)

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:Scan",
        "kms:CreateGrant",
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:ReEncryptFrom",
        "kms:ReEncryptTo",
        "rds:CopyDBClusterSnapshot",
        "rds:CopyDBSnapshot",
        "rds:CreateDBClusterSnapshot",
        "rds:CreateDBSnapshot",
        "rds:ModifyDBClusterSnapshotAttribute",
        "rds:ModifyDBSnapshotAttribute",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "rds:AddTagsToResource",
      "Resource": [
        "arn:aws:rds:*:*:snapshot:*",
        "arn:aws:rds:*:*:cluster-snapshot:*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/TenableContext": "DataAnalysis"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "rds:DeleteDBSnapshot",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "rds:snapshot-tag/TenableContext": "DataAnalysis"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "rds:DeleteDBClusterSnapshot",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "rds:cluster-snapshot-tag/TenableContext": "DataAnalysis"
        }
      }
    }
  ]
}

EC2 Instance Scanning (Workload Protection)

In the below IAM policy, the ec2:CopySnapshot appears three times. Each of these entries is required for a different purpose:

  1. Copy with Request Tag (Condition: aws:RequestTag/ErmeticContext)
    • Allows copying a snapshot only if a specific request tag is provided.
    • Ensures that the destination snapshot is automatically tagged.
    • Use case — Instances and AMIs where tagging of new snapshots is required.
  2. Copy any Snapshot as Source (Resource: arn:aws:ec2:*::snapshot/snap-*)
    • Allows using any existing snapshot as a source for copying.
    • Use case — Private AMIs that need to copy an existing snapshot.
  3. Copy with Resource Tag (Condition: aws:ResourceTag/ErmeticContext)
    • Allows copying snapshots that already have a specific resource tag.
    • Use case — Instances where only snapshots with a specific tag are permitted for copying.

For more details on AWS’s handling of source vs destination snapshots in IAM statements, see: Enhancing Resource-Level Permissions for Copying Amazon EBS Snapshots.

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:CreateSnapshot",
      "Resource": "arn:aws:ec2:*:*:volume/*"
    },
    {
      "Effect": "Allow",
      "Action": "kms:CreateAlias",
      "Resource": "arn:aws:kms:*:*:alias/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CopySnapshot",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "kms:CreateKey",
        "kms:TagResource"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/ErmeticContext": "WorkloadAnalysis"
        }
      }
    },
    {
      "Effect": "Deny",
      "Action": "kms:TagResource",
      "Resource": "*",
      "Condition": {
        "Null": {
          "aws:ResourceTag/ErmeticContext": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "ec2:CopySnapshot",
      "Resource": "arn:aws:ec2:*::snapshot/snap-*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CopySnapshot",
        "ec2:DeleteSnapshot",
        "ec2:ModifySnapshotAttribute",
        "kms:CreateAlias",
        "kms:CreateGrant",
        "kms:Decrypt",
        "kms:EnableKeyRotation",
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:ReEncryptFrom",
        "kms:ReEncryptTo",
        "kms:RevokeGrant",
        "kms:ScheduleKeyDeletion"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/ErmeticContext": "WorkloadAnalysis"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:CreateGrant",
        "kms:Decrypt",
        "kms:ReEncryptFrom"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "kms:ViaService": "ec2.*.amazonaws.com"
        }
      }
    }
  ]
}

ECR Scanning Workload Protection Policy

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }
  ]
}

Terraform Policy

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::<bucket_name>",
        "arn:aws:s3:::<bucket_name>/*",
      ]
    }
  ]
}

Where <bucket_name> is the name of the relevant S3 bucket.

Amazon Bedrock Invocation Logging

Note: The policy below should include every Amazon S3 bucket and every AWS KMS key that Amazon Bedrock uses as a logging destination, across all regions you monitor.
Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::bucketName",
        "arn:aws:s3:::bucketName/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "kms:Decrypt",
      "Resource": "bucketKeyArn"
    }
  ]
}

Where <bucketName> is the name of the relevant S3 bucket.

JIT Policy for AWS Account Access

Use these policies to allow Tenable One AI Exposure to manage JIT access to AWS accounts and permission sets through AWS Identity Center.

Use only one policy per environment, depending on whether AWS Identity Center is managed directly from the Management Account for Account Access or via a Delegated Administrator Account for Account Access.

Management Account for Account Access

Copy

JSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListRoles",
                "iam:ListPolicies"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:GetRole",
                "iam:ListAttachedRolePolicies",
                "iam:ListRolePolicies",
                "iam:PutRolePolicy"
            ],
            "Resource": "arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetSAMLProvider",
                "iam:UpdateSAMLProvider"
            ],
            "Resource": "arn:aws:iam::*:saml-provider/AWSSSO_*_DO_NOT_DELETE"
        },
        {
            "Effect": "Allow",
            "Action": [
                "identitystore:Describe*",
                "identitystore:List*",
                "sso:AttachManagedPolicyToPermissionSet",
                "sso:CreateAccountAssignment",
                "sso:CreatePermissionSet",
                "sso:DeleteAccountAssignment",
                "sso:DeletePermissionSet",
                "sso:Describe*",
                "sso:DetachManagedPolicyFromPermissionSet",
                "sso:Get*",
                "sso:List*",
                "sso:ProvisionPermissionSet",
                "sso:PutInlinePolicyToPermissionSet",
                "sso-directory:List*",
                "sso-directory:Search*"
            ],
            "Resource": "*"
        }
    ]
}

Delegated Administrator Account for Account Access

Copy

JSON

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sso:AttachManagedPolicyToPermissionSet",
                "sso:CreateAccountAssignment",
                "sso:CreatePermissionSet",
                "sso:DeleteAccountAssignment",
                "sso:DeletePermissionSet",
                "sso:DetachManagedPolicyFromPermissionSet",
                "sso:ProvisionPermissionSet",
                "sso:PutInlinePolicyToPermissionSet"
            ],
            "Resource": "*"
        }
    ]
}

JIT Policy for Application Access

Use these policies to allow Tenable One AI Exposure to manage JIT access to applications managed by AWS Identity Center.

Use only one policy per environment, depending on whether AWS Identity Center is managed directly from the Management Account for Application Access or via a Delegated Administrator Account for Application Access.

Management Account for Application Access

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "identitystore:Describe*",
        "identitystore:List*",
        "sso:CreateApplicationAssignment",
        "sso:DeleteApplicationAssignment",
        "sso:Describe*",
        "sso:Get*",
        "sso:List*",
        "sso-directory:List*",
        "sso-directory:Search*"
      ],
      "Resource": "*"
    }
  ]
}

Delegated Administrator Account for Application Access

Copy

JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sso:CreateApplicationAssignment",
        "sso:DeleteApplicationAssignment",
      ],
      "Resource": "*"
    }
  ]
}