I would suggest disallowing the putPolicy*
API call for each of the service supporting resource policies for all of the non-admins. Then providing a structured interface to make changes to these policies. I'm fairly certain users can still create S3 Buckets and SQS queues without having the putPolicy
permission. I do think you need to have the putPolicy permission to create a new CMK.
Cloudformation
If you had all of the resources in question controlled in CF, and your users could submit pull requests to the CF Template. Then you could have your reviewers review the changes before running the stack and implementing the changes.
Simple Workflow Service
Though I don't have personal experience with this service, this might be a good use-case. You could have users submit a proposed policy, have it sent to an approver and have it automatically implemented upon approval by Lambda. This seems like the lowest friction solution to me.
Service Catalog
Again, I don't have personal experience operating this service, but (I believe) you can set up a catalog item to make any change that can be represented by Cloudformation and provide cookie-cutter templates that users are allowed to use. It might be possible to list serveral types of policies with variables the users can control that would allow them flexibility without creating a policy that locks everyone out or otherwise doesn't meet your business standards. Also, this wouldn't require manual approval.
Roll your own
This isn't so hard of a problem that you couldn't write a Lambda or Fargate or other type of service that checks with your businesses ticketing system and implements policies that have been approved. And you might be able to provide an interface that automatically approves certain policies (no allow all, admins have allow all, no deny that apply to admins, etc.), but that depends on how confident you are in your validation logic and what your business needs are.