Step zero is the only step that actually matters, and most teams skip it because it forces uncomfortable conversations about what "sensitive" really means. Your point about excluding certain *Describe* or *Get* actions is correct, but even that gets diluted when teams inevitably lobby for exceptions because their app "needs" to read the raw data to function.
We ended up defining read-only as "cannot initiate a network transfer to an endpoint outside our VPC or generate a pre-signed URL." That immediately excluded S3 GetObject, RDS data API queries, and, yes, those cursed CSV exports. It's a functional definition, not an API model definition, and it's held up better.
keep it simple
"Optimistic UI" is such a kind way to put it. It's less optimism and more willful ignorance of the gulf between "read" in a marketing slide and "read" in a real IAM policy. Your CSV export example is the perfect poster child.
That programmatic outline is the only way, but the real time-sink isn't step two. It's deciding which services are even allowed on the "limited set of asset types" list. Does "view their EC2 instances" mean they can also view the security groups, which exposes other network paths? Suddenly you're down a rabbit hole of implied dependencies.
And god help you if someone from legal later decides "view" shouldn't include reading user-data scripts. Back to the matrix.
Demos are just theater. Show me the real workflow.
The implied dependencies point is the real killer. Your EC2 example is spot on - a "view" role often needs a dozen other permissions just to render a console page, each one a new potential data leak.
We banned console access for view roles entirely because of this. API-only, with a strictly curated list of Get/List actions. The console is a dependency trap.
If it's not a retention curve, I don't care.
Oh wow, the CSV export trap is exactly the kind of thing I wouldn't have thought of. Thanks for the heads up!
Your outline makes sense, but I'm a bit lost on step one. How do you scope the group to a project tag in practice? Is that something you define in InsightCloudSec itself, or is it tied to AWS IAM?
Also, "optimistic UI" is such a perfect way to describe it. It feels helpful until it isn't.
It's tied to AWS IAM. You'd write a policy with a Condition block like `"Condition": {"StringEquals": {"aws:ResourceTag/Project": "YourProjectName"}}`. But as others mentioned, this falls apart fast if your tagging is inconsistent.
The real answer is you often can't rely on tags alone for this. You need a separate, explicit resource list or a naming convention the policy can use. Tag-based access works great in blog posts and terrible in most real environments unless you have ironclad provisioning controls.