Access packages (MS Graph API)
The MS Graph API connector supports Entra ID Entitlement Management access packages through two surfaces:
-
The
accessPackageobject class: read and query only. -
The
__accessPackages__attribute on theuserobject: readable on request, updatable using replace semantics.
Reading or writing access packages requires the EntitlementManagement.Read.All permission. Granting or revoking access packages additionally requires EntitlementManagement.ReadWrite.All. Add these under the EntitlementManagement item when you set API permissions in Azure.
|
Access package UID format
Each access package can have multiple assignment policies. The connector represents each package+policy pair as a separate object. The __UID__ and __NAME__ both use a compound colon-delimited format.
__UID__ formatpackageId:policyId
__NAME__ formatPackageDisplayName:PolicyDisplayName
Each object carries the single assignment policy it represents in the assignmentPolicy attribute, alongside the access package’s own attributes. A package with three assignment policies returns three objects, each with the same package attributes and a different assignmentPolicy.
Query access packages
This command queries all access packages:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/system/azuread/accessPackage?_queryFilter=true&_fields=__NAME__,displayName"
{
"result": [
{
"_id": "5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98",
"__NAME__": "TestAccessPackage:SecondPolicy",
"displayName": "TestAccessPackage:SecondPolicy"
},
{
"_id": "2d90ab77-2623-4557-bec5-144f8eb6d147:055b56c2-322c-40df-b999-87c350133ea4",
"__NAME__": "Employee:Initial Policy",
"displayName": "Employee:Initial Policy"
}
],
"resultCount": 2,
"pagedResultsCookie": null,
"totalPagedResultsPolicy": "NONE",
"totalPagedResults": -1,
"remainingPagedResults": -1
}
The accessPackage object class uses offset-based paging ($skip), not the token-based paging ($skiptoken) used by other object types in this connector. Only _queryFilter=true (list all) and reads by compound UID are supported.
|
Read an access package
Use the compound packageId:policyId UID to read a specific access package:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/system/azuread/accessPackage/5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98"
{
"_id": "5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98",
"__NAME__": "TestAccessPackage:SecondPolicy",
"displayName": "TestAccessPackage:SecondPolicy",
"description": "Test Access Package",
"isHidden": false,
"createdDateTime": "2026-06-16T14:56:03.380Z",
"modifiedDateTime": "2026-06-16T14:56:03.380Z",
"catalog": {
"id": "fe096441-a946-4ae2-a013-3da9132c6b96",
"displayName": "Employee",
"catalogType": "userManaged",
"state": "published",
"isExternallyVisible": true
},
"assignmentPolicy": {
"id": "6e9ff82e-7b81-4047-9d35-395bd382ae98",
"displayName": "SecondPolicy",
"description": "A test policy for access packages",
"expiration": {
"duration": "P365D",
"type": "afterDuration"
}
}
}
Read a user’s access packages
The __accessPackages__ attribute is not returned by default. Request it explicitly using _fields:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/system/azuread/__ACCOUNT__/136bfdcd-dd11-4508-bb32-b333b3690ea2?_fields=__NAME__,__accessPackages__"
{
"_id": "136bfdcd-dd11-4508-bb32-b333b3690ea2",
"__NAME__": "adama@example.onmicrosoft.com",
"__accessPackages__": [
"5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98",
"2d90ab77-2623-4557-bec5-144f8eb6d147:055b56c2-322c-40df-b999-87c350133ea4"
]
}
The values match the accessPackage UID format: packageId:policyId.
The connector returns assignments that are current, meaning their state is Delivered, Delivering, or PartiallyDelivered. A package you granted moments ago can appear here while Entra ID is still delivering it. Assignments in the terminal Expired and DeliveryFailed states aren’t returned.
|
Update a user’s access packages
Set __accessPackages__ to the full desired list of packageId:policyId compound IDs. The connector computes a diff against the user’s current assignments and posts the appropriate ADMIN_ADD and ADMIN_REMOVE requests to the Entitlement Management API.
| Always send the complete desired set. The connector replaces the current state with the value you provide. It doesn’t accept discrete add or remove values. |
You can update __accessPackages__ using PATCH or PUT.
PATCH
Use a JSON patch body with the replace operation:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "Content-Type: application/json" \
--request PATCH \
--data '[{
"operation": "replace",
"field": "__accessPackages__",
"value": [
"5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98",
"2d90ab77-2623-4557-bec5-144f8eb6d147:055b56c2-322c-40df-b999-87c350133ea4"
]
}]' \
"http://localhost:8080/openidm/system/azuread/__ACCOUNT__/136bfdcd-dd11-4508-bb32-b333b3690ea2"
PUT
Use a PUT upsert to replace __accessPackages__ alongside other user attributes:
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "Content-Type: application/json" \
--header "If-Match: *" \
--request PUT \
--data '{
"__accessPackages__": [
"5b7c2fb6-ab91-4642-9b94-d447516efbe6:6e9ff82e-7b81-4047-9d35-395bd382ae98",
"2d90ab77-2623-4557-bec5-144f8eb6d147:055b56c2-322c-40df-b999-87c350133ea4"
]
}' \
"http://localhost:8080/openidm/system/azuread/__ACCOUNT__/136bfdcd-dd11-4508-bb32-b333b3690ea2"
| Access package assignment changes can take several seconds to a few minutes to propagate in Entra ID. A read immediately after an update might not yet reflect the change. |
Limitations
-
The
accessPackageobject class supports read and query only. Create, update, delete, and liveSync aren’t supported. -
__accessPackages__on the user object supportsreplacesemantics only, noaddorremovepatch operations. -
The
accessPackageobject class doesn’t support search filters. Because each object is a synthetic combination of an access package and one of its assignment policies, noaccessPackageattribute maps to a single filterable Graph property. Only two query forms work:_queryFilter=trueto list everything, and a read by the compound UID. Any other filter fails with anUnsupportedOperationException.