Adding custom data to Azure Active Directory users

Let's pretend we want to build some really custom app, like custom wireguar, we already can watch for changes in active directory so the only missing part left is storage - where can we store key pairs - why not store them directly in active directory user

Exactly for such cases there is an open extensions available

We gonna need access token

access_token=$(az account get-access-token --resource-type ms-graph --query=accessToken -o tsv)

Create

curl -s -i -X POST "https://graph.microsoft.com/v1.0/users/57434352-42b0-4090-9d36-9561ae89c607/extensions" -H "Authorization: Bearer $access_token" -H "Content-Type: application/json" -d '{
    "@odata.type": "#microsoft.graph.openTypeExtension",
    "extensionName": "ua.robota.mactemp",
    "github": "mac2000",
    "id": "ua.robota.mactemp"
}'

Update

curl -s -i -X PATCH "https://graph.microsoft.com/v1.0/users/57434352-42b0-4090-9d36-9561ae89c607/extensions/ua.robota.mactemp" -H "Authorization: Bearer $access_token" -H "Content-Type: application/json" -d '{
    "github": "mac2001",
}'

Retrieve

curl -s -X GET "https://graph.microsoft.com/v1.0/users/57434352-42b0-4090-9d36-9561ae89c607/extensions/ua.robota.mactemp" -H "Authorization: Bearer $access_token" | jq

Set for different user

curl -s -i -X POST "https://graph.microsoft.com/v1.0/users/6c291093-7739-4f89-ad4d-c25072030e3d/extensions" -H "Authorization: Bearer $access_token" -H "Content-Type: application/json" -d '{
    "@odata.type": "#microsoft.graph.openTypeExtension",
    "extensionName": "ua.robota.mactemp",
    "github": "bk",
    "id": "ua.robota.mactemp"
}'

Delete

curl -s -i -X DELETE "https://graph.microsoft.com/v1.0/users/6c291093-7739-4f89-ad4d-c25072030e3d/extensions/ua.robota.mactemp" -H "Authorization: Bearer $access_token"

To help find users here are few examples

tenant_id='695e64b5...'
access_token=$(az account get-access-token --resource-type ms-graph --query=accessToken -o tsv)

# List all users
curl -X GET \
  -H "Authorization: Bearer $access_token" \
  -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/users" | jq ".value"

# List only enabled users
curl -X GET \
  -H "Authorization: Bearer $access_token" \
  -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/users?\$top=999&\$filter=accountEnabled%20eq%20true" | jq ".value[] | {id: .id, mail: .mail}" | pbcopy

# List users from group
curl -s -X GET \
  -H "Authorization: Bearer $access_token" \
  -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/groups/82281f89.../members?\$top=999" | jq ".value[] | {id: .id, mail: (.mail | ascii_downcase)}"


# List groups, filtered by name, select id and mail only
curl -s -X GET \
  -H "Authorization: Bearer $access_token" \
  -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/groups?\$filter=displayName%20eq%20'Hello%20World'&\$select=id,mail" | jq ".value[0]"

# Find group id by name
gid=$(curl -s -X GET -H "Authorization: Bearer $access_token" -H "Content-Type: application/json" "https://graph.microsoft.com/v1.0/groups?\$filter=displayName%20eq%20'Hello%20World'&\$select=id" | jq -r ".value[0].id")

# List users from group
curl -s -X GET \
  -H "Authorization: Bearer $access_token" \
  -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/groups/$gid/members?\$top=999&\$select=id,mail" | jq ".value[] | {id: .id, mail: (.mail | ascii_downcase)}"

This approach may be used to wireup different services, aka thinking about having slack username, github username in active directory as well as other things that may be usefull