Creating a Service Principal in Azure Portal: Step-by-Step Guide

Azure service principal
Azure Service Principal

A service principal is the identity an app, script or CI pipeline uses to sign in to Azure. You create one by registering an application in Microsoft Entra ID (the new name for Azure Active Directory), giving it a credential, and assigning it a role on the resources it needs.

This guide shows three ways to create one (the portal, the Azure CLI and PowerShell), how to grant it access, and the secret-free option you should use for GitHub Actions. If your code runs on an Azure resource like a VM or App Service, skip ahead to managed identities: you may not need a service principal at all.

Using it from the command line? See using the Azure CLI with a service principal to list storage files.


Option 1: Create a Service Principal in the Azure Portal

Step 1: Open Microsoft Entra ID

  1. Log in to the Azure Portal.
  2. Search for Microsoft Entra ID (formerly Azure Active Directory) and open it. You can also use the Entra admin center at entra.microsoft.com.
Microsoft Entra ID in the Azure portal search

Step 2: Access App Registrations

  1. Under “Manage,” click on App registrations.
App registrations under Manage

Step 3: Register a New Application

  1. Click on New registration to create a new application.
New registration button

Step 4: Fill in Application Details

  1. Enter a meaningful name for your application.
  2. Choose the appropriate account type (e.g., “Accounts in this organizational directory only”).
  3. Leave the “Redirect URI” blank for now.
  4. Click Register to create the application.
Register an application form

Step 5: Note Application (Client) ID and Directory (Tenant) ID

  1. After registration, note the Application (Client) ID and Directory (Tenant) ID from the overview page.
Application (client) ID and Directory (tenant) ID on the overview page

Step 6: Create a New Client Secret

  1. In the left-hand menu, go to Certificates & secrets.
  2. Click on New client secret.
  3. Provide a description, set an expiration, and click Add.
  4. Copy the secret Value (not the Secret ID) immediately. Azure shows it only once.
New client secret in Certificates and secrets

Step 7: Assign a role

A new service principal has no access to anything until you give it a role:

  • Open the subscription, resource group or resource it should manage.
  • Go to Access control (IAM) → Add → Add role assignment.
  • Pick a role. Use the narrowest one that works, such as Reader, Storage Blob Data Contributor or a specific service role, rather than Contributor on the whole subscription.
  • On the Members tab choose User, group, or service principal, search for your app’s name, select it, then Review + assign.

Role assignments can take a few minutes to take effect.


Option 2: Create a Service Principal with the Azure CLI

az login

az ad sp create-for-rbac \
  --name "my-app-sp" \
  --role "Reader" \
  --scopes "/subscriptions/<subscription-id>/resourceGroups/<resource-group>"

This registers the app, creates the service principal, adds a client secret and assigns the role in one step. The output looks like this:

{
  "appId": "<client-id>",
  "displayName": "my-app-sp",
  "password": "<client-secret>",
  "tenant": "<tenant-id>"
}

Store password somewhere safe right away, such as Azure Key Vault or your CI system’s secret store. You cannot retrieve it later; you can only reset it. If you leave out --role and --scopes, the service principal is created with no access at all.

Sign in as the service principal to test it:

az login --service-principal -u <client-id> -p <client-secret> --tenant <tenant-id>
az group list -o table

Option 3: Create a Service Principal with PowerShell

Connect-AzAccount

$sp = New-AzADServicePrincipal `
  -DisplayName "my-app-sp" `
  -Role "Reader" `
  -Scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>"

$sp.AppId                          # client ID
$sp.PasswordCredentials.SecretText  # client secret, shown only here
(Get-AzContext).Tenant.Id          # tenant ID

Note the parameter names: -DisplayName and -Scope (singular). Older guides use -Name and -Scopes, which the current Az module does not accept. The secret is not printed to the console; read it from PasswordCredentials.SecretText and store it immediately.


Better for GitHub Actions: No Secret at All (OIDC)

A client secret stored in GitHub is a long-lived credential that can leak and must be rotated. With workload identity federation, GitHub Actions exchanges a short-lived OIDC token for Azure access, and there is no secret to store.

1. Add a federated credential to your app registration. Save this as credential.json:

{
  "name": "github-main",
  "issuer": "https://token.actions.githubusercontent.com",
  "subject": "repo:<org>/<repo>:ref:refs/heads/main",
  "audiences": ["api://AzureADTokenExchange"]
}
az ad app federated-credential create --id <client-id> --parameters credential.json

The subject controls exactly which workflows can sign in: here, only runs on the main branch of one repository. Use repo:<org>/<repo>:environment:production to tie it to a GitHub environment instead.

2. Sign in from the workflow:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: azure/login@v3
        with:
          client-id: ${{ vars.AZURE_CLIENT_ID }}
          tenant-id: ${{ vars.AZURE_TENANT_ID }}
          subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
      - run: az group list -o table

id-token: write is required; without it the login step fails. For more on workflow permissions, see our GitHub Actions workflow YAML guide.


Service Principal vs Managed Identity

Service principalManaged identity
Where your code runsAnywhere: laptop, CI, another cloudOn an Azure resource (VM, App Service, Functions, AKS, etc.)
CredentialsSecret, certificate or federated credential you manageNone; Azure issues and rotates tokens
RotationYour jobAutomatic
Best forCI/CD, external apps, scriptsAnything already running in Azure

A managed identity is a service principal that Azure creates and manages for you. If your code runs inside Azure, prefer it: there is nothing to leak or rotate.


Security Checklist

  • Assign the narrowest role at the narrowest scope. Contributor on a whole subscription is rarely needed.
  • Prefer federated credentials (for CI) or managed identities (inside Azure) over client secrets.
  • If you must use a secret, keep the expiry short and rotate before it expires. Expired secrets are one of the most common causes of sudden pipeline failures.
  • Use a separate service principal per app or pipeline, so you can revoke one without breaking others.
  • Review role assignments periodically and delete service principals you no longer use.

Common Errors

  • AADSTS7000215: Invalid client secret provided: you used the Secret ID instead of the secret Value, or the secret expired.
  • AuthorizationFailed: sign-in worked but the role assignment is missing, is on the wrong scope, or has not propagated yet. Wait a few minutes and check IAM.
  • AADSTS700213: No matching federated identity record found: the OIDC subject does not match the branch, environment or repository the workflow ran from.
  • Insufficient privileges to complete the operation when creating one: your account lacks permission to register apps in Entra ID. Ask an admin for the Application Developer role.

Frequently Asked Questions

What is an Azure service principal?

An identity that an application, script or automation tool uses to authenticate to Azure and access resources, with permissions scoped by role assignments.

What is the difference between a service principal and a managed identity?

A managed identity is a service principal that Azure creates and rotates for you and attaches to an Azure resource, so you never handle its credentials.

How do I create a service principal with the Azure CLI?

Run az ad sp create-for-rbac with a name, role and scope. It returns the appId, password and tenant.

How long do Azure service principal secrets last?

Client secrets expire, one year by default via the CLI. Rotate them before expiry, or use a certificate credential or a managed identity instead.

Commands verified against Microsoft Learn and the azure/login README on September 25, 2026.


Related guides