Edit - Please refer to http://msdn.microsoft.com/en-us/library/azure/dn720459.aspx for official documentation about directory extensions.

Directory schema extensions enable application developers to extend the directory and develop richer applications without worrying about the limitations imposed by an external store. This preview provides REST interfaces for an application to register, unregister, enumerate, read, write, and filter by extension values. Applications that register extensions in the directory are referenced from all the tenants consenting to that Application. Once a customer tenant has consented to an Application (even for read) the extensions registered on that Application are available in the consenting tenant for reading/writing by any Application that has the appropriate access. If the app developer wants to add more extension attributes, she can update her Application (in her developer tenant) and any tenants that are currently consented to this Application will be enabled for the new attributes. If consent is removed, if the extension is deleted, or if the Application is deleted, the extension values will no longer be accessible on the corresponding directory objects.

Types and Limitations
Currently “User”, “Group”, “TenantDetail”, “Device”, “Application” and “ServicePrincipal” entities can be extended with the following single-valued attributes types:

  • Integer
  • LargeInteger
  • DateTime (must be sent in ISO 8601 - DateTime will be stored in UTC)
  • Binary
  • Boolean
  • String

String type extensions can have maximum of 256 characters and binary extensions are limited to 256 bytes. 100 extension values (across ALL types and ALL applications) can be written to any single object. Directory extensions are available only in Graph api-version 1.21-preview. The application must be consented for write access to register an extension.

Registering an Extension
Let’s walk through an example. Contoso has built an OrgChart application and wants to allow users to make Skype calls from it. AAD does not expose a SkypeID user property. The OrgChart developer could use a separate store such as SQL Azure to store a record for each user’s SkypeID. Instead, the developer registers an extension that can expand User type with a String property. He does this by creating an “extensionProperty” on the Application using Graph API.
POST https://graph.windows.net/contoso.com/applications/<applicationObjectID>/extensionProperties?api-version=1.21-preview
“name”: “skypeId”,
“dataType”: “String”,
“targetObjects”: [“User”]
If the operation is successful, it will return 201 along with the fully qualified extension property name to be used for updating the intended types.
201 Created
“objectId”: “5ea3a29b-8efd-46bf-9dc7-f226e839d146”,
“objectType”: “ExtensionProperty”,
“name”: “extension_d8dde29f1095422e91537a6cb22a2f74_skypeId”,
“dataType”: “String”,        
“targetObjects”: [“User”]
Viewing Extensions Registered by your Application
You can view extensions registered by your application by issuing a GET of the extension properties of the application. This will provide object ID, data type, and target objects for each extension registered by the application.
GET https://graph.windows.net/contoso.com/applications/<applicationObjectID>/extensionProperties?api-version=1.21-preview

Unregistering an Extension
You can unregister an extension registered by your application by issuing a DELETE of the extension object ID as follows:
DELETE https://graph.windows.net/contoso.com/applications/<applicationObjectID>/extensionProperties/<extensionObjectID>?api-version=1.21-preview

Writing Extension Values
Once this application is consented by the admin, any user in the tenant can be updated to include this new property. For example,
PATCH https://graph.windows.net/contoso.com/users/joe@contoso.com?api-version=1.21-preview
“extension_d8dde29f1095422e91537a6cb22a2f74_skypeId”: “joe.smith”
The server will return a 204 if user was successfully updated. The extension value can be removed by sending the same PATCH request with “null” value.
PATCH https://graph.windows.net/contoso.com/users/joe@contoso.com?api-version=1.21-preview
“extension_d8dde29f1095422e91537a6cb22a2f74_skypeId”: null

Reading Extension Values
When directory objects are retrieved, they automatically include the extension values. For example:
GET https://graph.windows.net/contoso.com/users/joe@contoso.com?api-version=1.21-preview
200 OK
“objectId”: “ff7cd54a-84e8-4b48-ac5a-21abdbaef321”,
“displayName”: “Joe Smith”,
“userPrincipalName”: “joe@contoso.com“,
“objectType”: “User”,
“mail”: “null”,
“accountEnabled”: “True” ,
“extension_d8dde29f1095422e91537a6cb22a2f74_skypeId”: “joe.smith”
Filtering by Extension Values
The extension values can also be used as a part of $filter to search directory similar to any existing property. For example:
GET https://graph.windows.net/contoso.com/users?api-version=1.21-preview&$filter=extension_d8dde29f1095422e91537a6cb22a2f74_skypeId eq 'joe.smith'
Prefix searches on extensions are limited to 71 characters for string searches and 207 bytes for searches on binary extensions.

Sample Code
We have published a couple of samples to GitHub to showcase and illustrate the use of directory extensions. We plan to enhance them based on your feedback and as the feature evolves.

PHP Sample

This sample shows how to create and use extensions using PHP. The wiki of this GitHub project helps in understanding the sample and steps to modify/use it.

C# Sample

This sample displays an AAD tenant org chart and allows reading extension values right out of the box. The wiki of this GitHub project helps in understanding the sample and steps to modify/use it.

We would love to hear about the scenarios that you can enable using extensions or any feedback about the usage in our forum. This is just a first step in integrating on-premises AD with Azure AD.


Pavan Kompelli
Rakesh Varna
Arvind Suthar

Azure Active Directory Team