Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure DevOps Services
Service principals and managed identities provide secure, scalable authentication for Azure DevOps automation workflows. These Microsoft Entra identity types offer enhanced security over traditional personal access tokens (PATs). They use automatic credential management, shorter token lifespans, and enterprise-grade access controls.
Benefits of service principals and managed identities
Enhanced security
- Short-lived tokens: Microsoft Entra tokens expire every hour, which reduces exposure risk compared to PATs (which can last up to one year).
- Automatic rotation: Managed identities handle credential rotation automatically.
- No stored secrets: The need to store long-lived credentials in code or configuration is eliminated.
Operational excellence
- Centralized management: Control access through Microsoft Entra ID policies and Azure DevOps permissions.
- Audit capabilities: Track authentication and access patterns through comprehensive logging.
- Scale efficiently: Support enterprise automation scenarios without individual user dependencies.
Modern authentication
- Standards based: Uses OAuth 2.0 and OpenID Connect protocols.
- Multifactor authentication support: Inherits organizational security policies.
- Conditional access: Applies advanced security policies based on context.
Understand service principals and managed identities
Service principals
Service principals are Microsoft Entra objects that represent applications within a tenant. They define what an application can do, which resources it can access, and who can use it. Service principals are created automatically when you register an application in Microsoft Entra ID and provide a secure way for applications to authenticate and access resources.
Key characteristics
- Are created through application registration in Microsoft Entra ID.
- Support multitenant scenarios.
- Require explicit credential management (certificates or client secrets).
- Are ideal for applications that need to authenticate across different environments.
Managed identities
Managed identities are a special type of service principal that Azure manages automatically. They eliminate the need for developers to manage credentials by providing an automatically managed identity in Microsoft Entra ID for Azure resources.
Types of managed identities
System-assigned managed identity:
- Automatically created and tied to a specific Azure resource.
- Lifecycle managed by Azure (deleted when the resource is deleted).
- One-to-one relationship with the Azure resource.
- Best for applications deployed on a single Azure resource.
User-assigned managed identity:
- Created as a standalone Azure resource.
- Can be assigned to multiple Azure resources.
- Lifecycle managed independently of associated resources.
- Best for applications that run on multiple resources or need shared identity.
When to use each type:
- Service principals: Cross-cloud deployments, continuous integration and continuous delivery (CI/CD) pipelines, applications outside Azure.
- System-assigned managed identities: Single Azure resource applications (Azure Functions, Azure App Service).
- User-assigned managed identities: Multi-resource applications, shared identity scenarios.
Implementation guide
Follow these steps to implement service principals or managed identities for Azure DevOps authentication. For complete code examples, see our sample applications.
Step 1: Create your identity
Choose the appropriate identity type based on your deployment scenario.
Option A: Create a service principal (application registration)
Service principals work well for CI/CD pipelines, cross-cloud scenarios, and applications that need flexible deployment options.
Register an application in the Microsoft Entra admin center.
Go to App registrations > New registration.
Configure the application:
- Name: Use a descriptive name for your application.
- Account types: Select appropriate tenant support.
- Redirect URI: Leave blank for service-to-service scenarios.
Create authentication credentials:
- Recommended: Upload a certificate for enhanced security.
- Alternative: Create a client secret (requires regular rotation).
Important
When you register an application, Azure creates both an application object and a service principal object. Use the service principal's object ID (found on the Enterprise applications pane) when you add it to Azure DevOps, not the application's object ID.
For more information, see the following articles:
Option B: Create a managed identity
Managed identities provide the simplest authentication experience for Azure-hosted applications.
For system-assigned managed identity:
- Go to your Azure resource, such as App Service or an Azure Functions app.
- Go to Identity > System assigned.
- Switch the status to On.
- Select Save to save the configuration.
For user-assigned managed identity:
- Create the managed identity in the Azure portal.
- Go to Create a resource > Managed Identity.
- Configure basic settings and create the resource.
- Assign to resources as needed.
For more information, see the following articles:
Step 2: Add the identity to Azure DevOps
After you create your identity in Microsoft Entra ID, add it to your Azure DevOps organization to grant access to resources.
Prerequisites
- Project collection administrator role.
- Project administrator or team administrator role when the invite policy allows team admins to add users.
Add the identity
To add the identity through the Azure DevOps portal:
Go to Organization Settings > Users.
Select Add users.
Enter the display name of your service principal or managed identity.
Select the appropriate access level and project access.
Send the invitation.
Add the identity programmatically:
Use the ServicePrincipalEntitlements REST API to automate the process.
Other considerations:
- Find the correct ID: Use the service principal's object ID on the Enterprise applications pane in the Microsoft Entra admin center, not the application registration's object ID.
- Tenant restrictions: You can add identities only from the same tenant to which your Azure DevOps organization is connected. For cross-tenant scenarios, see the FAQ workaround.
Step 3: Configure permissions
Configure granular permissions for your service principal or managed identity within Azure DevOps. Unlike other Azure services, Azure DevOps uses its own permission model rather than Microsoft Entra application permissions.
Permission options:
- Direct assignment: Assign permissions directly to the identity.
- Group membership: Add to Azure DevOps or Microsoft Entra security groups.
- Access levels: Assign the appropriate license level (Basic, Basic + Test Plans, or Visual Studio subscriber).
Best practices:
- Apply least privilege: Grant only the minimum permissions needed.
- Use groups: Manage permissions through groups for easier maintenance.
- Regular reviews: Audit permissions periodically.
Permission management options:
- Azure DevOps portal: Select Organization settings > Permissions.
- REST APIs: Use Service Principal Graph APIs for programmatic management.
Important
Azure DevOps versus Microsoft Entra permissions: Azure DevOps doesn't use Microsoft Entra ID application permissions. All access control is managed through the Azure DevOps permission system, which allows for granular project and resource-level permissions.
Step 4: Get Microsoft Entra ID tokens
Get access tokens to authenticate your applications with Azure DevOps APIs and services.
For service principals
Use client credentials flow:
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={client-id}
&scope=https://app.vssps.visualstudio.com/.default
&client_secret={client-secret}
&grant_type=client_credentials
Use certificate authentication (recommended):
using Microsoft.Identity.Client;
var app = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithCertificate(certificate)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
.Build();
var result = await app
.AcquireTokenForClient(new[] { "https://app.vssps.visualstudio.com/.default" })
.ExecuteAsync();
string accessToken = result.AccessToken;
For managed identities
From Azure resources:
using Azure.Identity;
using Azure.Core;
var credential = new ManagedIdentityCredential();
var tokenRequest = new TokenRequestContext(new[] { "https://app.vssps.visualstudio.com/.default" });
var token = await credential.GetTokenAsync(tokenRequest);
string accessToken = token.Token;
Use Azure Instance Metadata Service:
GET http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://app.vssps.visualstudio.com/
Metadata: true
Azure CLI for ad hoc operations
For one-time operations or testing, use the Azure CLI:
# For service principal
az login --service-principal --username {client-id} --password {client-secret} --tenant {tenant-id}
az account get-access-token --resource https://app.vssps.visualstudio.com/
# For managed identity (from Azure resource)
az login --identity
az account get-access-token --resource https://app.vssps.visualstudio.com/
For more information, see Acquire Microsoft Entra tokens.
Step 5: Use tokens with Azure DevOps
Use your acquired tokens to authenticate REST API calls and other Azure DevOps operations.
Make authenticated API calls:
using System.Net.Http;
using System.Net.Http.Headers;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
var response = await client.GetAsync(
"https://dev.azure.com/{organization}/_apis/projects?api-version=7.1");
Video examples
Common integration scenarios
- NuGet feeds: Connect with NuGet.exe or dotnet CLI.
- Marketplace publishing: Publish extensions via command line.
- Azure Pipelines: Create service connections backed by managed identities.
- Git operations: Clone repositories with the Git Credential Manager.
For complete code examples, see our sample applications.
Management considerations
Service principals and managed identities have different management characteristics compared to user accounts.
Licensing
- Each identity requires a license in every organization it joins.
- Multi-organization billing doesn't apply to service principals.
- Group-based licensing rules don't automatically apply. You must assign licenses directly.
Identity management
- Email addresses aren't used, so there are no invitations via email.
- Display names or avatars aren't modified in Azure DevOps.
- Display names are inherited from Microsoft Entra ID.
Group membership
- Can be added to Microsoft Entra groups and Azure DevOps groups.
- Has a technical limitation that prevents display in Microsoft Entra group member lists (UI limitation only).
- Can still inherit permissions from Microsoft Entra groups to which they belong.
Materialization
- Must be explicitly added to organizations (no automatic materialization like users).
- Required because service principals can't sign in interactively.
Key differences from user accounts
Service principals and managed identities have specific limitations compared to regular users.
Capabilities
- ✅ Generate Microsoft Entra tokens for API access.
- ✅ Access Azure DevOps resources with proper permissions.
- ✅ Join security groups and teams.
- ❌ Create PATs or Secure Shell keys.
- ❌ Sign in interactively or access via a web UI.
- ❌ Create or own organizations.
- ❌ Support Azure DevOps OAuth flows.
Billing
- Counted as a separate license in each organization. (There's no multi-organization discount.)
- Must assign access level directly. (Group rules don't apply automatically.)
Frequently asked questions
Q. Why should I use a service principal or managed identity instead of a PAT?
A. Service principals and managed identities offer significant security advantages over PATs.
Security benefits:
- Shorter lifespan: Microsoft Entra tokens expire hourly compared to PATs, which can last up to a year.
- Automatic rotation: Managed identities rotate credentials automatically.
- No shared secrets: The risk of storing or accidentally exposing long-lived tokens is eliminated.
- Centralized control: Managed through Microsoft Entra ID with enterprise security policies.
Operational benefits:
- Audit trail: Logs authentication and access patterns completely.
- Conditional access: Applies policies based on location, device, and risk factors.
- No service accounts: Eliminates dependency on individual user accounts for automation.
For migration examples, see Replace PATs with Microsoft Entra tokens.
Q. What are the rate limits on service principals and managed identities?
A. Service principals and managed identities have the same rate limits as users.
Q. Will using this feature cost more?
A. Service principals and managed identities are priced like users based on access level. Key differences are:
- No multi-organization billing discount: Each identity counts as a separate license in every organization.
- License assignment: Access levels must be assigned directly. (Group rules don't apply automatically.)
- Same pricing tiers: Basic, Basic + Test Plans, and Visual Studio subscriber rates apply.
Q. Can I add a managed identity from a different tenant to my organization?
A. You can add identities directly from your organization's connected tenant only. For cross-tenant scenarios, use this workaround.
To set up a cross-tenant managed identity:
- Create a user-assigned managed identity in the resource tenant.
- Assign it to an Azure resource, such as a virtual machine or a Functions app).
- Create a key vault and generate a certificate (non-PEM format).
- Grant managed identity access to the key vault with the Get and List secret permissions.
- Download the certificate in CER format (public key only).
- Register the application in the target tenant.
- Upload the certificate to application registration.
- Add the service principal to the Azure DevOps organization.
- Configure authentication by using the certificate from the key vault.
// Example: Acquire token using managed identity certificate
public static async Task<string> GetSecret(string keyVaultName, string secretName)
{
var keyVaultUri = new Uri($"https://{keyVaultName}.vault.azure.net");
var client = new SecretClient(keyVaultUri, new ManagedIdentityCredential());
var keyVaultSecret = await client.GetSecretAsync(secretName);
return keyVaultSecret.Value.Value;
}
private static async Task<AuthenticationResult> GetAppRegistrationAADAccessToken(
string applicationClientID, string appTenantId)
{
byte[] privateKeyBytes = Convert.FromBase64String(await GetSecret(keyVaultName, secretName));
var certificate = new X509Certificate2(privateKeyBytes, (string)null, X509KeyStorageFlags.MachineKeySet);
var app = ConfidentialClientApplicationBuilder.Create(applicationClientID)
.WithCertificate(certificate)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{appTenantId}"))
.Build();
var result = await app.AcquireTokenForClient(
new[] { "499b84ac-1321-427f-aa17-267ca6975798/.default" })
.ExecuteAsync();
return result;
}
Important
Rotate certificates regularly for security best practices.
Common errors and solutions
The Git repository with name or identifier doesn't exist or you don't have permissions
Solution: Ensure that the service principal has at least a Basic license. Stakeholder licenses don't provide repository access.
Failed to create service principal with object ID
Solution: Verify that you're using the service principal's object ID from the Enterprise applications pane, not the application registration's object ID.
To find the correct ID:
- Go to Microsoft Entra admin center > Enterprise applications.
- Search for your application name.
- Use the object ID on the Enterprise applications pane.
Access denied: Needs permissions to add users
Possible causes and solutions:
- Insufficient role: Must be a project collection administrator (PCA) or a project or team administrator with invite permissions enabled.
- Policy restriction: Check if the Allow team and project administrators to invite new users policy is enabled.
- License assignment: Project admins can't assign licenses during invitation. Contact the PCA for license changes.
Azure DevOps Graphs List API returns empty list
Solution: Use continuationToken
to iterate through all pages. Service principals might appear on later pages because of API pagination behavior.
TF401444: Sign-in required error
Solution: Ensure that the service principal is added properly to the organization with required permissions. This error indicates that the identity isn't recognized in the organization.