AWS IAM isn't well designed, policy attachments all over the place making it near impossible to figure out what set of permissions you might actually have
As hair-splitting, its IAM can be well designed but the management tooling/observability can be lacking.
In my mind, "not well designed" would be "I cannot represent my security need in this policy language" versus the more common opinion "AWS IAM is a black box" means "I cannot understand why I am getting a 403"
GCP's IAM is, in this premise, not well designed because I cannot express ReadOnlyAccess in their policy language without having a constantly updating policy job, because they do not have wildcards in the Action as does AWS. Contrast `Action: ["s3:Get*"]` which would cheerfully include access to a future GetBucketV7 verb to GCP's "storage.buckets.get" which must always be specified, in full, and when storage2.buckets.get comes out, it's my job to find all references and patch them
and too much string to hang yourself with