ICF 1.5.20.36

Access packages (MS Graph API)

The MS Graph API connector supports Entra ID Entitlement Management access packages through two surfaces:

  • The accessPackage object class: read and query only.

  • The __accessPackages__ attribute on the user object: 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__ format
packageId:policyId
__NAME__ format
PackageDisplayName: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 accessPackage object class supports read and query only. Create, update, delete, and liveSync aren’t supported.

  • __accessPackages__ on the user object supports replace semantics only, no add or remove patch operations.

  • The accessPackage object class doesn’t support search filters. Because each object is a synthetic combination of an access package and one of its assignment policies, no accessPackage attribute maps to a single filterable Graph property. Only two query forms work: _queryFilter=true to list everything, and a read by the compound UID. Any other filter fails with an UnsupportedOperationException.