May 3, 2023
IAM
Curtis Castrapel

AWS Permission Bouncers: Letting Loose in Dev, Keeping it Tight in Prod

Ever had a slight configuration change take down production services? Wish you could give teams more AWS permissions in dev/test accounts, but less in production? Right sizing IAM policies for each team and account can be a tedious task, especially as your environment grows. In this post, we’ll explore how IAMbic brings order to multi-account AWS IAM chaos.

Ever had a slight configuration change take down production services? Wish you could give teams more AWS permissions in dev/test accounts, but less in production? 

Right sizing IAM policies for each team and account can be a tedious task, especially as your environment grows. In this post, we’ll explore how IAMbic brings order to multi-account AWS IAM chaos.

What’s IAMbic?

IAMbic is a framework for managing the lifecycle of IAM permissions across multiple providers in a single place, using a familiar Git workflow. You can see the full history of IAM changes in Git History, making it easier to identify the cause of permissions-related production outages.

Now imagine scenarios where you have various IAM entities like Roles and Managed Policies spread across many accounts. IAMbic combines these entities into a single template, helping avoid permission sprawl and policy confusion.

To get started, follow the Getting Started Guide on GitHub.

Creating an IAM role with varying permissions

One common requirement is maintaining developer access to all of your AWS accounts, but with different permissions depending on the account. Typically, developers should have more permissions in development accounts and fewer permissions in production accounts. 

IAMbic makes this process easier compared to using Infrastructure as Code (IaC) tools like Terraform or CloudFormation, because it’s specialized for IAM and manages all of your AWS accounts from a single location.

One template, multiple roles, different permissions

With IAMbic, you can implement different permissions per account by specifying managed policies or inline policies and limiting their inclusion to specific accounts. For instance, you can provide the ViewOnlyAccess managed policy on all accounts where the role exists by adding this block to your IAMbic template:

managed_policies:
  - policy_arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess

To grant more permissions on all accounts except the prod account, use the following block:

managed_policies:
  - policy_arn: arn:aws:iam::aws:policy/job-function/SupportUser
    excluded_accounts:
       - 'prod'

This approach allows for flexibility and scalability as your organization grows, because included_accounts defaults to * (all of your accounts, including new accounts you create in the future). But if you prefer to be more explicit, you can limit accounts using included_accounts:

managed_policies:
  - policy_arn: arn:aws:iam::aws:policy/job-function/SupportUser
    included_accounts:
       - 'dev'
       - 'staging'
       - 'test'

Inline policies work similarly. Define separate policies for development, test, and staging accounts, and another one for production accounts. In the prod_secure_permissions policy, we further restrict permissions to require multi factor authentication and a request tag:

inline_policies:
  - policy_name: dev_test_staging_permissions
    included_accounts:
      - dev
      - test
      - staging
    statement:
      - action:
          - s3:*
          - ec2:*
        effect: Allow
        resource: '*'
  - policy_name: prod_secure_permissions
    included_accounts:
      - prod
    statement:
      - action:
          - ec2:StartInstances
          - ec2:StopInstances
        effect: Allow
        resource: '*'
        condition:
          Bool:
            aws:MultiFactorAuthPresent: "true"
          StringEquals:
            aws:RequestTag/SecureValue: "true"
  - policy_name: prod_permissions
    included_accounts:
      - prod
    statement:
      - action:
          - s3:GetObject
          - s3:ListBucket
          - ec2:DescribeInstances
        effect: Allow
        resource: '*'

Single template, dynamic role name

Handling IAM roles across multiple accounts can be challenging when role names lack context, making it difficult to quickly pinpoint the source of an issue. For instance, consider a situation where you find an intriguing action in your CloudTrail logs executed by `arn:aws:iam::447153953033:role/engineering`. Identifying the associated account for 447153953033 demands context switching, which slows down the process of locating the problem.

IAMbic resolves this issue by offering dynamic role names based on the account. By designing an IAMbic role template with the name {{var.account_name}}_engineering that exists across multiple accounts, the differences between accounts become evident in your logs. For instance, if we had prod and test accounts, the role names for these accounts would be displayed as arn:aws:iam::447153953033:role/prod_engineering and arn:aws:iam::847153953033:role/test_engineering in the CloudTrail logs, respectively. This makes it more convenient to distinguish between similarly named roles across accounts.

Preventing Drift

By using the `iambic_managed: enforced` template option, we can instruct IAMbic to revert any out-of-band modifications to our templated role. When this flag is set, IAMbic considers the template as the definitive source of truth for the role and will automatically undo any out-of-band changes back to the template's state.

Complete Role Template

To manage permissions across multiple AWS accounts and environments with different role names, you can use the following IAMbic role template as a starting point. This template includes separate inline policies for development, test, and staging environments, as well as for the production environment. It also uses dynamic role names based on the account to provide better context and easier management.

template_type: NOQ::AWS::IAM::Role
included_accounts:
  - dev
  - test
  - staging
  - prod
identifier: '{{var.account_name}}_engineering'
iambic_managed: enforced
properties:
  description: IAMbic engineering role on {{var.account_name}}
  assume_role_policy_document:
    statement:
      - action: sts:AssumeRole
        effect: Allow
        principal:
          service: ec2.amazonaws.com
  inline_policies:
    - policy_name: dev_test_staging_permissions
      included_accounts:
        - dev
        - test
        - staging
      statement:
        - action:
            - s3:*
            - ec2:*
          effect: Allow
          resource: '*'
    - policy_name: prod_permissions
      included_accounts:
        - prod
      statement:
        - action:
            - s3:GetObject
            - s3:ListBucket
            - ec2:DescribeInstances
          effect: Allow
          resource: '*'
    - policy_name: prod_secure_permissions
      included_accounts:
        - prod
      statement:
        - action:
            - ec2:StartInstances
            - ec2:StopInstances
          effect: Allow
          resource: '*'
          condition:
            Bool:
              "aws:MultiFactorAuthPresent": "true"
            StringEquals:
              "aws:RequestTag/SecureValue": "true"
  managed_policies:
    - policy_arn: arn:aws:iam::aws:policy/job-function/ViewOnlyAccess
      - policy_arn: arn:aws:iam::aws:policy/job-function/SupportUser
      excluded_accounts:
       - 'prod'
  path: /engineering_role/
  role_name: '{{var.account_name}}_engineering'

Identity Center (AWS SSO) Permission Sets 

IAMbic also offers management capabilities for AWS Identity Center / AWS SSO permission sets, akin to its handling of IAM roles. The two high-level steps for accomplishing this are: First, use IAMbic to create a customer managed policy with dynamic permissions across AWS accounts, and second, manage the access rules and managed policy attachments for the permission set. 

In an upcoming blog post, we will dive deeper into this use case.

Conclusion

IAMbic allows cloud administrators and security teams to manage permissions across multiple AWS accounts and environments more easily. This approach is intended to reduce complexity and ensure that your team can focus on more important tasks. By using IAMbic, you can maintain a balance between providing developers with the necessary permissions in dev/test accounts while maintaining strict control in production environments.

If you'd ever like to discuss IAM woes, or have feature requests for IAMbic, please feel free to join our Slack Community and submit/upvote issues on GitHub.

Thank you, David Behroozi, Michael Woodside, Richard Julian, and Ivan Dwyer for your feedback on this post!

Curtis Castrapel

Noq Founder
linkedin
twittergithub

The First IAM Ops Platform for AWS

Learn More