{"slug": "why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account", "title": "Why Read-Only Is the Only Safe Way to Let AI Near Your AWS Account", "summary": "CloudWise, a cloud cost optimization tool, has detailed its security model for AWS account access, emphasizing that its read-only monitoring role is scoped to specific actions and cannot make any write calls. The company's remediation role, which can make changes, is deliberately separate and includes explicit deny rules to protect critical resources. The design aims to ensure that AI-driven cost optimization cannot accidentally harm a user's AWS environment.", "body_md": "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.\n\nWhen 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')`\n\nis the only path the connect flow calls.\n\nThat stack's policy (`cloudwise-cur-setup-template.yaml`\n\n) is a bespoke allow-list we wrote and maintain, not the AWS-managed `ReadOnlyAccess`\n\npolicy. That distinction matters more than it sounds like it should: `ReadOnlyAccess`\n\nis 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`\n\n, `rds:DescribeDBInstances`\n\n, `s3:ListAllMyBuckets`\n\n, `ce:GetCostAndUsage`\n\n, `compute-optimizer:GetEC2InstanceRecommendations`\n\n, and so on — read the whole thing at [cloudcostwise.io/security/permissions](https://cloudcostwise.io/security/permissions?utm_source=blog&utm_medium=hub&utm_campaign=read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account), 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*`\n\n, `Describe*`\n\n, `List*`\n\n, or `BatchGet*`\n\ncall — plus `sts:GetCallerIdentity`\n\nand `iam:SimulatePrincipalPolicy`\n\n, which CloudWise uses to check what a role *can* do without ever calling it. There is no `Put`\n\n, `Create`\n\n, `Delete`\n\n, `Update`\n\n, `Attach`\n\n, or `Modify`\n\nverb 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.\n\n(One nuance, for the pedants, because I'd rather you catch it than an auditor: the CUR bucket in that same template does have a bucket policy permitting `s3:PutObject`\n\n— granted to AWS's own `billingreports.amazonaws.com`\n\nservice principal, not to CloudWise. That's how AWS itself delivers your Cost and Usage Report into a bucket you own. It's AWS writing to you, not us writing to anything.)\n\nIf you want CloudWise to actually *fix* waste — stop an idle NAT gateway, delete an orphaned snapshot, right-size an instance — that is never part of onboarding. It requires deploying a second, separate CloudFormation stack (`CloudWise-Remediation`\n\n, using `cloudwise-remediation-role.yaml`\n\n) that you reach only from `settings/remediation`\n\nor `setup/permissions`\n\n, deliberately after the point where you've already seen what a read-only scan finds. Nothing in the sign-up or connect flow grants this role. You have to go looking for it.\n\nThat role's policy carries an explicit **Deny** block that overrides everything else, no matter what any other statement in the policy says:\n\n`iam:*`\n\n, `organizations:*`\n\n, `sts:*`\n\n— CloudWise can never touch identity, org structure, or assume other roles`secretsmanager:GetSecretValue`\n\n/ `PutSecretValue`\n\n/ `CreateSecret`\n\n/ `UpdateSecret`\n\n— no access to your secrets, ever`cloudtrail:DeleteTrail`\n\n, `cloudtrail:StopLogging`\n\n, `config:DeleteConfigRule`\n\n, `config:StopConfigurationRecorder`\n\n, `guardduty:DeleteDetector`\n\n— your audit and detection trail can't be turned off`s3:DeleteBucket`\n\n, `ec2:DeleteVpc`\n\n, `ec2:DeleteSubnet`\n\n, `ec2:DeleteSecurityGroup`\n\n, `rds:DeleteDBInstance`\n\n— no deleting the structural stuff that would actually hurt`ec2:AuthorizeSecurityGroupIngress/Egress`\n\n, `ec2:RevokeSecurityGroupIngress/Egress`\n\n, `ec2:CreateSecurityGroup`\n\n— CloudWise cannot open, close, or create a network path`kms:CreateKey/CreateGrant/Encrypt/Decrypt/GenerateDataKey*`\n\n, `ssm:*`\n\n— no touching encryption or Systems ManagerA Deny statement in IAM always wins, regardless of what any Allow statement elsewhere in the same policy — or any other policy — grants. That's not a UI promise. It's how the policy evaluates at the API layer.\n\nYou'll also see a small number of `Create*`\n\nactions in that same policy file — things like `ec2:RunInstances`\n\nor `rds:CreateDBInstance`\n\n. Those exist for one purpose: **rollback**. Before executing an approved action, CloudWise records enough state to reverse it — restart an instance it stopped, recreate a resource it deleted, restore a secret's scheduled deletion. If a fix goes wrong, or you change your mind, there's a way back. That's a narrower and more honest thing than \"can create resources,\" and it's also narrower than \"can never create resources\" — so I'm not going to round it either direction. Read the actual file if you want the specifics; that's the point of publishing it.\n\nHere's the part I actually care about you believing: CloudWise proposes fixes. It does not execute them on its own initiative, ever, under any circumstance we ship today.\n\nThe execution path (`lambdas/remediation_executor/handler.py`\n\n) checks a status field before it will run a single mutating API call, and that status has to read `approved`\n\n. The only thing that writes `approved`\n\nis a separate approval-gateway Lambda, triggered by a verified, authenticated action from you. There is no code path today that sets an action to `approved`\n\nautomatically. If you never click approve, the action sits there, proposed, forever, and nothing happens to your account.\n\nThere's also a second, quieter layer under that: every mutating call CloudWise's execution role makes is tagged with a session tag — `aws:PrincipalTag/cloudwise-action`\n\n— that CloudWise itself sets at execution time, and the role's policy can further condition on that tag. I want to be precise about what this is and isn't: it's real defense-in-depth inside our own execution path, not a lever you hold. You don't set that tag; we do. The thing you actually control is upstream of it — the approve click that has to happen before any of this fires at all.\n\nSo, precisely:\n\n`Get`\n\n/`Describe`\n\n/`List`\n\n/`BatchGet`\n\nactions, verifiable line-by-line at None of that requires you to trust our intentions. It requires you to trust IAM evaluation semantics, which is a much smaller ask, and one you can verify yourself against files we publish rather than a page of prose we wrote about ourselves.\n\nIf you want to see what the read-only role actually finds in your account, [a free, read-only scan](https://cloudcostwise.io?utm_source=blog&utm_medium=hub&utm_campaign=read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account) takes about five minutes, grants nothing beyond what's described above, and changes nothing without you approving it first.", "url": "https://wpnews.pro/news/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account", "canonical_source": "https://dev.to/cloudwiseteam/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account-jj5", "published_at": "2026-08-12 13:54:04+00:00", "updated_at": "2026-08-12 14:19:13.294494+00:00", "lang": "en", "topics": ["ai-products", "ai-tools", "ai-safety", "developer-tools"], "entities": ["CloudWise", "AWS", "CloudFormation", "IAM", "Cost and Usage Report"], "alternates": {"html": "https://wpnews.pro/news/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account", "markdown": "https://wpnews.pro/news/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account.md", "text": "https://wpnews.pro/news/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account.txt", "jsonld": "https://wpnews.pro/news/why-read-only-is-the-only-safe-way-to-let-ai-near-your-aws-account.jsonld"}}