Every AWS cost tool eventually asks you for the same terrifying thing: an IAM role. And every vendor says the same reassuring word about it: "read-only." I want to tell you exactly what that word means when CloudWise says it, because "read-only" gets used loosely enough in this industry that the word alone shouldn't be enough to trust anyone — including us. So this post is the IAM, not the marketing.

The role you actually grant

When you connect an AWS account through CloudWise's one-click setup, you launch exactly one CloudFormation stack: the monitoring stack. There is no button in onboarding that launches anything else — startConnect('monitoring') is the only path the connect flow calls.

That stack's policy (cloudwise-cur-setup-template.yaml) is a bespoke allow-list we wrote and maintain, not the AWS-managed ReadOnlyAccess policy. That distinction matters more than it sounds like it should: ReadOnlyAccess is enormous and vague — it grants read access to almost every AWS service, including ones CloudWise has no reason to ever look at. Our policy is scoped to what a cost scan actually needs, action by action: ec2:DescribeInstances, rds:DescribeDBInstances, s3:ListAllMyBuckets, ce:GetCostAndUsage, compute-optimizer:GetEC2InstanceRecommendations, and so on — read the whole thing at cloudcostwise.io/security/permissions, which renders the live action count straight off the template, not a number we typed into a page and forgot to update. Every single statement in that policy is a Get*, Describe*, List*, or BatchGet* call — plus sts:GetCallerIdentity and iam:SimulatePrincipalPolicy, which CloudWise uses to check what a role can do without ever calling it. There is no Put, Create, Delete, Update, Attach, or Modify verb anywhere in that role's policy. It cannot make a single write call against your account. Not "shouldn't" — cannot; IAM will reject the attempt at the API layer before it reaches any resource.