Custom security attributes in Azure AD part 3: working with custom security attributes

After introducing custom security attributes and creating an attribute set and definitions, we can start assigning values for our custom-created attribute across all the relevant objects within the directory. As a reminder, currently only user, service principal and managed identity object types support custom security attributes, with more to follow. Before you can assign values though, you need to have permissions granted, so let’s expand a bit on the permission model used by custom security attributes.

Granular delegation of custom security attributes permissions

As mentioned in our introduction to custom security attributes, one of the main benefits they offer is the ability to granularly control who can create, manage, assign or even view their values. To facilitate this, we can work with four admin roles, one of which we already introduced above: Attribute definition administrator. The Attribute definition reader is a read-only version of the same role, useful for reporting scenarios. The Attribute assignment administrator role in turn allows users to set values for custom security attributes. Lastly, the Attribute assignment reader role can be used to read (report on) values for said attributes, without being able to modify them.

All these roles can be delegated on a per-set basis, or granted tenant-wide. When granted on the tenant level, designated users can read or manage attributes across all supported object types, for all attribute sets, as well as create new ones. This might be an appropriate scenario for smaller organizations or when you want to centrally exert control over custom security attributes within a larger organization. In such cases assigning the Attribute definition administrator and Attribute assignment administrator role to your Global admin(s) is a reasonable approach. If you want to adhere to the principle of least privilege though, or you plan to store sensitive data that only specific users will be privy to, granting permissions on a per-set basis is likely the way to go.

To grant scoped permissions, the attribute set needs to already exist. This should not be an issue, as the set itself is nothing more than a container, and as such can be created by an administrator. Once created, the administrator can delegate the Attribute definition administrator role to say a department head, which in turn can proceed with creating the attribute definitions and/or populating their values across the relevant object types, as needed. To grant permissions on the attribute set level, open the Azure AD blade > go to the Custom security attributes (Preview) page > select the attribute set in question > select Roles and administrators > select the role you want to grant > click Add assignment > select the user you want to grant the role to.

On the same page, you can get a list of all the users that have been granted access to the selected role, either on the tenant level (shown as Directory (inherited)) or the attribute set level (this resource). You can also obtain this information on a per-user basis, by opening the user’s page and looking at the information presented under the Assigned roles tab. For additional details on what the individual roles entail to and how scoping affects them, refer to the official documentation.

This granular delegation model in turn allows custom security attributes to be used for scenarios similar to those for confidential attributes in AD. For example, you can use them for storing sensitive data such government identification numbers or employee’s salary, all while making sure that only certain authorized users and applications will be able to gain access to said data.

Microsoft is also working on providing proper support for Privileged Identity Management for the aforementioned admin roles. Currently, there is no support for eligible role assignments on a per-set basis. Some other caveats exist, but will likely be addressed in time.

Querying and setting attribute values

Once you have been granted permissions to assign custom security attributes from a given set, or tenant-wide, you can easily perform this action via the UI. To assign our newly created “SSN” attribute to a given user for example, all we need to do is open the Azure AD blade > Users > select the user > select Custom security attributes (preview) > hit the Add assignment button > use the first dropdown to select the Attribute set > then select attribute from the second dropdown > finally add the value and press the Save button. The UI will perform basic data type validation before allowing you to save the value.

We are of course more interested in automation scenarios, so let’s see how we can perform the same operation via the Graph API. We will have to prepare a JSON payload that contains the attribute set as an element, and nested within it, the corresponding attribute(s) we want to configure on the user. Interestingly enough, you are required to provide the data type as well, even though the service should have this information readily available from the attribute definition. Anyway, once you have the JSON payload prepared, issue a PATCH request against the /users/{userid} endpoint:

One thing to keep in mind that the JSON payload is case sensitive, or at least some elements are. A “204 No content” reply will indicate success for the operation, and you can now verify the attribute value was successfully configured by issuing the corresponding GET request. Unfortunately, filtering support for custom security leaves a lot to be desired, so in most cases we will need to rely on client-side filters. We can however filter all user objects for which we have configured a given custom security attribute’s value:

GET$count=true&$select=id,displayName,customSecurityAttributes&$filter=customSecurityAttributes/HRdata/NoticePeriod eq 14


People that have not been assigned the Attribute assignment reader or equivalent role will not be able to see custom security attribute values for any user. This also applies to users looking at their own profile data – the corresponding page within the Azure AD blade UI will be grayed out, and Graph queries will throw an “Invalid custom security attribute” error. Similarly, if they have been granted access to specific attribute set(s) only, they will be unable to view/set values for attributes from other sets.

It’s worth mentioning that even though we used a regular “member” account in the examples above, custom security attributes can also be assigned to Guest users, as well as to objects synchronized from on-premises AD (you cannot sync values from on-premises though). And as mentioned already, assignment can also be performed via the Azure AD blade UI. Filtering on custom security attributes is also available therein.

Of course, one can also update or clear attribute values as needed, either via the UI or the corresponding Graph API calls. As these operations are straightforward, we will not cover them here, but you can see examples in the official documentation. All the operations we have covered so far can also be performed via the Azure AD PowerShell module (version of the Preview branch) and support for the Microsoft Graph SDK is likely coming soon.

Auditing operations with custom security attributes

It should come as no surprise that most operations related to management of attribute sets and definitions are audited, as is assignment of custom security attribute values. You can find the corresponding audit log entries under the Azure AD blade > Audit logs, where you can filter based on Core directory service and AttributeManagement category. For some record types, multiple entries might be generated, with one of them usually presenting the relevant details under the Modified properties tab, whereas the other one shows it empty. Adding/removing items from the allowedValues list of predefined values is one such example.

To get the full list of audited operations, click the Activity filter button. As other operations and object types become supported, you can expect the list of audited activities to grow. Based on customer’s feedback, we might even see events such as “queried custom security attribute value” added, to address some requirements for the healthcare or government sector.

Some known issues and limitations

Unfortunately, as with most preview functionalities, working with custom security attributes is currently subject to some known issues. For example, we cannot delete custom security attribute definitions, instead we can only “deactivate” them, which leaves the already assigned values intact. The same applies to predefined values. Some other permissions-related issues are listed in the official documentation.

Support for custom security attributes across Azure AD is currently somewhat limited, as they cannot be used with group objects, including the creation of dynamic membership rules based on their values. Microsoft is already panning support group, device, application objects and more. In time, features such as Access Reviews or Conditional access policies will be updated to support custom security attributes. Directory synchronization scenarios are also part of the planned improvements.

One notable area for Microsoft to improve upon is the filtering capability, which sadly that has been a long-standing annoyance with the Graph API itself. Until better support is added, you will likely need to rely on client-side functionalities to filter just the objects you care about.

Some of the current limits might need to be extended, to accommodate larger tenants, but overall they seem reasonable. The licensing requirements might also be off-putting, and since they are actually enforced in code, can also create some annoyances for people wanting to try the functionality first.

In the last article of these series, we will compare custom security attributes against older directory extension methods.

This entry was posted in Azure AD, Graph API, Microsoft 365, Office 365. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.