All articles

Get Azure Subscription, Tenant, Client ID and Client Secret

Find your Azure subscription ID and Microsoft Entra tenant ID, register an app for a client ID and secret, assign RBAC roles, and wire all four into DefaultAzureCredential.

0 · log in to like, save & follow Share on LinkedIn Share on X

Four values unlock programmatic access to Azure: the subscription ID (which subscription to bill and manage), the tenant ID (which Microsoft Entra directory you authenticate against), and — for an app or script acting as itself — a client ID and client secret from an app registration. This guide shows where each one lives in the portal and the one-line CLI command for it, then how the four fit together in code.

Naming note: Azure Active Directory is now Microsoft Entra ID. Older docs and screenshots say "Azure AD" — same service, new name.

Get the subscription ID

The subscription is the billing and management boundary; its ID is a GUID you'll pass to SDKs and az commands.

  1. Log in to the Azure Portal.
  2. Search Subscriptions and open the list.
  3. Copy the Subscription ID of the subscription you need.

Get Azure Subscription id

CLI:

az account show --query id --output tsv
az account list --output table          # all subscriptions you can see

Get the tenant ID

The tenant is your Microsoft Entra directory — where users, groups, and app registrations live.

  1. In the portal, search Microsoft Entra ID.
  2. The Overview page shows the Tenant ID directly; with multiple tenants, Manage tenants lists them all.

Get Azure Tenant id

CLI:

az account show --query tenantId --output tsv

Get a client ID and client secret (app registration)

When a script, CI pipeline, or server app needs to call Azure without a signed-in user, you register an application — a service principal — and authenticate with its client ID + secret.

  1. Microsoft Entra ID → App registrations → New registration. Name it (e.g. geekstore-automation) and register.
  2. The app's Overview shows the Application (client) ID — copy it. (The Directory (tenant) ID is repeated here too.)

Azure AD app client id

  1. Certificates & secrets → New client secret. Set an expiry (6–12 months; shorter is safer) and add.
  2. Copy the secret Value immediately — it is shown once and never again. Store it in a secret manager, not in code or a repo.

Azure AD app secret id

  1. Give the principal permissions with an RBAC role — nothing works until it has one:
az role assignment create \
    --assignee <client-id> \
    --role Contributor \
    --scope /subscriptions/<subscription-id>/resourceGroups/geekstore-rg

Scope as narrowly as you can — one resource group beats the whole subscription.

The CLI shortcut that does registration + secret + role in one step:

az ad sp create-for-rbac \
    --name geekstore-automation \
    --role Contributor \
    --scopes /subscriptions/<subscription-id>/resourceGroups/geekstore-rg

Its JSON output contains appId (client ID), password (client secret), and tenant — everything below.

Using the four values

Modern Azure SDKs read them from environment variables via DefaultAzureCredential:

export AZURE_TENANT_ID=<tenant-id>
export AZURE_CLIENT_ID=<client-id>
export AZURE_CLIENT_SECRET=<client-secret>
var client = new ArmClient(new DefaultAzureCredential());
var subscription = await client.GetSubscriptionResource(
    SubscriptionResource.CreateResourceIdentifier("<subscription-id>")).GetAsync();

The same credential chain also picks up az login on your laptop and managed identity in Azure — so the code with no secrets at all is identical everywhere. See it in a full example in creating an Azure VM from C#.

Secrets, certificates, or federated credentials?

The client secret is only one of three ways an app registration can authenticate — and the weakest:

  • Client secret — a password. Simple, works everywhere, leaks like a password, expires and takes production with it if unrotated.
  • Certificate — upload a public key to Certificates & secrets; the app signs with the private key. Stronger, and required by some org policies. DefaultAzureCredential picks it up via AZURE_CLIENT_CERTIFICATE_PATH.
  • Federated credentials (OIDC) — no stored secret at all. The app registration trusts tokens from an external issuer — this is how GitHub Actions deploys to Azure without any secret in the repo:
# .github/workflows/deploy.yml
permissions:
  id-token: write
steps:
  - uses: azure/login@v2
    with:
      client-id: ${{ vars.AZURE_CLIENT_ID }}
      tenant-id: ${{ vars.AZURE_TENANT_ID }}
      subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}

Configure the trust under Certificates & secrets → Federated credentials (issuer: GitHub, subject: your repo + branch). Those three IDs are not secrets — the token exchange is the credential. For new CI/CD, start here and skip client secrets entirely.

Auditing and rotating what you have

# every credential on an app registration, with expiry dates
az ad app credential list --id <client-id> -o table

# rotate: create the new secret first, deploy it, then delete the old
az ad app credential reset --id <client-id> --append --years 1
az ad app credential delete --id <client-id> --key-id <old-key-id>

--append is the important flag — without it, reset replaces all secrets and everything using the old one breaks immediately. Store the value in Azure Key Vault or your platform's secret store; the portal will never show it again, and neither should your git history.

The errors you'll actually hit

  • AADSTS7000215 invalid client secret — the secret expired, or you pasted the secret's ID instead of its Value (everyone does this once).
  • AADSTS700016 application not found in directory — client ID and tenant ID are from different tenants.
  • AuthorizationFailed on an API call — authentication worked, but the principal has no RBAC role on the target scope; assign one as shown above.

Good hygiene

  • Prefer managed identity over client secrets when the caller runs inside Azure — no secret to rotate or leak.
  • Set secret expirations short and calendar the rotation; an expired secret is the classic "everything broke at 2am" cause.
  • One app registration per purpose, least-privilege role per registration — never share one god-principal across projects.

Comments (0)

Log in to join the conversation.

No comments yet — be the first to share your thoughts.