Introduction
This guide details the process of configuring Azure Active Directory (Azure AD) to correctly send group membership claims within a JSON Web Token (JWT) for use with Consul's Access Control List (ACL) binding rules. This is particularly relevant when users are members of a large number of groups, which can lead to "group overage" where Azure AD provides a Graph API endpoint for group information instead of embedding the groups directly in the token.
Primer: Important Terms
- Azure Active Directory (Azure AD): Microsoft's cloud-based identity and access management service. It helps employees sign in and access resources.
- OpenID Connect (OIDC): An authentication layer built on top of OAuth 2.0. It allows clients to verify the identity of the end-user based on the authentication performed by an authorization server (like Azure AD) and to obtain basic profile information about the end-user.
- JSON Web Token (JWT): A compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed.
- Claims: Pieces of information asserted about a subject (e.g., a user). In the context of OIDC and JWTs, claims are key-value pairs that describe the authenticated user, such as their name, email, or, in this case, their group memberships.
-
groups
claim: A specific claim within a JWT that contains a list of the security groups to which a user belongs. -
Group Overage: A scenario in Azure AD where a user is a member of too many groups (typically over 150 for ID tokens or 200 for access tokens). When this occurs, Azure AD doesn't embed all group SIDs directly into the JWT. Instead, it includes a special claim (e.g.,
_claim_names
,_claim_sources
) that points to a Graph API endpoint where the complete list of group memberships can be retrieved. This prevents the token from exceeding size limits. -
Consul ACL Binding Rules: Rules within Consul's Access Control List system that map authenticated identities (from OIDC, for example) to Consul policies and roles. These rules often use selectors to match claims from the identity token (like
groups
) to grant appropriate access. - Application Manifest (Azure AD): A JSON file that defines the properties of an Azure AD application registration. It controls how the application integrates with Azure AD, including which claims are issued in tokens.
-
groupMembershipClaims
: A property in the Azure AD application manifest that specifies which types of group claims should be included in tokens."ApplicationGroup"
means only groups explicitly assigned to the application will be included."SecurityGroup"
means all security groups the user is a member of will be included. -
optionalClaims
: A property in the Azure AD application manifest that allows you to configure additional claims (beyond the default set) that should be included in ID tokens and access tokens.
Expected Outcome
Upon completing these steps, the JWT issued by Azure AD will include the user's group memberships directly as a groups
claim. This will enable Consul ACL binding rules that rely on group membership to function as expected, allowing for granular access control based on Azure AD security groups.
Prerequisites
- Consul Enterprise with OpenID Connect (OIDC) authentication enabled.
- Azure Active Directory tenant with an Azure AD application registration for Consul.
- Understanding of Azure AD application manifests.
- Consul version that supports OIDC authentication (e.g., Consul 1.8.0+).
Use Case
A user attempts to authenticate to Consul using OIDC with Azure AD as the identity provider. The Consul ACL binding rule expects a groups
claim in the JWT to determine the user's policies. However, due to group overage, the groups
claim is not present directly in the JWT but is instead referenced by a Graph API endpoint. This guide provides the necessary steps to ensure the groups
claim is directly embedded in the JWT, allowing the Consul ACL binding rule to evaluate correctly.
Procedure
Step 1: Access the Azure AD Application Manifest
- Log in to the Azure Portal.
- Navigate to Azure Active Directory > App registrations.
- Select the application registration associated with your Consul OIDC configuration.
- Under the Manage section in the left-hand navigation pane, select Manifest to open the inline manifest editor.
Step 2: Modify the Azure AD Application Manifest
In the manifest editor, you need to configure groupMembershipClaims
and optionalClaims
to ensure group information is included directly in the ID token and access token.
- Locate the
"groupMembershipClaims"
property. Change its value to"ApplicationGroup"
.
Before (potentially):
"groupMembershipClaims": "SecurityGroup",
After:
"groupMembershipClaims": "ApplicationGroup",
Note: "ApplicationGroup" ensures that groups assigned to the application will be included in the token. If you need all security groups the user is a member of, you might use "SecurityGroup", but "ApplicationGroup" is often preferred for more controlled access and to mitigate group overage issues by only including relevant groups.
-
Add the following
optionalClaims
block if it doesn't exist, or modify it if it does, to includegroups
in both theidToken
andaccessToken
:"optionalClaims": { "idToken": [ { "name": "groups", "additionalProperties": [] } ], "accessToken": [ { "name": "groups", "additionalProperties": [] } ] }
Ensure the
"optionalClaims"
object is correctly placed within the overall JSON structure of the manifest.The relevant part of your manifest should look similar to this after modifications:
"groupMembershipClaims": "ApplicationGroup", "optionalClaims": { "idToken": [ { "name": "groups", "additionalProperties": [] } ], "accessToken": [ { "name": "groups", "additionalProperties": [] } ] }
- Click Save to apply the changes to the application manifest.
Step 3: Verify Consul OIDC Auth Method Configuration
Ensure your Consul OIDC authentication method is configured to map the groups
claim. Based on the provided configuration, this is already correctly set up:
{
"AllowedRedirectURIs": [
"http://localhost:8550/oidc/callback",
"https://consul.yourdomain.com/ui/oidc/callback",
"https://consul.anotherdomain.com/ui/oidc/callback"
],
"BoundAudiences": [
"YOUR_AZURE_AD_APPLICATION_CLIENT_ID"
],
"ListClaimMappings": {
"groups": "groups"
},
"OIDCClientID": "YOUR_AZURE_AD_APPLICATION_CLIENT_ID",
"OIDCClientSecret": "YOUR_AZURE_AD_APPLICATION_CLIENT_SECRET",
"OIDCDiscoveryURL": "https://login.microsoftonline.com/YOUR_AZURE_AD_TENANT_ID/v2.0",
"OIDCScopes": [
"openid",
"https://graph.microsoft.com/.default",
"profile,groups"
],
"VerboseOIDCLogging": true
}
The key part here is "ListClaimMappings": { "groups": "groups" }
and "OIDCScopes": [ "profile,groups" ]
. This configuration tells Consul to expect and map a claim named groups
from the JWT.
Step 4: Verify Consul ACL Binding Rule
Confirm that your ACL binding rule is correctly configured to use the groups
claim for evaluation.
consul acl binding-rule create \
-method=azuread-auth \
-bind-type=policy \
-bind-name=global-management \
-selector='"YOUR_GROUP_NAME" in list.groups'
This rule specifies that a user whose groups
claim (which is a list) contains "YOUR_GROUP_NAME" will be bound to the global-management
policy. Replace "YOUR_GROUP_NAME"
with the actual name of the Azure AD security group you want to use for binding.
Step 5: Test the OIDC Authentication
After making the changes, attempt to authenticate to Consul using your configured Azure AD OIDC method. Verify that the user can now successfully log in and that their permissions are correctly applied based on their group memberships and the Consul ACL binding rules. You can inspect the JWT token (e.g., using jwt.io
if you have access to the token for debugging purposes) to confirm that the groups
claim is now directly present in the payload.
By following these steps, you should resolve issues where Azure AD group overage prevents group claims from being included directly in the JWT, enabling Consul ACL binding rules to function correctly.