As I see more and more support for tag-based permissions in AWS services, I'm conflicted; while the ability to apply advanced conditionals to control access to resources sounds like a nice thing to have up my sleeve, I can't help but feel that complicating an already challenging space is doing the opposite of what is intended: Keeping your AWS resources secure.
The main problem is this: By using tags for authorisation, you have a multitude of completely new - per-service - actions that can be used to compromise your security posture.
Ignoring the fact that not all AWS services even support using tags for conditionals (check this table if you were wondering which), ask yourself some important questions before you start relying on tags for authorisation.
How Hard Could It Be?
grep of all IAM actions to find those related to creating and deleting tags across all AWS services comes back with nearly 260 results! Even allowing for a few false-positives, this is a non-trivial number. This is what you're going to have to be aware of if you want cover all your bases.
But hey, maybe it's me - maybe I just need to get with the new world order. I mean, how hard can it be to just tag everything and move on with my life?
Resource Tag Support
Pretty hard actually, given not all resources support tags! This means that even if you do get the tag-based approach 100% right, it can only ever work for a subset of AWS resources. I know the service teams at AWS are doing there best in a dynamic and challenging space, but here's an example of the reality: Amazon SQS (usually billed as the first AWS service, released in 2005) only got support for setting tags on create August 22, 2019. The EC2 documentation includes a nice table to show you what resources support tags; while most (but not all!) support tags, not all of those support them on creation. Another one that's burnt me before is that you still can't create tags on the root EBS volumes of EC2 instances created via CloudFormation.
Here's another gotcha that I only discovered while doing some research for this blog: When you use the "ResourceTag/
tag-key" in you IAM conditions, tag key names are not case-sensitive when matched! This means your condition will happily match
KEYNAME, because all those are the same thing, right? Right? RIGHT? (see what I did there!)
In The Real World
Note that my problem with this is not limited to the escalation of privileges in IAM; in some cases you might actually lose access to a resource. While less scary, it can still be problematic.
The most common scenario I've seen in the real world is where a failure to tag a resource appropriately means that the person/role that created a resource can no longer update or delete that resource, because they didn't get the tags right; developers might be allowed to update/delete resources that are tagged with an "environment" tag, or an appropriate "owner" tag, but if they forget to add it they've now created a resource they can't manage or clean-up, and need to ask for help to fix it.
Keep It Simple
Just to be clear; I'm not saying it's not possible manage permissions with tags, I'm saying you shouldn't, because it makes things more complicated:
I'm a big believer that simplicity is the best way to be secure. If it's hard to understand, there's more chance you'll get it wrong. Don't believe me? AWS themselves got this wrong not too long ago with a SageMaker managed policy.
This is why ideas like the single responsibility principal and principal of least privilege are so prevalent; they work! Having multiple ways to set authorise things that use services other than the actual authorisation service of your platform makes it harder for everyone to reason about... And let's not kid ourselves, many developers and users on AWS struggle with IAM permissions in the first place.