ITToolbox

Set this up once

One read-only connection, all three tools.

The tools here read different things from Microsoft, but they can all read them through a single app registration. Do this once and paste the same three values into whichever tools you use, instead of repeating the whole dance each time.

What each tool reads

PermissionNeeded byWhat it is for
Group.Read.AllAccessKitGroups and who is in them
User.Read.AllAccessKitNames, sign-in names and managers
RoleManagement.Read.DirectoryAccessKitWho holds admin roles
SecurityEvents.Read.AllQBRkitMicrosoft Secure Score
Organization.Read.AllQBRkitTenant name and licence counts
Reader (Azure role, not Graph) CostWatchCost data and resource inventory

Every one is read-only. Nothing here can change your tenant, your directory or your subscriptions.

The one-time setup

Run this in Azure Cloud Shell or anywhere with the Azure CLI, signed in as someone who can grant admin consent. It creates the app registration, adds the permissions, consents to them, makes a secret, and prints the three values the tools ask for.

#!/usr/bin/env bash
set -euo pipefail

APP_NAME="IT Toolbox (read-only)"
GRAPH_APP_ID="00000003-0000-0000-c000-000000000000"

# Every permission, resolved by name so there are no GUIDs to mistype.
SCOPES=(
  "Group.Read.All"
  "User.Read.All"
  "RoleManagement.Read.Directory"
  "SecurityEvents.Read.All"
  "Organization.Read.All"
)

app_id=$(az ad app create --display-name "$APP_NAME" --query appId -o tsv)
az ad sp create --id "$app_id" >/dev/null
echo "created app $app_id"

for scope in "${SCOPES[@]}"; do
  perm_id=$(az ad sp show --id "$GRAPH_APP_ID" \
    --query "appRoles[?value=='$scope'].id | [0]" -o tsv)
  az ad app permission add --id "$app_id" --api "$GRAPH_APP_ID" \
    --api-permissions "$perm_id=Role" >/dev/null
  echo "  + $scope"
done

# Consent once, for all of them.
az ad app permission admin-consent --id "$app_id"

# CostWatch reads cost through Azure RBAC, not Graph. Repeat per subscription.
sub_id=$(az account show --query id -o tsv)
az role assignment create --assignee "$app_id" --role Reader \
  --scope "/subscriptions/$sub_id" >/dev/null
echo "  + Reader on subscription $sub_id"

secret=$(az ad app credential reset --id "$app_id" --years 1 \
  --query password -o tsv)

echo
echo "Tenant ID:     $(az account show --query tenantId -o tsv)"
echo "Client ID:     $app_id"
echo "Client secret: $secret"
echo
echo "Store the secret now. Azure will not show it again."

Only using one tool? You can trim the SCOPES list to that tool's rows above. CostWatch needs no Graph permissions at all, so a CostWatch-only setup is just the role assignment line and needs no admin consent.

Then, in each tool

  1. Open the tool and go to Integrations.
  2. Paste the same tenant ID, client ID and client secret.
  3. The tool checks the credentials before it stores them, and tells you which permission is missing if one did not consent.

Each tool encrypts the secret at rest and only ever issues read requests. Rotating the secret in Azure means pasting the new one into each tool you connected.

Open QBRkitOpen CostWatchOpen AccessKit