avatarTeri Radichel

Summarize

AWS IAM Permission Boundaries Versus Service Control Policies

ACM.373 Designing use of Permission Boundaries and Service Control Policies for credential management across and organization

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Part of my series on Automating Cybersecurity Metrics. The Code.

🔒 Related Stories: AWS Security | IAM | AWS Organizations

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~In the last post I revisited AWS IAM Permission Boundaries and how they can help you prevent privilege escalation. I demonstrated what they can and cannot do, to some degree.

In this post I’m going to consider using a Permission Boundary versus a Service Control Policy (SCP) to solve a particular problem.

The problem I would like to solve is this:

I want to make sure that users are only ever allowed to change their own passwords, change their own MFA, and manage their own developer credentials.

Denying the IAM user’s ability to change their own policies is fairly straightforward when you create a user policy as demonstrated in prior posts.

The problem is that the IAM administrator can create a new user, get the password, create a policy that allows changing any password, assign the overly permissive policy to the new user and then login as the new user.

I wrote about this and other forms of privilege escalation here:

How can we prevent this? One way was using a Permission Boundary. We could also try to leverage an AWS IAM Service Control Policy.

Which is better?

Permission Boundary to limit changing passwords

As explained in the last post, we can assign a policy to an administrator that requires them to assign a particular AWS IAM Permission Boundary to every user they create or modify.

So what if we want to ensure that policy is applied to every user in every account in our organization?

We would have to deploy that permission boundary in every account.

When you choose an AWS Permission Boundary for a user in the AWS console you have to select from a list of policies in that account. You can’t pick policies from another account. For consistency we could give the Permission Boundary the same name in every account and we could make sure the admin policy requires that particular Permission Boundary name.

The other thing with Permissions Boundaries is that odd issue with resource policies and NotPrincipal in a Deny statement we would need to be aware of that I wrote about in my last post.

Additionally, I was reading some of the details about permission boundaries and how they apply to session policies that sound a bit dicey. I’ll have to look at this more again later.

Permissions granted directly to a session are not limited by an implicit deny in an identity-based policy, a permissions boundary, or session policy. When you assume a role and make a request, the principal making the request is the IAM role session ARN and not the ARN of the role itself.

The above would apply to federated users assuming roles when using an IdP as well.

Permissions granted directly to a session are not limited by an implicit deny in an identity-based policy, a permissions boundary, or session policy.

That’s important to know if you use any session policies or allow them. I’ll have to revisit that later.

I’m not going to fully dive into session policies here but essentially you can inject policies when you create an AWS IAM session.

You can create role session and pass session policies programmatically using the AssumeRole, AssumeRoleWithSAML, or AssumeRoleWithWebIdentity API operations. You can pass a single JSON inline session policy document using the Policy parameter. You can use the PolicyArns parameter to specify up to 10 managed session policies.

If you use a session policy you have to be very explicit about what that session is allowed to do because some other policies and restrictions will not apply.

Service Control Policies do not apply to the root management account but if we were to add a permission boundary to users in that account, it would apply. But for my particular design, I am not going to allow creation of new users in the root account beyond the rootadmin (what I formerly called OrgRoot) or the first user I create in a new AWS management account. That means I probably won’t need a permission boundary in that account.

Service Control Policies for limiting password changes and credential management

In an earlier post I suggested that it would be interesting to have a specific IAM account for IAM resources. However, IAM policies only apply to users in the current account. We can’t create one PermissionBoundary in a single IAM account and share it across the organization. Wouldn’t that be nice?

Well that’s kind of what Service Control Policies do. You can manage a policy in a single place and apply it across the organization. What if we could create an SCP that only allows any user in our organization to change their own username and password and other credentials? That would be great.

But can we use a Service Control Policy to control actions with ${aws:username}?

Let’s test it out.

Create a new Service Control Policy. It seems like we should be able to because if we enter an invalid condition in the IAM console, we get the error below. Invalid Global Condition Key.

Side note: The error messages here are very nice, as is the specific location of the error in the code. If you’re having problems with a CloudFormation template policy, try copying and pasting it into the console.

So what’s a Global Condition Key? Here’s the documentation:

If we check that documentation for the condition key we want to use it’s in the list:

So it should work. If I fix the name of the condition the error indicator disappears. But will it work?

Can we use that to create a policy that limits users to changing their own credentials?

For an initial test, I added some actions related to credential management to my SCP.

What’s wrong with the above policy?

First, I’m denying these actions if the user matches a certain name. I want to deny the actions when the username does not match the current user.

What if we change it to NotResource?

That’s not supported in SCPs:

There are a few other things we can’t use in SCPs also:

Well that’s a problem. We can’t disallow the actions unless the resource in the actions is the current principal. And as explained in prior posts, that’s not always going to work anyway because not all these actions have a user ARN in the resources.

We can use variables in policies but how do those really work?

When the policy is evaluated, the policy variables are replaced with values that come from the conditional context keys passed in the request.

I’ve explained this before but what are context keys?

Global condition context keys can be used as variables in requests across AWS services.

That’s the list I provided above — a defined list of values that you can use to replace variables in policies.

Service specific condition keys can also be used as variables when interacting with AWS resources, but are only available when requests are made against resources which support them.

To find the context keys you can use with each service use this list:

Choose your service and click on Condition keys. Here’s the list of values in requests we can use to replace a variable.

Is there a way to get the role or user that a request is operating on from these resources? No. So we cannot use a condition to prevent actions if the user is not the current user either.

Bummer.

So when it comes to IAM policies across all accounts, Service Control Policies have some limitations at the time of this writing.

Update: I found one other possible option on using PrincipalARN which I explore in a later post.

"ArnNotLike": {
      "aws:PrincipalARN": [
        "arn:aws:iam::*:role/Role1AllowedToBypassThisSCP",
        "arn:aws:iam::*:role/Role2AllowedToBypassThisSCP"
      ]
    }

In addition, AWS has come out with some new options I’ll look at in future posts in advance of AWS re:Invent 2023.

Perhaps some new interesting announcements will help us out.

Abstraction to reduce management overhead

I keep writing about the principle of abstraction in cybersecurity to reduce misconfigurations, mistakes, and the things you need to monitor.

If we have to manage Permission Boundaries in every account that’s kind of a pain.

When do we use Permission Boundaries? We use it when people are creating new policies and assigning them to users, roles, or groups.

Can we limit those actions to a single account?

Users: We could put all our users in one account and grant them cross-account roles. That would be one thing that could help simplify our architecture. Then we could prevent user creation across the rest of the organization. We can limit our Permission Boundary as it pertains to users to a single account.

Roles: We need roles in every account. Users need to assume cross-account roles. Lambda functions use roles. AWS Batch uses roles. EC2 instances use roles. We cannot limit roles to a single account. For the purposes of the specific problem in this post, why are we using a permission boundary? We are trying to prevent creation of a policy that allows changing other people’s credentials. What if we limit those actions to our IAM account(s) in an SCP? Then we have no need for a permission boundary on our roles (for this specific problem.)

My proposed design (subject to testing)

So what do we end up with?

An organization (production) environment with an IAM account for the organization.

A sandbox environment with an IAM account for testing IAM changes before pushing them to production.

A Service Control Policy will prevent credential changes or user creation across the organization except in my IAM accounts.

A Permission Boundary will only exist in my IAM accounts and I will use that to limit credential changes, which are only possible in the IAM accounts with this design.

I also need to revisit Session Policies to see if and how they could be used to by pass the above restrictions. I’ll save that for another post.

The only way to know how well this works is to test it. But before I do that I have a couple of other things to implement.

See upcoming posts for how this ties into the administration of accounts and environments in my overall AWS Organizations architecture.

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2023

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
Permission Boundary
Service Control Policy
Aws Organizations
Iam
Security
Recommended from ReadMedium