Attribute based access control to AWS resources
Credit: https://aws.amazon.com/blogs/security/securing-resource-tags-used-for-authorization-using-service-control-policy-in-aws-organizations/

Attribute based access control to AWS resources

Part of the platform vision we have at Coinmama includes mandatory tagging of all managed resources in our AWS account. When I say "managed" resources, I refer to resources managed by Infrastructure as Code (usually HashiCorp's Terraform in our case). 

Because we use mandatory and uniform tagging across all managed resources that we provision inside AWS, that gives us a trust anchor that we can utilize inside our applications to make for more repeatable and cleaner patterns when creating applicative IAM policies.

That's admittedly a lot of big fancy words, so let me try to break that down a bit.

First of all, I talk about using mandatory and uniform tagging across all managed - e.g., Terraform created - resources. I'm not going to go over the basics of tagging inside AWS here. There are some great resources, including this great whitepaper published by AWS, for getting started with how, why and tag strategies. At Coinmama, our Terraform design assigns a "project name" and "environment" internally to the Terraform workspace names that we use. This helps us maintain individual workspaces for projects which tweak individual settings while leveraging similar (or occasionally the exact same) codebases.

We set the tags globally like this:

# main.tf

locals {

 # … other stuff …

 aws_tags = {

   # … other stuff …

   environment   = local.values.environment # Something like "test", "dev", "qa", "prod", "staging"

   project       = local.values.project # Something like "web-front", "user-auth-service", etc

 }

}

And then reference this aws_tags in all AWS resources like this:

resource "aws_security_group" "sg" {

 # … other stuff …

 tags       = local.aws_tags

}

 

…

resource "aws_instance" "instance" {

 # … other stuff …

 tags = merge({ Name : "instance" }, local.aws_tags)

}

 

Sometimes we'll merge in other tags - notably the Name tag as seen above - as needed, but will always use the base tags. 

If desired we could also enforce the tags on the IAM level, too. For example, we could set the following IAM policy which would validate the environment tag on the AWS side…

{

   "Version": "2012-10-17",

   "Statement": {

       "Effect": "Allow",

       "Action": "ec2:CreateTags",

       "Resource": "arn:aws:ec2:*:*:instance/*",

       "Condition": {

           "StringEquals": {

               "aws:RequestTag/environment": [

                   "test",

                   "dev",

                   "qa",

                   "prod",

                   "staging"

               ]

           },

           "ForAllValues:StringEquals": {"aws:TagKeys": "environment"}

       }

   }

}

 

Or we could go one step further and require the tags on all resources across an AWS Organization using Tag Policies, which is definitely worth a quick read!

This creates a mandatory and uniform tagging policy across all managed resources that we provision inside AWS.

The next step is to utilize this as a trust anchor inside our applications to make for more repeatable and cleaner patterns. To explain this, let's say that we keep our application configurations stored inside of an S3 bucket. We want to give each project/environment access to its own configuration, while denying access to the rest of the files in the bucket.

One way to accomplish this would be to dynamically generate a role for each cartesian product of project/environment which would grant the specific access we needed inside of the S3 bucket. You can see an example AWS implementation of this technique on this excellent article by AWS - look for the "Permission Templates" heading.

The problem with this is that it requires an individual policy for each role created, and in addition needs to update the S3 bucket policy every time a project or environment is added. (In the example above, one would need to update the S3 bucket policy every time a tenant is added).

However, we can use a technique called Attribute Based Access Control (ABAC) to use a static bucket policy that can leverage the tagging that we implemented above. 

{

   "Version": "2012-10-17",

   "Statement": {

       "Effect": "Allow",

       "Principal": {

           "AWS": [

               "arn:aws:iam::account-id:root"

           ]

       },

       "Action": "s3:GetObject",

       "Resource": "arn:aws:s3:::my-bucket/${aws:PrincipalTag/environment}/${aws:PrincipalTag/project}/config.env",

       "Condition": {

           "ForAllValues:StringEquals": {

               "aws:TagKeys": [

                   "project",

                   "environment"

               ]

           }

       }

   }

}

 

This will utilize the tagging policy enforced above to dynamically resolve the tags on the IAM entity requesting access to S3. This entity can be a Lambda role, an EC2 instance role, a role assigned to EKS/ECS or even a dynamic IAM entity created by a third party tool, such as Hashicorp Vault. 

In this setup, environments and projects can be created, modified or removed without ever needing to make changes to the above S3 bucket role. It is important to note that we have a hardcoded AWS account ID (or list of them for cross-account access) which would still need to be modified to restrict the source accounts (else some third party who knew your naming structure could create an IAM entity with the required tags and gain access to your configuration files). 

We now have a static - or nearly static - centrally manageable IAM policy which can be used as a clean and repeatable pattern for our applicative IAM needs which utilizes the trust anchor provided by our mandatory and uniform tagging used across all managed resources that we provision inside AWS.

As I've illustrated, this pattern can help to eliminate external tooling and reduce the changesets required in policy management when introducing changes to an ever-evolving modern web application. It's not a perfect one-size-fits all solution - there's a limit to how much you can do with tags - but hopefully this will help you adhere to important architectural principals, such as the KISS principal.

Has this helped you? Do you have another interesting pattern to share? Questions? Leave your comments below!

要查看或添加评论,请登录

Issac Goldstand的更多文章

  • Automating CI for Infrastructure as Code

    Automating CI for Infrastructure as Code

    In my last post, we learned about how Infrastructure as Code can be tested using standard software testing techniques…

  • Automated Testing for Terraform

    Automated Testing for Terraform

    In my last post, I went over some of the automated testing techniques that I use to test infrastructure as code at…

  • CI For Platform Teams

    CI For Platform Teams

    One of the key components of a baseline SSDLC is automated testing. In a large organization that wants to move as…

  • Hashicorp Waypoint - Some initial thoughts, and what's yet to come...

    Hashicorp Waypoint - Some initial thoughts, and what's yet to come...

    Last week Hashicorp dropped a product bomb on the world. Not one, but two new open source products were released! I…

  • Vaults & TLS-es & K8S-es & Ingress-es (Oh, my!)

    Vaults & TLS-es & K8S-es & Ingress-es (Oh, my!)

    Time for another DevOps related post - this time about the Vault Helm chart. I've been mulling over what I could write…

  • Using Wazuh 3.13 to monitor Docker containerized applications

    Using Wazuh 3.13 to monitor Docker containerized applications

    Over the past few weeks, I've taken responsibility over a project that utilizes the open source SIEM (Security…

    1 条评论
  • Using consul auto-encrypt with k8s

    Using consul auto-encrypt with k8s

    I'm an old-school consul user who stepped away for a couple of years, and came back - delighted! - to consul's…

    3 条评论
  • Traefik and Consul: Tips & Tricks

    Traefik and Consul: Tips & Tricks

    I've been a long-time fan and evangelist of consul (and most of the Hashicorp products, for that matter), so as I've…

    1 条评论
  • Advanced Home Assistant Add-on Development with Visual Studio Code

    Advanced Home Assistant Add-on Development with Visual Studio Code

    A short while ago, I wrote a post exploring a boilerplate add-on for Home Assistant and how to set up a streamlined…

    1 条评论
  • Creating Your First Home Assistant Add-On

    Creating Your First Home Assistant Add-On

    One of the things I like so much about the amazing Home Assistant project is its endless potential for extensibility…

    2 条评论

社区洞察

其他会员也浏览了