Manage a Microsoft Entra application using Microsoft Graph
Article
Your app must be registered in Microsoft Entra ID before the Microsoft identity platform can authorize it to access data stored in the Microsoft cloud. This condition applies to apps that you develop yourself, that your tenant owns, or that you access through an active subscription.
Many settings for apps are recorded as objects that can be accessed, updated, or deleted using Microsoft Graph. In this article, you learn how to use Microsoft Graph to manage details of app and service principal objects including the properties, permissions, and role assignments.
Prerequisites
To test the API operations, you need the following resources and privileges:
A working Microsoft Entra tenant.
Sign in to Graph Explorer as a user with privileges allowed to create and manage applications in the tenant.
Grant yourself the least privilege delegated permission indicated for the operation.
Register an application with Microsoft Entra ID
The following request creates an app by specifying only the required displayName property. Other properties are assigned the default values.
Least privileged delegated permission: Application.ReadWrite.All.
POST https://graph.microsoft.com/v1.0/applications
Content-type: application/json
{
"displayName": "My application"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
DisplayName = "My application",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewApplication()
displayName := "My application"
requestBody.SetDisplayName(&displayName)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
applications, err := graphClient.Applications().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
application.setDisplayName("My application");
Application result = graphClient.applications().post(application);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\Application;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Application();
$requestBody->setDisplayName('My application');
$result = $graphServiceClient->applications()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
display_name = "My application",
)
result = await graph_client.applications.post(request_body)
The request returns a 201 Created response with the application object in the response body. The application is assigned an id that's unique for apps in the tenant, and an appId that's globally unique in the Microsoft Entra ID ecosystem.
Create a service principal for an application
Least privileged delegated permission: Application.ReadWrite.All.
POST https://graph.microsoft.com/v1.0/servicePrincipals
Content-type: application/json
{
"appId": "fc876dd1-6bcb-4304-b9b6-18ddf1526b62"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new ServicePrincipal
{
AppId = "fc876dd1-6bcb-4304-b9b6-18ddf1526b62",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.ServicePrincipals.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewServicePrincipal()
appId := "fc876dd1-6bcb-4304-b9b6-18ddf1526b62"
requestBody.SetAppId(&appId)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
servicePrincipals, err := graphClient.ServicePrincipals().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
ServicePrincipal servicePrincipal = new ServicePrincipal();
servicePrincipal.setAppId("fc876dd1-6bcb-4304-b9b6-18ddf1526b62");
ServicePrincipal result = graphClient.servicePrincipals().post(servicePrincipal);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\ServicePrincipal;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ServicePrincipal();
$requestBody->setAppId('fc876dd1-6bcb-4304-b9b6-18ddf1526b62');
$result = $graphServiceClient->servicePrincipals()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.service_principal import ServicePrincipal
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = ServicePrincipal(
app_id = "fc876dd1-6bcb-4304-b9b6-18ddf1526b62",
)
result = await graph_client.service_principals.post(request_body)
The request returns a 201 Created response with the service principal object in the response body.
Addressing an application or a service principal object
You can address an application or a service principal by its ID or by its appId, where ID is referred to as Object ID and appId is referred to as Application (client) ID on the Microsoft Entra admin center. These syntaxes are supported for all HTTP CRUD operations on applications and service principals.
To address an application or a service principal by its ID.
In addition, you can address an application object unique its uniqueName. You can use this property to create an application with the unique name if it doesn't exist, or update it if it exists; an operation referred to as "Upsert".
Create an application with the specified uniqueName if it doesn't exist, otherwise, update it.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
Tags = new List<string>
{
"HR",
"Payroll",
"HideApp",
},
Info = new InformationalUrl
{
LogoUrl = "https://cdn.pixabay.com/photo/2016/03/21/23/25/link-1271843_1280.png",
MarketingUrl = "https://www.contoso.com/app/marketing",
PrivacyStatementUrl = "https://www.contoso.com/app/privacy",
SupportUrl = "https://www.contoso.com/app/support",
TermsOfServiceUrl = "https://www.contoso.com/app/termsofservice",
},
Web = new WebApplication
{
HomePageUrl = "https://www.contoso.com/",
LogoutUrl = "https://www.contoso.com/frontchannel_logout",
RedirectUris = new List<string>
{
"https://localhost",
},
},
ServiceManagementReference = "Owners aliases: Finance @ contosofinance@contoso.com; The Phone Company HR consulting @ hronsite@thephone-company.com;",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
LinkedList<String> tags = new LinkedList<String>();
tags.add("HR");
tags.add("Payroll");
tags.add("HideApp");
application.setTags(tags);
InformationalUrl info = new InformationalUrl();
info.setLogoUrl("https://cdn.pixabay.com/photo/2016/03/21/23/25/link-1271843_1280.png");
info.setMarketingUrl("https://www.contoso.com/app/marketing");
info.setPrivacyStatementUrl("https://www.contoso.com/app/privacy");
info.setSupportUrl("https://www.contoso.com/app/support");
info.setTermsOfServiceUrl("https://www.contoso.com/app/termsofservice");
application.setInfo(info);
WebApplication web = new WebApplication();
web.setHomePageUrl("https://www.contoso.com/");
web.setLogoutUrl("https://www.contoso.com/frontchannel_logout");
LinkedList<String> redirectUris = new LinkedList<String>();
redirectUris.add("https://localhost");
web.setRedirectUris(redirectUris);
application.setWeb(web);
application.setServiceManagementReference("Owners aliases: Finance @ contosofinance@contoso.com; The Phone Company HR consulting @ hronsite@thephone-company.com;");
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
from msgraph.generated.models.informational_url import InformationalUrl
from msgraph.generated.models.web_application import WebApplication
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
tags = [
"HR",
"Payroll",
"HideApp",
],
info = InformationalUrl(
logo_url = "https://cdn.pixabay.com/photo/2016/03/21/23/25/link-1271843_1280.png",
marketing_url = "https://www.contoso.com/app/marketing",
privacy_statement_url = "https://www.contoso.com/app/privacy",
support_url = "https://www.contoso.com/app/support",
terms_of_service_url = "https://www.contoso.com/app/termsofservice",
),
web = WebApplication(
home_page_url = "https://www.contoso.com/",
logout_url = "https://www.contoso.com/frontchannel_logout",
redirect_uris = [
"https://localhost",
],
),
service_management_reference = "Owners aliases: Finance @ contosofinance@contoso.com; The Phone Company HR consulting @ hronsite@thephone-company.com;",
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new ServicePrincipal
{
AppRoleAssignmentRequired = true,
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.ServicePrincipals["{servicePrincipal-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewServicePrincipal()
appRoleAssignmentRequired := true
requestBody.SetAppRoleAssignmentRequired(&appRoleAssignmentRequired)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
servicePrincipals, err := graphClient.ServicePrincipals().ByServicePrincipalId("servicePrincipal-id").Patch(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
ServicePrincipal servicePrincipal = new ServicePrincipal();
servicePrincipal.setAppRoleAssignmentRequired(true);
ServicePrincipal result = graphClient.servicePrincipals().byServicePrincipalId("{servicePrincipal-id}").patch(servicePrincipal);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\ServicePrincipal;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ServicePrincipal();
$requestBody->setAppRoleAssignmentRequired(true);
$result = $graphServiceClient->servicePrincipals()->byServicePrincipalId('servicePrincipal-id')->patch($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.service_principal import ServicePrincipal
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = ServicePrincipal(
app_role_assignment_required = True,
)
result = await graph_client.service_principals.by_service_principal_id('servicePrincipal-id').patch(request_body)
While you can assign permissions to an app through the Microsoft Entra admin center, you also assign permissions through Microsoft Graph by updating the requiredResourceAccess property of the app object. You must pass in both existing and new permissions. Passing in only new permissions overwrites and removes the existing permissions that haven't yet been consented to.
Assigning permissions doesn't automatically grant them to the app. You must still grant admin consent using the Microsoft Entra admin center. To grant permissions without interactive consent, see Grant or revoke API permissions programmatically.
Least privileged delegated permission: Application.ReadWrite.All.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
RequiredResourceAccess = new List<RequiredResourceAccess>
{
new RequiredResourceAccess
{
ResourceAppId = "00000002-0000-0000-c000-000000000000",
ResourceAccess = new List<ResourceAccess>
{
new ResourceAccess
{
Id = Guid.Parse("311a71cc-e848-46a1-bdf8-97ff7156d8e6"),
Type = "Scope",
},
new ResourceAccess
{
Id = Guid.Parse("3afa6a7d-9b1a-42eb-948e-1650a849e176"),
Type = "Role",
},
},
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
LinkedList<RequiredResourceAccess> requiredResourceAccess = new LinkedList<RequiredResourceAccess>();
RequiredResourceAccess requiredResourceAccess1 = new RequiredResourceAccess();
requiredResourceAccess1.setResourceAppId("00000002-0000-0000-c000-000000000000");
LinkedList<ResourceAccess> resourceAccess = new LinkedList<ResourceAccess>();
ResourceAccess resourceAccess1 = new ResourceAccess();
resourceAccess1.setId(UUID.fromString("311a71cc-e848-46a1-bdf8-97ff7156d8e6"));
resourceAccess1.setType("Scope");
resourceAccess.add(resourceAccess1);
ResourceAccess resourceAccess2 = new ResourceAccess();
resourceAccess2.setId(UUID.fromString("3afa6a7d-9b1a-42eb-948e-1650a849e176"));
resourceAccess2.setType("Role");
resourceAccess.add(resourceAccess2);
requiredResourceAccess1.setResourceAccess(resourceAccess);
requiredResourceAccess.add(requiredResourceAccess1);
application.setRequiredResourceAccess(requiredResourceAccess);
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
from msgraph.generated.models.required_resource_access import RequiredResourceAccess
from msgraph.generated.models.resource_access import ResourceAccess
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
required_resource_access = [
RequiredResourceAccess(
resource_app_id = "00000002-0000-0000-c000-000000000000",
resource_access = [
ResourceAccess(
id = UUID("311a71cc-e848-46a1-bdf8-97ff7156d8e6"),
type = "Scope",
),
ResourceAccess(
id = UUID("3afa6a7d-9b1a-42eb-948e-1650a849e176"),
type = "Role",
),
],
),
],
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Application
{
AppRoles = new List<AppRole>
{
new AppRole
{
AllowedMemberTypes = new List<string>
{
"User",
"Application",
},
Description = "Survey.Read",
DisplayName = "Survey.Read",
Id = Guid.Parse("7a9ddfc4-cc8a-48ea-8275-8ecbffffd5a0"),
IsEnabled = false,
Origin = "Application",
Value = "Survey.Read",
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
LinkedList<AppRole> appRoles = new LinkedList<AppRole>();
AppRole appRole = new AppRole();
LinkedList<String> allowedMemberTypes = new LinkedList<String>();
allowedMemberTypes.add("User");
allowedMemberTypes.add("Application");
appRole.setAllowedMemberTypes(allowedMemberTypes);
appRole.setDescription("Survey.Read");
appRole.setDisplayName("Survey.Read");
appRole.setId(UUID.fromString("7a9ddfc4-cc8a-48ea-8275-8ecbffffd5a0"));
appRole.setIsEnabled(false);
appRole.setOrigin("Application");
appRole.setValue("Survey.Read");
appRoles.add(appRole);
application.setAppRoles(appRoles);
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.application import Application
from msgraph.generated.models.app_role import AppRole
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
app_roles = [
AppRole(
allowed_member_types = [
"User",
"Application",
],
description = "Survey.Read",
display_name = "Survey.Read",
id = UUID("7a9ddfc4-cc8a-48ea-8275-8ecbffffd5a0"),
is_enabled = False,
origin = "Application",
value = "Survey.Read",
),
],
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
Identify ownerless service principals and service principals with one owner
Least privileged delegated permission: Application.ReadWrite.All.
This request requires the ConsistencyLevel header set to eventual because $count is in the request. For more information about the use of ConsistencyLevel and $count, see Advanced query capabilities on directory objects.
This request also returns the count of the apps that match the filter condition.
GET https://graph.microsoft.com/v1.0/servicePrincipals?$filter=owners/$count eq 0 or owners/$count eq 1&$count=true
ConsistencyLevel: eventual
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.ServicePrincipals.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Filter = "owners/$count eq 0 or owners/$count eq 1";
requestConfiguration.QueryParameters.Count = true;
requestConfiguration.Headers.Add("ConsistencyLevel", "eventual");
});
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
ServicePrincipalCollectionResponse result = graphClient.servicePrincipals().get(requestConfiguration -> {
requestConfiguration.queryParameters.filter = "owners/$count eq 0 or owners/$count eq 1";
requestConfiguration.queryParameters.count = true;
requestConfiguration.headers.add("ConsistencyLevel", "eventual");
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.service_principals.service_principals_request_builder import ServicePrincipalsRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = ServicePrincipalsRequestBuilder.ServicePrincipalsRequestBuilderGetQueryParameters(
filter = "owners/$count eq 0 or owners/$count eq 1",
count = True,
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
request_configuration.headers.add("ConsistencyLevel", "eventual")
result = await graph_client.service_principals.get(request_configuration = request_configuration)
POST https://graph.microsoft.com/v1.0/applications/7b45cf6d-9083-4eb2-92c4-a7e090f1fc40/owners/$ref
Content-Type: application/json
{
"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new ReferenceCreate
{
OdataId = "https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Applications["{application-id}"].Owners.Ref.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewReferenceCreate()
odataId := "https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26"
requestBody.SetOdataId(&odataId)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
graphClient.Applications().ByApplicationId("application-id").Owners().Ref().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.models.ReferenceCreate referenceCreate = new com.microsoft.graph.models.ReferenceCreate();
referenceCreate.setOdataId("https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26");
graphClient.applications().byApplicationId("{application-id}").owners().ref().post(referenceCreate);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\ReferenceCreate;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ReferenceCreate();
$requestBody->setOdataId('https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26');
$graphServiceClient->applications()->byApplicationId('application-id')->owners()->ref()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.reference_create import ReferenceCreate
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = ReferenceCreate(
odata_id = "https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26",
)
await graph_client.applications.by_application_id('application-id').owners.ref.post(request_body)
Least privileged delegated permission: Application.ReadWrite.All.
The following request references the service principal using its appId. You can alternatively reference it using the object ID in the pattern ../servicePrincipals/{bject ID}/owners/$ref. 8afc02cb-4d62-4dba-b536-9f6d73e9be26 is the object ID for a user or service principal.
POST https://graph.microsoft.com/v1.0/servicePrincipals(appId='46e6adf4-a9cf-4b60-9390-0ba6fb00bf6b')/owners/$ref
Content-Type: application/json
{
"@odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/8afc02cb-4d62-4dba-b536-9f6d73e9be26"
}
Lock sensitive properties for service principals
The app instance lock feature allows you to protect sensitive properties of your multitenant apps from unauthorized tampering. The following properties of the service principal object can be locked:
keyCredentials where the usage type is Sign or Verify.
passwordCredentials where the usage type is Sign or Verify.
tokenEncryptionKeyId property.
You manage the app instance lock feature through the servicePrincipalLockConfiguration property of the application object of the multitenant app.
To lock all sensitive properties of a service principal
When isEnabled and allProperties is set to true, even if other properties of the servicePrincipalLockConfiguration object are null, then all sensitive properties of the service principal are locked.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Beta.Models;
var requestBody = new Application
{
ServicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration
{
IsEnabled = true,
AllProperties = true,
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v0.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-beta-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-beta-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewApplication()
servicePrincipalLockConfiguration := graphmodels.NewServicePrincipalLockConfiguration()
isEnabled := true
servicePrincipalLockConfiguration.SetIsEnabled(&isEnabled)
allProperties := true
servicePrincipalLockConfiguration.SetAllProperties(&allProperties)
requestBody.SetServicePrincipalLockConfiguration(servicePrincipalLockConfiguration)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
applications, err := graphClient.Applications().ByApplicationId("application-id").Patch(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
ServicePrincipalLockConfiguration servicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration();
servicePrincipalLockConfiguration.setIsEnabled(true);
servicePrincipalLockConfiguration.setAllProperties(true);
application.setServicePrincipalLockConfiguration(servicePrincipalLockConfiguration);
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
<?php
use Microsoft\Graph\Beta\GraphServiceClient;
use Microsoft\Graph\Beta\Generated\Models\Application;
use Microsoft\Graph\Beta\Generated\Models\ServicePrincipalLockConfiguration;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Application();
$servicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration();
$servicePrincipalLockConfiguration->setIsEnabled(true);
$servicePrincipalLockConfiguration->setAllProperties(true);
$requestBody->setServicePrincipalLockConfiguration($servicePrincipalLockConfiguration);
$result = $graphServiceClient->applications()->byApplicationId('application-id')->patch($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph_beta import GraphServiceClient
from msgraph_beta.generated.models.application import Application
from msgraph_beta.generated.models.service_principal_lock_configuration import ServicePrincipalLockConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
service_principal_lock_configuration = ServicePrincipalLockConfiguration(
is_enabled = True,
all_properties = True,
),
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Beta.Models;
var requestBody = new Application
{
ServicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration
{
IsEnabled = true,
CredentialsWithUsageSign = true,
CredentialsWithUsageVerify = true,
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Applications["{application-id}"].PatchAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v0.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-beta-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-beta-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewApplication()
servicePrincipalLockConfiguration := graphmodels.NewServicePrincipalLockConfiguration()
isEnabled := true
servicePrincipalLockConfiguration.SetIsEnabled(&isEnabled)
credentialsWithUsageSign := true
servicePrincipalLockConfiguration.SetCredentialsWithUsageSign(&credentialsWithUsageSign)
credentialsWithUsageVerify := true
servicePrincipalLockConfiguration.SetCredentialsWithUsageVerify(&credentialsWithUsageVerify)
requestBody.SetServicePrincipalLockConfiguration(servicePrincipalLockConfiguration)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
applications, err := graphClient.Applications().ByApplicationId("application-id").Patch(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Application application = new Application();
ServicePrincipalLockConfiguration servicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration();
servicePrincipalLockConfiguration.setIsEnabled(true);
servicePrincipalLockConfiguration.setCredentialsWithUsageSign(true);
servicePrincipalLockConfiguration.setCredentialsWithUsageVerify(true);
application.setServicePrincipalLockConfiguration(servicePrincipalLockConfiguration);
Application result = graphClient.applications().byApplicationId("{application-id}").patch(application);
<?php
use Microsoft\Graph\Beta\GraphServiceClient;
use Microsoft\Graph\Beta\Generated\Models\Application;
use Microsoft\Graph\Beta\Generated\Models\ServicePrincipalLockConfiguration;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Application();
$servicePrincipalLockConfiguration = new ServicePrincipalLockConfiguration();
$servicePrincipalLockConfiguration->setIsEnabled(true);
$servicePrincipalLockConfiguration->setCredentialsWithUsageSign(true);
$servicePrincipalLockConfiguration->setCredentialsWithUsageVerify(true);
$requestBody->setServicePrincipalLockConfiguration($servicePrincipalLockConfiguration);
$result = $graphServiceClient->applications()->byApplicationId('application-id')->patch($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph_beta import GraphServiceClient
from msgraph_beta.generated.models.application import Application
from msgraph_beta.generated.models.service_principal_lock_configuration import ServicePrincipalLockConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Application(
service_principal_lock_configuration = ServicePrincipalLockConfiguration(
is_enabled = True,
credentials_with_usage_sign = True,
credentials_with_usage_verify = True,
),
)
result = await graph_client.applications.by_application_id('application-id').patch(request_body)
Configure trusted certificate authorities for apps
You can restrict certificate credential usage for apps in your tenant to only the certificates issued by trusted certificate authorities. This policy is enforced when you add a certificate to an app and doesn't affect existing certificates unless they are rotated. When an app tries to rotate its certificate credentials, it goes through the policy evaluation to ensure the credentials being added comply with the trusted certificate authority restriction.
Step 1: Create a certificate chain of trust
Least privileged delegated permission: AppCertTrustConfiguration.Read.All
Least privileged Microsoft Entra role: Application Administrator
POST https://graph.microsoft.com/beta/certificateAuthorities/certificateBasedApplicationConfigurations
{
"displayName": "Trusted Certificate Chain of Trust for Contoso",
"description": "The Trusted Certificate Chain of Trust containing a certificate chain used by app policy, to only allow application certificates from selected issuer.",
"trustedCertificateAuthorities": [
{
"isRootAuthority": true,
"certificate": "MIIFVjCCAz6gAwIBAgIQJdrL...UyNDIyNTcwM1owPDE …="
},
{
"isRootAuthority": false,
"certificate": QAAAAAAWjABAQsFADA8M...UyNDIyNTcwM1o …="
}
]
}
The request returns a 200 OK response object. The response includes the ID of the certificate chain of trust object. Assume that the ID is eec5ba11-2fc0-4113-83a2-ed986ed13743.
Step 2: Assign the certificate chain of trust to an application management policy
The following sample sets up a policy to ensure that only certificates issued by the intermediate certificate authority defined in the previous step can be added to apps in the tenant. The applicationRestrictions > keyCredentials object defines a restrictionType with the value trustedCertificateAuthority, which references the ID that was created. Because this policy is applied to the default tenant-level app management policy, it's enforced for all apps created in the tenant and rejects attempts to add noncompliant certificates as part of an app's certificate credentials.
This policy ensures that only certificates from the specified intermediate certificate authority can be added to apps. The applicationRestrictions > keyCredentials object sets a restrictionType to trustedCertificateAuthority, referencing the created ID. This policy applies to all apps in the tenant, rejecting any noncompliant certificates.
Least privileged delegated permission: Policy.Read.ApplicationConfiguration
Least privileged Microsoft Entra role: Security Administrator
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new TenantAppManagementPolicy
{
Id = "d015220e-9789-4e8e-bbcc-270fe419229d",
Description = "Lorem ipsum",
DisplayName = "Credential management policy",
IsEnabled = true,
ApplicationRestrictions = new AppManagementApplicationConfiguration
{
PasswordCredentials = new List<PasswordCredentialConfiguration>
{
new PasswordCredentialConfiguration
{
RestrictionType = AppCredentialRestrictionType.PasswordLifetime,
MaxLifetime = TimeSpan.Parse("P14D"),
RestrictForAppsCreatedAfterDateTime = DateTimeOffset.Parse("2020-01-01T07:00:00Z"),
},
},
KeyCredentials = new List<KeyCredentialConfiguration>
{
new KeyCredentialConfiguration
{
RestrictionType = AppKeyCredentialRestrictionType.AsymmetricKeyLifetime,
RestrictForAppsCreatedAfterDateTime = DateTimeOffset.Parse("2020-01-01T10:37:00Z"),
MaxLifetime = TimeSpan.Parse("P90D"),
},
new KeyCredentialConfiguration
{
RestrictionType = AppKeyCredentialRestrictionType.AsymmetricKeyLifetime,
RestrictForAppsCreatedAfterDateTime = DateTimeOffset.Parse("2019-10-19T10:37:00Z"),
AdditionalData = new Dictionary<string, object>
{
{
"certificateBasedApplicationConfigurationIds" , new List<string>
{
"eec5ba11-2fc0-4113-83a2-ed986ed13743",
}
},
},
},
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Policies.DefaultAppManagementPolicy.PatchAsync(requestBody);