loading...
Cover image for Find Expired Service Principal

Find Expired Service Principal

tsuyoshiushio profile image Tsuyoshi Ushio ・2 min read

My tenant seems to have a quota limit of the Service Principal.

$ az ad sp create-for-rbac
The directory object quota limit for the Principal has been exceeded. Please ask your administrator to increase the quota limit or delete objects to reduce the used quota.

Since I'm a DevOps guy, I frequently create a service principal. I'd like to find expired service principals on my tenant.

I struggled for a while with OData and JMESPath that is supported with az command. I eventually use jq instead.

Get the current date with the Azure CLI format.

We can use %N for nanosecond, however, it doesn't match the style of the Azure CLI output. I eventually use this command.

CURRENT_TIME=`date -u +'%Y-%m-%dT%H:%M:%S.024000+00:00'`

Get Expired Service Principal

The query is only list the service principal that you create with password credentials.

$ az ad sp list --show-mine | jq ".[] | select(.passwordCredentials[].endDate < \"$CURRENT_TIME\") | { objectId : .objectId, appId: .appId, passwordCredentials : .passwordCredentials, displayName: .displayName, tenantId : .appOwnerTenantId }" 

az ad sp list --show-mine will show the service principals that you created. select will filter the json. The json start with array that has no name. so start with .[]. .[] returns each element of the array. After filter the result, it project some values.

The original structure of the az ad sp list --show-time

[{
  "appId": "YOUR_APP_ID_HERE",
  "appOwnerTenantId": "YOUR_TENANT_ID_HERE",
  "displayName": "procohapp10",
  "objectId": "YOUR_OBJECT_ID_HERE",
  "passwordCredentials": [
    {
      "additionalProperties": null,
      "customKeyIdentifier": null,
      "endDate": "2019-05-02T20:32:27.908964+00:00",
      "keyId": "YOUR_KEY_ID",
      "startDate": "2018-05-02T20:32:27.908964+00:00",
      "value": null
    }
  ],
             :
},
  :
}

Result

{
  "objectId": "YOUR_OBJECT_ID",
  "appId": "YOUR_APP_ID",
  "passwordCredentials": [
    {
      "additionalProperties": null,
      "customKeyIdentifier": null,
      "endDate": "2019-05-02T20:32:27.908964+00:00",
      "keyId": "YOUR_KEY_ID",
      "startDate": "2018-05-02T20:32:27.908964+00:00",
      "value": null
    }
  ],
  "displayName": "procohapp10",
  "tenantId": "YOUR_TENANT_ID"
}

Remove the expired service principal

Please double check if your script works before execute the second last line.

$ az ad sp list --show-mine | jq ".[] | select(.passwordCredentials[].endDate < \"$CURRENT_TIME\") | .objectId" > sp_list.txt
$ lines=`cat sp_list.txt`
$ for item in $lines; do  echo $item | xargs az ad sp delete --id ; done
$ rm sp_list.txt

Confirm removed

It returns zero result.

$ az ad sp list --show-mine | jq ".[] | select(.passwordCredentials[].endDate < \"$CURRENT_TIME\") | .objectId" 

Resource

Posted on by:

tsuyoshiushio profile

Tsuyoshi Ushio

@tsuyoshiushio

Serverless, DevOps, Programming, and Music. Opinion is my own.

Discussion

markdown guide