TL;DR – For an enterprise level solution that authorizes user access, use application roles as much as possible instead of security groups.
One of the principles of the zero trust model is “least privileged access”, which is very well documented. However, I am focusing on a specific area that sometimes goes unnoticed until it’s too late and it becomes painful to correct.
This is my attempt to warn security architects and anyone planning to implement a zero trust model to ensure they pay attention to this detail because it can be costly to correct later on.
First, some basics.
In general terms authentication (Authn) is the process of verifying a user is who they say they are, whereas authorization (Authz) covers what the user should have access to, the specific permissions that have been (hopefully) assigned to the user based on the job they do. This post focuses on authorization (Authz), the access the user gets once they are authenticated.
Authorization can be based on various triggers, among them group membership and/or role assignment:
- Groups are a logical collection of users, which can have specific privileges assigned to them. Groups can be on-prem AD groups that are synchronized to cloud or cloud-only groups [Ref: M365 and AAD groups]. Groups are not necessarily tied to an application, but security groups can be used in multiple applications and can be used for access control purposes. They can also be nested, meaning that group 1 can be a member of group 2, and so on.
- Roles are used to assign permissions to users and groups. Roles are specific to a function within a specific application.
Applications and services handle authorization in different ways.
A security best practice for enterprise solutions is to have applications and services rely on a central identity provider (IdP) for authentication and authorization whenever possible. This is referred to as SSO (single sign-on) or federation. Reference this quickstart for additional details.
Those applications and services that delegate authentication and sometimes authorization to the central IdP, handle authorization in various different ways:
- Some applications and services can only handle authorization internally, so we simply need to authenticate the user and the application knows what permissions (groups/roles/privileges/responsibilities/profiles) are assigned to that user. These applications do this various different ways, that includes:
- The use of LDAP calls to a directory service to check group membership.
- Through their own internal authorization. Many enterprise applications (SAP, Salesforce, etc.) have their own authorization mechanisms within the application. That means that there is no mapping between the permissions set within the application to any group in any directory and typically this is for a good reason, as we explain below. For applications/services with independent authorization, an integration solution (i.e. SCIM) is required to synchronize the assignment of permissions between the application/service and the identity management solution. This supports the ultimate goal of having a single identity governance solution to view, audit, and modify all roles and assignments that a user has access to. More on that on a follow-up post.
- Some applications can be configured to receive and process an access token or assertion that is passed when the user logs in. These assertions or access tokens include attributes or claims that tell the relying or service provider what specific groups and/or roles are assigned to the user that is connecting.
The applications that can consume access tokes or assertions will process those claims (roles and/or groups) and proceed with the authorization based on the claims that were passed on that token. For example, if the claim in the access token includes [roles=’Admin’], then the user receives access to a special area granted only to admins. Keep in mind that regardless of the protocol payload (SAML assertion, OIDC access token, or a Kerberos token), they are all bound by a maximum header size.
As noted above these claims can include a variety of attributes, including groups or roles.
- When groups are used, all groups that the user is a member of are typically included in the token. This includes groups that are not associated with the application/service. Some services, allow the prioritization of groups in the claims by using custom filters per application, but these results can often be unpredictable.
- For roles, only the roles associated with that specific application are included.
Maybe smaller organizations can initially survive with using groups to determine the level of authorization to applications or services. However, larger enterprises, where users are often members of multiple groups, need to be concerned with the token size. All tokens have a maximum allowable limit due to header size restrictions. For example, Okta’s group limit is 100, Azure/O365 restricts SAML tokens to 150 groups, 200 groups for JWTs. Additionally, this affects Kerberos tokens which prevents login when a user is a member of around 125 groups or more. As such, if a user is a member of 202 groups, then the user will receive errors when trying to login to various applications/services (i.e. HTTP 400).
It’s just a math problem.
Applications and services can have a multitude of permissions. At the time of writing, Salesforce has a maximum of 1500 custom profiles, which is the main permission set within the service, Azure has a maximum of 5000 custom roles per tenant and AWS has a maximum of 5000 IAM roles per AWS account. Any authorization that needs to be attached to security groups will then require a security group to be created per role per account/tenant. When you take in to consideration that many enterprises have hundreds of tenants and accounts, it starts to compound quite rapidly. Even if an organization consolidates, typically the math for a large enterprise can realistically result in hundreds of thousands of security groups with users having to be members of hundreds of these groups, which can quickly add up to surpass the maximums mentioned above.
This is not new to the IT industry as many large organizations have experienced the growing pains of discovering these complications as they merge or expand in size and have a desire to increase their security posture. More information can be found by searching online for “token bloat”.
In addition to token bloat, there are also known AD replication issues with group membership sizing as well as the issue of the lifetime of groups, since groups can continue to exist long after the application is removed, and may even be used for other unintended purposes. Consequently, this is why most industry experts recommend that enterprises, or any organizations planning for their future, use role based authorization, instead of group membership due to the above mentioned restrictions and also due to the amount of information that can end up in the token.
How Azure AD makes it easier.
Unlike other IdPs, Azure AD natively handles and manages application roles for enterprise application, including many SaaS services as well as custom applications. Therefore, when assigning users to these services, the administrators can choose specific application roles, which are not mapped to any security groups.
These roles can also be included in access packages that can be assigned to or requested by end users and for which access reviews can be created.
In a follow-up post I will go into the various options that are available, as well as some of my own recommendations when architecting security solutions for identity governance.