Context
I'm implementing a service to rotate the secrets of the service principals. The authenticated user must be a Service Principal and it can only update the secrets from specifics service principals of my organization.
Ex.:
- Service Principal: aadapp-manage -> this is the authenticated service principal
- Service Principal: aadapp-user-01 -> this is a specifc SP that aadapp-manage can manage its secrets
- Service Principal: aadapp-user-02 -> this is a specifc SP that aadapp-manage can manage its secrets
- Service Principal: aadapp-user-03 -> this SP CANNOT be have its secrets modified by the aadapp-manage SP.
What I did
- Created an AD Role named
Got-ManagedSecrets-Roleand assign the microsoft.directory/servicePrincipals/synchronizationCredentials/manage permission. Then, within the PIM, I assigned - Created an AD Group named
aadgrp-managed-secretsand added the SPsaadapp-user-01andaadapp-user-02. - Underneath PIM, created an assignment with the following entries:
- Role: Got-ManagedSecrets-Role
- Scope: Group
- Selected Scope: aadapp-manage
- Selected Application: aadgrp-managed-secrets
I granted Delegated / Application.ReadWrite.All, one of the required permission described in the MS Docs, but this is not useful when I want to restrict the SP that my authenticated user can do.
Source: https://learn.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http
Test Cases
HTTP Request 01
Validate if aadapp-managed-secrets SP can generate a secret for aadapp-user-01. Expeccted result: YES
POST /v1.0/applications(appId='[USER-01-ID]')/addPassword HTTP/1.1
Host: graph.microsoft.com
Content-Type: application/json
Authorization: Bearer [TOKEN]
Content-Length: 96
{
"passwordCredential": {
"displayName": "New Secret"
}
}
Response
Status: OK (new secret generated)
HTTP Request 02
Validate if aadapp-managed-secrets SP can generate a secret for aadapp-user-02. Expeccted result: YES
POST /v1.0/applications(appId='[USER-02-ID]')/addPassword HTTP/1.1
Host: graph.microsoft.com
Content-Type: application/json
Authorization: Bearer [TOKEN]
Content-Length: 96
{
"passwordCredential": {
"displayName": "New Secret"
}
}
Response
Status: OK (new secret generated)
HTTP Request 03
Validate if aadapp-managed-secrets SP CANNOT generate a secret for aadapp-user-03. Expeccted result: NO
POST /v1.0/applications(appId='[USER-03-ID]')/addPassword HTTP/1.1
Host: graph.microsoft.com
Content-Type: application/json
Authorization: Bearer [TOKEN]
Content-Length: 96
{
"passwordCredential": {
"displayName": "New Secret"
}
}
Response
Status: OK (new secret generated). At this point, my test failed.
Problem
Given that (at least what I thought) I setup the Role and the assignment, it seems that the Graph API step through those securities concerns.
Any thoughts?

I created four Azure AD Applications like below:
And created a group
aadgrp-managed-secretsand added Service Principals as members:Now, created a custom role and assigned to the group as scope and
aadgrp-managed-secretsas member:I generated access token for
aadapp-managelike below:When I tried to create secret for
aadapp-user-03, it got created, but it shouldn't be the case:Note that: As you granted Admin consent to the API permission
Application.ReadWrite.Allof the Applicationaadapp-manage, it is not possible to restrict the application to stop creating the secrets foraadapp-user-03. The Application can create secrets for all the applications in the tenant. The Graph API permission is allowing the Application to create secrets through those security concerns.Reference:
Custom role permissions for app registration - Microsoft Entra