The short version
| nable can | nable cannot |
|---|---|
| Read cost, usage and billing data (Cost Explorer, Cost Management, BigQuery billing export) | Create, modify, delete or terminate any resource (EC2, RDS, S3, Lambda, anything) |
| Read resource metadata and CloudWatch metrics for rightsizing (describe calls, GetMetricData) | Read your application data, S3 object contents, database rows, logs content, or customer data |
| Read rightsizing and commitment recommendations (Compute Optimizer, Advisor) | Move, spend, or commit money: no purchase, no Savings Plan or RI buy, no budget changes |
There is exactly one optional write permission in the whole footprint: logs:PutRetentionPolicy, used only if you explicitly ask nable to fix a CloudWatch Log Group that has no retention policy (a common silent cost leak). You can omit it and lose nothing but that one auto-fix. Destructive cleanup actions are off entirely unless you set FINOPS_CLEANUP_ENABLED=true yourself.
Verify before you trust
You do not have to take this page on faith. nable ships the tools to generate a scoped credential and prove it is read-only:
finops setup aws --iam-templateprints the exact CloudFormation policy belowfinops setup aws --iam-terraformprints it as a Terraform snippetfinops setup aws --check-scopeinspects a credential and confirms it has no write permissions
And because nable runs entirely on your machine with no backend, you can watch the network yourself: run it behind a packet capture or an egress allowlist and confirm the only destinations are your own cloud provider APIs, plus anonymous opt-out telemetry (NABLE_NO_TELEMETRY=1 to disable) and, if you opt into peer benchmarking which is off by default, anonymized cost ratios. FINOPS_AIRGAP=1 blocks all of it. Details on the security page.
AWS
least-privilege read-only policy
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "NableReadOnlyFinOps",
"Effect": "Allow",
"Action": [
"ce:GetCostAndUsage", "ce:GetCostForecast",
"ce:GetReservationUtilization", "ce:GetReservationCoverage",
"ce:GetSavingsPlansPurchaseRecommendation",
"ce:GetSavingsPlansUtilization", "ce:GetSavingsPlansUtilizationDetails",
"ce:GetSavingsPlansCoverage", "ce:GetRightsizingRecommendation",
"ce:ListCostAllocationTags", "ce:DescribeCostCategoryDefinition",
"compute-optimizer:GetEC2InstanceRecommendations",
"compute-optimizer:GetLambdaFunctionRecommendations",
"compute-optimizer:GetRDSDatabaseRecommendations",
"compute-optimizer:GetECSServiceRecommendations",
"compute-optimizer:GetEnrollmentStatus",
"compute-optimizer:GetRecommendationSummaries",
"cloudwatch:GetMetricData", "cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics",
"ec2:DescribeInstances", "ec2:DescribeRegions", "ec2:DescribeVolumes",
"ec2:DescribeSnapshots", "ec2:DescribeAddresses",
"ec2:DescribeNatGateways", "ec2:DescribeImages",
"elasticloadbalancing:DescribeLoadBalancers",
"rds:DescribeDBInstances", "rds:DescribeDBSnapshots",
"lambda:ListFunctions", "lambda:GetFunctionConfiguration",
"ecr:DescribeRepositories", "ecr:DescribeImages",
"ecs:ListClusters", "ecs:ListServices",
"ecs:DescribeServices", "ecs:DescribeTaskDefinition",
"logs:DescribeLogGroups", "logs:DescribeLogStreams",
"logs:PutRetentionPolicy", // the one optional write — omit to be pure read-only
"cloudtrail:DescribeTrails", "cloudtrail:GetTrailStatus",
"cloudtrail:GetEventSelectors",
"s3:ListAllMyBuckets", "s3:GetBucketLocation",
"s3:GetBucketIntelligentTieringConfiguration",
"s3:ListBucketMultipartUploads", "s3:ListMultipartUploadParts",
"organizations:ListAccounts", "organizations:ListRoots",
"organizations:ListOrganizationalUnitsForParent",
"organizations:ListParents", "organizations:DescribeOrganizationalUnit",
"organizations:DescribeOrganization", "organizations:DescribeAccount",
"sts:GetCallerIdentity", "sts:AssumeRole"
],
"Resource": "*"
}]
}
Every action is a Get, List, Describe, or read. There is no Create, Delete, Modify, Run, Terminate, or Put anywhere except the single annotated log-retention line.
One optional, separate backend: if you turn on the detailed CUR-via-Athena cost path (off by default, not part of this policy), it additionally needs read access to Athena and Glue plus a scoped s3:PutObject to its own Athena query-results bucket. That is the only write outside log retention, it is opt-in, and it is scoped to a bucket you designate.
Google Cloud
roles to grant the service account
roles/billing.vieweron the billing account, to read costroles/bigquery.dataVieweron the billing-export datasetroles/bigquery.jobUseron the project, to run the export queries
All three are read and query roles. nable reads your Cloud Billing export in BigQuery; it does not write to BigQuery or touch any other GCP service.
Azure
RBAC roles per subscription
- Cost Management Reader, for cost and usage queries
- Reader, for Advisor cost recommendations and the VM list
- Monitoring Reader, for VM CPU metrics used in rightsizing
All three are Reader-tier roles. nable performs no write operation on Azure.
finops setup aws --iam-template), they create a scoped read-only credential in minutes, and nable runs on your machine with that. Nothing leaves your side either way.