Exactly what access KloudLytics asks for
You create one IAM role in your account. This page lists every permission on it, why each is there, every AWS API a scan calls, and what is never read. It is generated from the same template the onboarding wizard gives you, so you can review it before you sign up and compare it afterwards.
- AWS-managed read policies
- 2
- additional actions, each explained below
- 54
- write actions in any policy we author
- 0
- longest a session can last
- 60 min
Role template v4 · role name kloudlyticsReadOnlyRole
The role and who can use it
The role lives in your account and you can delete it at any time, which ends our access immediately. Its trust policy decides who may assume it. Two conditions must both hold:
- An external ID unique to you. Without it, someone who learned your role’s ARN could ask KloudLytics to assume it on their behalf. AWS calls this the confused deputy problem.
- One named role in our account. Only the scanner’s own role may assume yours, not any identity in the KloudLytics AWS account.
KloudLytics holds no AWS access keys for your account. Each scan asks AWS for temporary credentials, and the role caps a session at 60 minutes.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<KLOUDLYTICS_ACCOUNT_ID>:role/<KLOUDLYTICS_SCANNER_ROLE>"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<YOUR_EXTERNAL_ID>"
},
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::<KLOUDLYTICS_ACCOUNT_ID>:role/<KLOUDLYTICS_SCANNER_ROLE>"
}
}
}
]
}<YOUR_EXTERNAL_ID> and the account and role in arn:aws:iam::<KLOUDLYTICS_ACCOUNT_ID>:role/<KLOUDLYTICS_SCANNER_ROLE> are filled in by the onboarding wizard. They are the only differences between this page and your template.
AWS-managed policies
Two policies written and maintained by AWS provide the baseline. They are broad, and AWS can add services to them. We link to AWS’s own reference for each rather than restating their contents here.
SecurityAudit
arn:aws:iam::aws:policy/SecurityAudit
AWS-managed. Read access to security configuration across services: IAM, encryption settings, logging, network rules, resource policies.
SecurityAudit in the AWS policy referenceViewOnlyAccess
arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
AWS-managed. Lets the role list and describe resources so there is an inventory to check. AWS maintains it and adds services over time.
ViewOnlyAccess in the AWS policy referenceKloudLytics does not use AWS’s ReadOnlyAccess policy, which also allows reading the contents of S3 objects and other stored data.
Additional permissions, one by one
Where the AWS-managed policies do not reach, the role adds 54 specific actions in 6 small policies. Every one is a Get, List, Describe or equivalent read. None creates, changes or deletes anything.
KloudLyticsThreatDetectionReadOnly
Reads whether GuardDuty is on and the findings it has already raised.
| Action | Why it is needed |
|---|---|
| guardduty:ListDetectors | Checks whether GuardDuty is enabled in each region. |
| guardduty:GetDetector | Reads the detector's settings and which protections are on. |
| guardduty:ListFindings | Lists GuardDuty's findings so they appear beside configuration risks. |
| guardduty:GetFindings | Reads the detail of those findings: severity, type, affected resource. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsThreatDetectionReadOnly",
"Effect": "Allow",
"Action": [
"guardduty:ListDetectors",
"guardduty:GetDetector",
"guardduty:ListFindings",
"guardduty:GetFindings"
],
"Resource": "*"
}
]
}KloudLyticsAISecurityReadOnly
Reads Amazon Bedrock configuration: guardrails, logging, agents, knowledge bases and how models are served. No model is invoked.
| Action | Why it is needed |
|---|---|
| bedrock:GetModelInvocationLoggingConfiguration | Checks whether model invocation logging is enabled. |
| bedrock:ListFoundationModels | Lists the foundation models available, to tell an unused account from one using Bedrock. |
| bedrock:ListGuardrails | Lists guardrails, to flag workloads running without one. |
| bedrock:GetGuardrail | Reads a guardrail's configuration to check what it filters. |
| bedrock:ListCustomModels | Lists custom models for the AI inventory. |
| bedrock:GetCustomModel | Reads a custom model's encryption and training-data settings. |
| bedrock:ListAgents | Lists Bedrock agents. |
| bedrock:GetAgent | Reads an agent's role and guardrail, to flag over-permissioned agents. |
| bedrock:ListKnowledgeBases | Lists knowledge bases. |
| bedrock:GetKnowledgeBase | Reads a knowledge base's storage and encryption settings. |
| bedrock:ListTagsForResource | Reads tags on Bedrock resources. |
| bedrock:ListImportedModels | Lists imported models for the AI inventory. |
| bedrock:ListModelInvocationJobs | Lists batch inference jobs, to detect Bedrock usage. |
| bedrock:ListPromptRouters | Lists prompt routers, to detect Bedrock usage. |
| bedrock:ListInferenceProfiles | Lists inference profiles, to detect cross-region inference. |
| bedrock:ListCustomModelDeployments | Detects models served on demand. Without it an account using Bedrock looks unused and AI checks pass on nothing. |
| bedrock:ListMarketplaceModelEndpoints | Detects models served through Marketplace endpoints. |
| bedrock:ListProvisionedModelThroughputs | Detects models served through provisioned throughput. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsAISecurityReadOnly",
"Effect": "Allow",
"Action": [
"bedrock:GetModelInvocationLoggingConfiguration",
"bedrock:ListFoundationModels",
"bedrock:ListGuardrails",
"bedrock:GetGuardrail",
"bedrock:ListCustomModels",
"bedrock:GetCustomModel",
"bedrock:ListAgents",
"bedrock:GetAgent",
"bedrock:ListKnowledgeBases",
"bedrock:GetKnowledgeBase",
"bedrock:ListTagsForResource",
"bedrock:ListImportedModels",
"bedrock:ListModelInvocationJobs",
"bedrock:ListPromptRouters",
"bedrock:ListInferenceProfiles",
"bedrock:ListCustomModelDeployments",
"bedrock:ListMarketplaceModelEndpoints",
"bedrock:ListProvisionedModelThroughputs"
],
"Resource": "*"
}
]
}KloudLyticsCostGovernanceReadOnly
Reads whether AWS Budgets are configured.
| Action | Why it is needed |
|---|---|
| budgets:ViewBudget | Checks whether any budget exists for the account. |
| budgets:DescribeBudgetAction | Reads whether a budget has an action attached. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsCostGovernanceReadOnly",
"Effect": "Allow",
"Action": [
"budgets:ViewBudget",
"budgets:DescribeBudgetAction"
],
"Resource": "*"
}
]
}KloudLyticsSecurityReadOnly
Security settings the AWS-managed policies do not cover.
| Action | Why it is needed |
|---|---|
| kms:GetKeyRotationStatus | Checks whether automatic rotation is on for each key. |
| kms:GetKeyPolicy | Reads key policies to find keys usable from outside the account. |
| kms:ListKeyPolicies | Lists the policies attached to each key. |
| glue:GetTriggers | Reads Glue triggers for the data-pipeline inventory. |
| ssm:GetDocument | Reads the Session Manager preferences document, to check whether sessions are logged. |
| ssm:DescribeParameters | Lists Parameter Store names and types to flag secrets not stored as SecureString. Values are not read. |
| macie2:GetMacieSession | Checks whether Macie is enabled. |
| lambda:ListFunctionUrlConfigs | Lists Lambda function URLs. |
| lambda:GetFunctionUrlConfig | Reads a function URL's auth type, to flag ones open to the internet. |
| cognito-idp:ListUserPools | Lists Cognito user pools. Users are not listed. |
| cognito-idp:DescribeUserPool | Reads a pool's password policy, MFA and advanced-security settings. |
| ecr:GetRegistryScanningConfiguration | Checks whether image scanning is configured for the registry. |
| dms:DescribeReplicationInstances | Flags publicly accessible DMS replication instances. |
| redshift:DescribeLoggingStatus | Checks whether audit logging is on for each Redshift cluster. |
| account:GetAlternateContact | Checks that a security contact is set. The name, e-mail and phone are removed before the response is stored. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsSecurityReadOnly",
"Effect": "Allow",
"Action": [
"kms:GetKeyRotationStatus",
"kms:GetKeyPolicy",
"kms:ListKeyPolicies",
"glue:GetTriggers",
"ssm:GetDocument",
"ssm:DescribeParameters",
"macie2:GetMacieSession",
"lambda:ListFunctionUrlConfigs",
"lambda:GetFunctionUrlConfig",
"cognito-idp:ListUserPools",
"cognito-idp:DescribeUserPool",
"ecr:GetRegistryScanningConfiguration",
"dms:DescribeReplicationInstances",
"redshift:DescribeLoggingStatus",
"account:GetAlternateContact"
],
"Resource": "*"
}
]
}KloudLyticsApiGatewayReadOnly
Reads API Gateway configuration. Neither AWS-managed policy grants it.
| Action | Why it is needed |
|---|---|
| apigateway:GET | Reads REST and HTTP API configuration: stages, authorisers, validators, domains. Limited to those resources; request and response bodies are not read. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsApiGatewayReadOnly",
"Effect": "Allow",
"Action": [
"apigateway:GET"
],
"Resource": [
"arn:aws:apigateway:*::/restapis",
"arn:aws:apigateway:*::/restapis/*",
"arn:aws:apigateway:*::/apis",
"arn:aws:apigateway:*::/apis/*",
"arn:aws:apigateway:*::/domainnames",
"arn:aws:apigateway:*::/domainnames/*"
]
}
]
}KloudLyticsExtendedReadOnly
Account-level defaults and service enablement the AWS-managed policies do not grant.
| Action | Why it is needed |
|---|---|
| ec2:GetEbsEncryptionByDefault | Checks whether new EBS volumes are encrypted by default. |
| s3:ListBucketMultipartUploads | Finds incomplete multipart uploads that are silently billed. Lists the keys and ids of unfinished uploads, never object contents. |
| ec2:GetSnapshotBlockPublicAccessState | Checks the account-level block on public EBS snapshots. |
| ec2:GetInstanceMetadataDefaults | Checks whether IMDSv2 is the account default. |
| cloudtrail:GetInsightSelectors | Checks whether CloudTrail Insights is enabled. |
| iam:SimulatePrincipalPolicy | Asks IAM whether this role holds a permission, so a missing grant is never reported as a finding. Evaluates policies; returns no account data. |
| backup:ListBackupVaults | Checks whether a backup vault exists. |
| inspector2:BatchGetAccountStatus | Checks whether Inspector is enabled. |
| detective:ListGraphs | Checks whether Detective is enabled. |
| glue:GetJobs | Reads Glue job definitions for the inventory. |
| codebuild:ListProjects | Lists CodeBuild projects. |
| codebuild:BatchGetProjects | Reads project configuration, including environment variables, to flag credentials stored in plain text. |
| lightsail:GetInstances | Detects Lightsail instances, which sit outside the usual EC2 controls. |
| lightsail:GetLoadBalancers | Detects Lightsail load balancers. |
Policy document
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsExtendedReadOnly",
"Effect": "Allow",
"Action": [
"ec2:GetEbsEncryptionByDefault",
"s3:ListBucketMultipartUploads",
"ec2:GetSnapshotBlockPublicAccessState",
"ec2:GetInstanceMetadataDefaults",
"cloudtrail:GetInsightSelectors",
"iam:SimulatePrincipalPolicy",
"backup:ListBackupVaults",
"inspector2:BatchGetAccountStatus",
"detective:ListGraphs",
"glue:GetJobs",
"codebuild:ListProjects",
"codebuild:BatchGetProjects",
"lightsail:GetInstances",
"lightsail:GetLoadBalancers"
],
"Resource": "*"
}
]
}Optional cost policy
Not part of the role. Offered separately because it is the one grant that reads billing data; the product works without it.
| Action | Why it is needed |
|---|---|
| ce:GetCostAndUsage | Reads spend by service for the cost view. |
| ce:GetCostForecast | Reads AWS's own forecast for the month. |
| ce:GetDimensionValues | Lists the services and regions spend can be grouped by. |
| cloudwatch:GetMetricData | Reads utilisation metrics to find idle resources. |
AWS APIs a scan calls
A scan makes 209 distinct calls across 59 AWS services. CloudTrail records them under the role’s name, so you can check this list against what actually happened.
accessanalyzer2 calls
- list-analyzers
- list-findings
account1 call
- get-alternate-contact
acm2 calls
- describe-certificate
- list-certificates
apigateway5 calls
- get-domain-names
- get-request-validators
- get-resources
- get-rest-apis
- get-stages
apigatewayv23 calls
- get-apis
- get-authorizers
- get-domain-names
autoscaling2 calls
- describe-auto-scaling-groups
- describe-policies
backup1 call
- list-backup-vaults
bedrock12 calls
- get-guardrail
- get-model-invocation-logging-configuration
- list-custom-model-deployments
- list-custom-models
- list-foundation-models
- list-guardrails
- list-imported-models
- list-inference-profiles
- list-marketplace-model-endpoints
- list-model-invocation-jobs
- list-prompt-routers
- list-provisioned-model-throughputs
bedrock-agent3 calls
- get-agent
- list-agents
- list-knowledge-bases
budgets1 call
- describe-budgets
cloudformation3 calls
- describe-stack-resources
- describe-stacks
- get-template
cloudfront1 call
- list-distributions
cloudsearch2 calls
- describe-domains
- describe-service-access-policies
cloudtrail3 calls
- describe-trails
- get-event-selectors
- get-insight-selectors
cloudwatch2 calls
- describe-alarms
- list-metrics
codebuild2 calls
- batch-get-projects
- list-projects
cognito-idp2 calls
- describe-user-pool
- list-user-pools
config3 calls
- describe-config-rules
- describe-configuration-recorders
- describe-delivery-channels
detective1 call
- list-graphs
directconnect1 call
- describe-connections
dms1 call
- describe-replication-instances
dynamodb3 calls
- describe-continuous-backups
- describe-table
- list-tables
ec225 calls
- describe-addresses
- describe-availability-zones
- describe-flow-logs
- describe-images
- describe-instance-attribute
- describe-instances
- describe-internet-gateways
- describe-nat-gateways
- describe-network-acls
- describe-network-interfaces
- describe-route-tables
- describe-security-groups
- describe-snapshot-attribute
- describe-snapshots
- describe-subnets
- describe-volumes
- describe-vpc-endpoint-connections
- describe-vpc-endpoints
- describe-vpc-peering-connections
- describe-vpcs
- describe-vpn-connections
- describe-vpn-gateways
- get-ebs-encryption-by-default
- get-instance-metadata-defaults
- get-snapshot-block-public-access-state
ecr3 calls
- describe-repositories
- get-registry-scanning-configuration
- get-repository-policy
ecs7 calls
- describe-container-instances
- describe-task-definition
- describe-tasks
- list-clusters
- list-container-instances
- list-task-definitions
- list-tasks
efs1 call
- describe-file-systems
eks2 calls
- describe-cluster
- list-clusters
elasticache2 calls
- describe-cache-clusters
- describe-replication-groups
elasticbeanstalk2 calls
- describe-applications
- describe-configuration-settings
elb4 calls
- describe-load-balancer-attributes
- describe-load-balancer-policies
- describe-load-balancers
- describe-tags
elbv27 calls
- describe-listeners
- describe-load-balancer-attributes
- describe-load-balancers
- describe-rules
- describe-tags
- describe-target-groups
- describe-target-health
es2 calls
- describe-elasticsearch-domain
- list-domain-names
events2 calls
- describe-event-bus
- list-rules
firehose2 calls
- describe-delivery-stream
- list-delivery-streams
glacier2 calls
- get-vault-access-policy
- list-vaults
glue2 calls
- get-jobs
- get-triggers
guardduty2 calls
- get-detector
- list-detectors
iam17 calls
- generate-credential-report
- generate-service-last-accessed-details
- get-account-authorization-details
- get-account-password-policy
- get-account-summary
- get-credential-report
- get-open-id-connect-provider
- get-role
- get-saml-provider
- get-service-last-accessed-details
- get-user
- list-account-aliases
- list-open-id-connect-providers
- list-saml-providers
- list-server-certificates
- list-service-specific-credentials
- list-virtual-mfa-devices
inspector21 call
- batch-get-account-status
kms6 calls
- describe-key
- get-key-policy
- get-key-rotation-status
- list-grants
- list-key-policies
- list-keys
lambda6 calls
- get-policy
- list-function-url-configs
- list-functions
- list-layer-versions
- list-layers
- list-tags
lightsail2 calls
- get-instances
- get-load-balancers
logs4 calls
- describe-destinations
- describe-log-groups
- describe-metric-filters
- describe-resource-policies
macie21 call
- get-macie-session
organizations2 calls
- describe-organization
- list-accounts
rds8 calls
- describe-db-clusters
- describe-db-engine-versions
- describe-db-instances
- describe-db-parameters
- describe-db-snapshot-attributes
- describe-db-snapshots
- describe-event-subscriptions
- list-tags-for-resource
redshift3 calls
- describe-cluster-subnet-groups
- describe-clusters
- describe-logging-status
route533 calls
- list-hosted-zones
- list-hosted-zones-by-vpc
- list-resource-record-sets
route53domains1 call
- list-domains
s310 calls
- get-bucket-acl
- get-bucket-encryption
- get-bucket-lifecycle-configuration
- get-bucket-location
- get-bucket-logging
- get-bucket-policy
- get-bucket-tagging
- get-bucket-versioning
- list-buckets
- list-multipart-uploads
s3control1 call
- get-public-access-block
sagemaker6 calls
- describe-endpoint
- describe-notebook-instance
- describe-training-job
- list-endpoints
- list-notebook-instances
- list-training-jobs
secretsmanager2 calls
- get-resource-policy
- list-secrets
securityhub2 calls
- describe-hub
- get-enabled-standards
sns2 calls
- get-topic-attributes
- list-topics
sqs2 calls
- get-queue-attributes
- list-queues
ssm3 calls
- describe-instance-patch-states
- describe-parameters
- get-document
sts1 call
- get-caller-identity
wafv25 calls
- get-logging-configuration
- get-web-acl
- list-resources-for-web-acl
- list-web-acls
- list-web-acls-cloudfront
Two calls are not plain reads. iam generate-credential-report and iam generate-service-last-accessed-details ask IAM to prepare a report about your account, which the scan then reads. They change no resource and no permission.
Outside the scan itself:
- guardduty list-findings, every scan, where GuardDuty is enabled.
- guardduty get-findings, every scan, where GuardDuty is enabled.
- iam simulate-principal-policy, when you verify the role's permissions.
- ce get-cost-and-usage, only with the optional cost policy.
- ce get-cost-forecast, only with the optional cost policy.
- cloudwatch get-metric-data, only with the optional cost policy.
Configuration that can hold secrets
Read-only does not mean nothing sensitive is seen. Some configuration can contain a credential if someone put one there, and finding those is one of the things a scan is for. These are the places KloudLytics reads and checks:
| What is read | Through |
|---|---|
| Lambda environment variables | lambda list-functions |
| EC2 instance user data | ec2 describe-instance-attribute |
| ECS task definition environment variables | ecs describe-task-definition |
| CodeBuild project environment variables | codebuild batch-get-projects |
| CloudFormation templates and stack parameters | cloudformation get-template |
| API Gateway stage variables | apigateway get-stages |
| Elastic Beanstalk environment settings | elasticbeanstalk describe-configuration-settings |
A finding records where a secret is and what kind it looks like, for example an AWS access key in a named environment variable. It never records the secret itself.
The configuration a scan collects is stored encrypted in our AWS account. If one of the fields above holds a secret, that secret is part of what is stored. Moving it into Secrets Manager or a SecureString parameter, which the finding recommends, takes it out of reach of this role.
What is never read
KloudLytics assesses how your resources are configured. It does not read what they hold. None of the following is called by a scan, and none is granted by a policy we author.
S3 object contents
s3: get-object, select-object-content, list-objects, list-objects-v2, list-object-versions
Secrets Manager secret values
secretsmanager: get-secret-value, batch-get-secret-value
Parameter Store values
ssm: get-parameter, get-parameters, get-parameters-by-path, get-parameter-history
Anything encrypted with your KMS keys
kms: decrypt, generate-data-key, re-encrypt
DynamoDB items
dynamodb: get-item, batch-get-item, query, scan
CloudWatch log events
logs: get-log-events, filter-log-events, start-query, get-query-results
SQS messages
sqs: receive-message
Lambda function code
lambda: get-function, invoke
Database contents
rds-data: execute-statement, batch-execute-statement
Bedrock model output
bedrock-runtime: invoke-model, converse
Cognito users
cognito-idp: list-users, admin-get-user
- Nothing is created, changed or deleted in your account.
- No agent, Lambda function or other software is deployed.
- No remediation is applied for you. Fixes are shown for you to review and run.
The full template
This is the CloudFormation template the onboarding wizard produces, with placeholders where your external ID and our scanner’s identity go. Sign up, download yours, and diff the two.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "KloudLytics read-only IAM role for cross-account access (v4)",
"Resources": {
"KloudLyticsRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "kloudlyticsReadOnlyRole",
"MaxSessionDuration": 3600,
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<KLOUDLYTICS_ACCOUNT_ID>:role/<KLOUDLYTICS_SCANNER_ROLE>"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<YOUR_EXTERNAL_ID>"
},
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::<KLOUDLYTICS_ACCOUNT_ID>:role/<KLOUDLYTICS_SCANNER_ROLE>"
}
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/SecurityAudit",
"arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
],
"Policies": [
{
"PolicyName": "KloudLyticsThreatDetectionReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsThreatDetectionReadOnly",
"Effect": "Allow",
"Action": [
"guardduty:ListDetectors",
"guardduty:GetDetector",
"guardduty:ListFindings",
"guardduty:GetFindings"
],
"Resource": "*"
}
]
}
},
{
"PolicyName": "KloudLyticsAISecurityReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsAISecurityReadOnly",
"Effect": "Allow",
"Action": [
"bedrock:GetModelInvocationLoggingConfiguration",
"bedrock:ListFoundationModels",
"bedrock:ListGuardrails",
"bedrock:GetGuardrail",
"bedrock:ListCustomModels",
"bedrock:GetCustomModel",
"bedrock:ListAgents",
"bedrock:GetAgent",
"bedrock:ListKnowledgeBases",
"bedrock:GetKnowledgeBase",
"bedrock:ListTagsForResource",
"bedrock:ListImportedModels",
"bedrock:ListModelInvocationJobs",
"bedrock:ListPromptRouters",
"bedrock:ListInferenceProfiles",
"bedrock:ListCustomModelDeployments",
"bedrock:ListMarketplaceModelEndpoints",
"bedrock:ListProvisionedModelThroughputs"
],
"Resource": "*"
}
]
}
},
{
"PolicyName": "KloudLyticsCostGovernanceReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsCostGovernanceReadOnly",
"Effect": "Allow",
"Action": [
"budgets:ViewBudget",
"budgets:DescribeBudgetAction"
],
"Resource": "*"
}
]
}
},
{
"PolicyName": "KloudLyticsSecurityReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsSecurityReadOnly",
"Effect": "Allow",
"Action": [
"kms:GetKeyRotationStatus",
"kms:GetKeyPolicy",
"kms:ListKeyPolicies",
"glue:GetTriggers",
"ssm:GetDocument",
"ssm:DescribeParameters",
"macie2:GetMacieSession",
"lambda:ListFunctionUrlConfigs",
"lambda:GetFunctionUrlConfig",
"cognito-idp:ListUserPools",
"cognito-idp:DescribeUserPool",
"ecr:GetRegistryScanningConfiguration",
"dms:DescribeReplicationInstances",
"redshift:DescribeLoggingStatus",
"account:GetAlternateContact"
],
"Resource": "*"
}
]
}
},
{
"PolicyName": "KloudLyticsApiGatewayReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsApiGatewayReadOnly",
"Effect": "Allow",
"Action": [
"apigateway:GET"
],
"Resource": [
"arn:aws:apigateway:*::/restapis",
"arn:aws:apigateway:*::/restapis/*",
"arn:aws:apigateway:*::/apis",
"arn:aws:apigateway:*::/apis/*",
"arn:aws:apigateway:*::/domainnames",
"arn:aws:apigateway:*::/domainnames/*"
]
}
]
}
},
{
"PolicyName": "KloudLyticsExtendedReadOnly",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KloudLyticsExtendedReadOnly",
"Effect": "Allow",
"Action": [
"ec2:GetEbsEncryptionByDefault",
"s3:ListBucketMultipartUploads",
"ec2:GetSnapshotBlockPublicAccessState",
"ec2:GetInstanceMetadataDefaults",
"cloudtrail:GetInsightSelectors",
"iam:SimulatePrincipalPolicy",
"backup:ListBackupVaults",
"inspector2:BatchGetAccountStatus",
"detective:ListGraphs",
"glue:GetJobs",
"codebuild:ListProjects",
"codebuild:BatchGetProjects",
"lightsail:GetInstances",
"lightsail:GetLoadBalancers"
],
"Resource": "*"
}
]
}
}
]
}
}
},
"Outputs": {
"RoleArn": {
"Value": {
"Fn::GetAtt": [
"KloudLyticsRole",
"Arn"
]
},
"Description": "Copy this ARN and paste it into KloudLytics to complete setup"
}
}
}How the role has changed
A new permission never reaches an existing role on its own. When the template changes, the app tells you what the update adds and you choose when to apply it.
- v4
- Detection of Bedrock usage served on demand, via Marketplace endpoints, or through provisioned throughput — without it, AI governance checks silently passed on accounts that do use Bedrock
- Bedrock API key (IAM service-specific credential) detection
- v3
- Incomplete S3 multipart upload detection (storage waste)
- Direct IAM permission verification, so a scan error is never reported as a missing permission
- v2
- Account-level EBS snapshot public-access block check
- Account-level IMDSv2 default check
- CloudTrail Insights (API anomaly detection) check
- v1
- SecurityAudit + ViewOnlyAccess baseline
- KMS key rotation and policy checks
- Bedrock imported models, prompt routers, and guardrail inspection
- API Gateway configuration checks
- EBS default encryption, Backup, Inspector, and Detective enablement checks
Find out what is actually exposed in your AWS environment.
Connect one AWS account and run your first security assessment.
No credit card · Agentless · Read-only