AWS likes to rename, replace, etc their managed policies a fair bit. Generally, before (for instance) outright deleting one, they'll send a deprecation notice. But even with all of that, it's complicated as some people don't read their AWS emails frequently. Sometimes I and a few others have to send tailored temporary CloudFormation stacks to clients, so if it's referencing non-existent policies that's a bit embarrassing on our part. Manual testing is obviously an answer, but in 2021 what we do manually we should try to automate at this point.
Before we get into this "meh practice" policy linting, let's talk about best practices:
This may not work 100%. It may require modification. It just works for our niche project in question. It's a bit grimey, but Reddit asked and I'll be damned if I'm not an OP who delivers.
Like many others, I don't typically develop my code, policies, etc in AWS. Sorry, CodeCommit. What we do have is a CI/CD pipeline that runs against our CodeFormation. AWS is nice enough to have a cfn-lint tool to check for common mistakes, and other third party tools exist for other things, but what about referncing policies that exist? The Cfn may be well formed that references something that doesn't exist at all.
In my case, to avoid rotting managed policies, in our CI (without disclosing individual internal stacks) I'll regex for arn:aws:iam::aws:policy\/([A-Za-z0-9_\-]{1,150}) in any yaml and pass the captured policy (not the ARN stub) to the below script.
As for the API Gateway, it passes to a lambda function that runs this:
All this will do is return a list of policy names latest to AWS when calling the API Gateway. Feel free to put the API Gateway behind any necessary security, WAF, etc.
So what we have is a script pulling each policy name, comparing them against AWS, and throwing an error if one doesn't exist in AWS. Running this on push works, like most CI, but running it on a schedule is probably better.