Bash script to check when an azure’s service principal/application password or certificate expires

Sometimes you are gonna create a service principal on Azure Cloud that will manage some applications or automate some tasks. For example you might use a service principal to upload backups on Azure Storage. A service principal can be created with either password or a certificate but it has an expiration date by default. This means that in order to ensure that you can use your service principal and perform tasks you have assigned to it you have to change the password of certificate from time to time. I have created a simple script that uses azure-cli to check when the password or certificate expires. It can be executed via cron or a monit check and notify you.

You will need to install azure-cli and jq.

Instructions on how to install azure-cli can be found at https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest

To install jq, for apt based distributions, you just execute

apt-get -s install jq

If you do not have a service principal yet you can create it by executing the following command after you have logged in Azure from azure-cli.

$ az ad sp create-for-rbac --name MyServicePrincipal --scopes="/subscriptions/00000000-0000-0000-0000-000000000000"

{
  "appId": "00000000-0000-0000-0000-111111111111",
  "displayName": "MyServicePrincipal",
  "name": "http://MyServicePrincipal",
  "password": "0000-0000-0000-0000-000000000000",
  "tenant": "00000000-0000-0000-0000-000000000000"
}

In order to create a service principal with a certificate instead of password

$ az ad sp create-for-rbac --name MyServicePrincipal --create-cert

Please copy /home/dimka/tmpoi517t8s.pem to a safe place. When run 'az login' provide the file path to the --password argument
{
  "appId": "00000000-0000-0000-0000-111111111111",
  "displayName": "MyServicePrincipal",
  "fileWithCertAndPrivateKey": "/home/dimka/tmpoi517t8s.pem",
  "name": "http://MyServicePrincipal",
  "password": null,
  "tenant": "00000000-0000-0000-0000-000000000000"
}

Copy the private key of the certificate created under /etc/azure-cli/service_principal_key.pem

Create a config file under /etc/azure-cli/azure.cfg with the following contents

SERVICE_PRINCIPAL_USER=00000000-0000-0000-0000-111111111111
TENANT_ID=00000000-0000-0000-0000-000000000000

Make sure that files azure.cfg and service_principal_key.pem can not be read by unauthorized users.

# chmod 600 /etc/azure-cli/azure.cfg /etc/azure-cli/service_principal_key.pem

Create the following script with filename checkAzureKeyExpiration.sh

#!/bin/bash
# Make sure that jq package is installed
 
COLLECTION="${1}"
TYPE="${2}"
FILTER="appId eq '${3}'"
GRAPH_ENDPOINT="${4:-https://graph.windows.net}"

source /etc/azure-cli/azure.cfg

if [[ -z "${SERVICE_PRINCIPAL_USER}" || -z "${TENANT_ID}" ]]
then
   echo "Tenant ID or Service Principal User not defined"
   exit 1
fi

if [ $# -eq 0 ]
then
    echo "Usage: ./$(basename $0) collection [credential type] [application id]"
    echo "Examples:"
    echo "  $(basename $0) applications passwordCredentials 25a550c7-d710-487d-af4e-5f32d07725c4"
    echo "  $(basename $0) applications keyCredentials 25a550c7-d710-487d-af4e-5f32d07725c4"
    exit 2;
fi
 
az login --service-principal -u ${SERVICE_PRINCIPAL_USER} -p /etc/azure-cli/service_principal_key.pem --tenant ${TENANT_ID} &> /dev/null || { echo "Error while login in Azure"; exit 1; }

# Try to get an access token to the Azure AD Graph API
AT="$(az account get-access-token --resource "$GRAPH_ENDPOINT" --query "accessToken" --output tsv)"
if [ $? -eq 0 ]
then
    # Get the tenant ID of the signed-in account and build the request
    #TENANT_ID="$(az account show --query 'tenantId' --output tsv)"
    REQ="${GRAPH_ENDPOINT}/${TENANT_ID}/${COLLECTION}"
 
    # Query the Azure AD Graph API and output the result
    # WARNING: This will not retrieve multiple pages of results, only up to 999.
    RESULT=$(curl --silent --get "${REQ}" \
                  --header "Authorization: ${AT}" \
                  --data-urlencode "api-version=1.6" \
                  --data-urlencode "\$filter=${FILTER}" \
                  --data-urlencode "\$top=999")
    ending_date=$(date -d $(echo ${RESULT} | jq '.value[0].'${TYPE} | grep endDate | awk -F"\"" {'print $4'}) +"%s")
    today=$(date +"%s")
    datediff=$((($ending_date-$today)/86400))

    if [ $datediff -lt 15 ]
    then
      echo "Critical - Days left $datediff"
      exit 1
    else 
      echo "OK - Days left $datediff"
      exit 0
    fi
fi

Execute the script

$ checkAzureKeyExpiration.sh applications keyCredentials 00000000-0000-0000-0000-111111111111
OK - Days left 330

In order to execute the script you will need to give access to the service principal with id 00000000-0000-0000-0000-111111111111 on Windows Azure Active Directory
Go to app registrations on Azure Active Directory resource in https:// portal.azure.com and locate the application 00000000-0000-0000-0000-111111111111 . In there click on “Required Permissions” and select the “Windows Azure Active Directory” API -> this is the Azure Graph API.
Select the permission “Read Directory Data” -> save it and click the “Grant Permission” Button

image001

I have hardcoded the script to fail if the expiration date is in less than 15 days.
It’s a first version of the script and will need to be polished.

Bonus
A monit check can be

check program check-AzureAD-ToraBackups-Expiration with path /bin/bash -c '/usr/local/bin/checkAzureKeyExpiration.sh applications keyCredentials 6766cefd-be1e-448b-b7ad-9a31ade3e3ce'
every 720 cycles
    if status != 0 for 1 cycles then alert

If your set daemon is 60 then the check will be executed every 12 hours and it will alert on the first time that the expiration will be under 15 days.

The script can be modified accordingly and work for nagios too.

Links
https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal
https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal?view=azure-cli-latest

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s