# Agent Identity for AI Agents in Microsoft Foundry

It has been exactly a year since I published my last blog on Microsoft Foundry, and a lot has changed and evolved in the Foundry ecosystem over the year.

You can find those blogs [here](https://www.azureguru.net/authentication-tokens-for-azure-ai-foundry-data-agents-through-entra-service-principal-part-1) and [here](https://www.azureguru.net/authentication-tokens-for-azure-ai-foundry-data-agents-through-entra-service-principal-part-2).

The above two blogs revolved around generating access tokens to create agents in Microsoft Foundry through service principal with granted delegated permissions.

Over the last one year, the major deprecation that I see in Microsoft Foundry is the deprecation of **PersistentAgentsClient** class from the **Azure.AI.Agents** namespace.

Today I tried creating an agent through PersistentAgentsClient. The agent does get created but the created agent will be categorized as a **"Classic Agent"** in the Foundry portal.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/557eda3f-72ed-427c-93e7-0f19b242229b.png align="center")

Clicking on **Select a classic agent** navigates to the list of agents created through PersistentAgentsClient where it asks you upgrade to the new agent version.

![](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/c4a8a766-c14d-4db1-974d-b9819eec4019.png align="center")

Another aspect that surprised me the most was the naming restriction that agent names cannot contain spaces. For instance you cannot create an agent named "My First Agent".

Doing so results in the following error.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/6630362e-8a20-48a1-ae45-a7049b1fbca4.png align="center")

This wasn't case when creating agents through PersistentAgentsClient class.

Also the major role name changes where roles like Azure AI User, Azure AI Owner, Azure AI Account Owner, and Azure AI Project Manager where renamed to Foundry User, Foundry Owner, Foundry Account Owner and Foundry Project Manager.

This is a screenshot of the role names prior to the name changes.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/4a3042b4-d77b-4e61-8d42-7e05c0559b52.png align="center")

Anyways, the point of this article is not to highlight the deprecation of Microsoft Foundry features but rather to focus on how to leverage Microsoft Agent Identity within Microsoft Foundry.

Given that there is now agent identity support available, the approach I have used in my articles that was published a year ago are more or less redundant.

For this article, we’ll revisit the use case from my earlier article where I created a Microsoft Foundry agent using bearer access tokens.

I posted an [article](https://www.azureguru.net/agent-identity-for-ai-agents-in-microsoft-agent-framework) just last week on leveraging agent identities for Microsoft Agent Framework.

A quick recap on the use case from the article on Agent Identities in MAF :

The article demonstrated how to use agent identities to access Azure resources in Microsoft Agent Framework. It focused on generating Azure token credentials through **Microsoft.Identity.Web** namespace and then use agent identities RBAC granted privileges to access Azure ADLS Gen2 storage.

In this article we wont deep dive on using agent identities to access Azure resources but a simple use case where we can create a Foundry agent through agent identities.

### Inheritable Permissions

When we want to grant permissions on a resource through Microsoft Entra for a service principal we would normally grant delegated permissions to it.

But we cant do that for an agent identity. Instead what we could do is grant inheritable permissions on an agent identity blueprint to authorize a set delegate scopes.

Lets assume that an agent identity requires permissions to create and deploy agents on Microsoft Foundry. This requires delegated permission for **Azure Machine learning services**.

As mentioned earlier its not possible to assign the delegated permissions to a agent identity the way its done for a service principal.

With inheritable permissions agents automatically inherit permissions with the resulting access token's **scp** claim containing the inherited scopes and the inherited roles in the **roles** claim.

### Inheritance patterns

There are two different inheritance patterns **All Allowed** and **None.**

*   All Allowed :- It inherits all the delegated permissions and roles for a resource app.
    
*   None :- Inherits no permissions and roles
    

We will see inheritance pattern in action while configuring inheritance pattern for a resource app.

**Inheritance permission options**

Following are two options available when configuring inheritance permissions

*   allAllowedScope
    
*   allAllowedRoles
    

**AllowedScope** is the delegated permissions and acts on behalf of a signed in user and is the part of **scp** component in the access token while **AllowedRoles** is the app roles or application permissions and is the part of the **roles** component in the access token.

You can set them to **allAllowed** or **none** through the property **kind.**

> If you would like to know more about on setting up custom scopes and roles, you can refer my past article on the topic [https://www.azureguru.net/understanding-delegated-tokens-vs-application-tokens-through-claims-based-authorization-in-microsoft-entra-id](https://www.azureguru.net/understanding-delegated-tokens-vs-application-tokens-through-claims-based-authorization-in-microsoft-entra-id)

The following screenshots are from the above article.

![](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/45719d0c-1ae6-44fe-8391-cfc5e3e3a0ae.png align="center")

![](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/77a3b6ed-2238-4e08-8256-4f841c1694d9.png align="center")

**Configure Inheritance permissions**

> Unlike the Microsoft Entra UI support that's available for setting up delegated permissions for a service principal, setting up on scopes and roles has to be done through Response object. We will use PowerShell for that.

Using the PowerShell ISE will **NOT** work. We will have to use the PowerShell command line in the Administrator mode.

To get started, install **Microsoft.Graph.Authentication** module through PowerShell.

```javascript
Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
```

We then have to request permission to read and modify Agent Identity blueprints through the **AgentIdentityBlueprint.ReadWrite.All** scopes and request delegated permission to create and modify application registrations through **Application.ReadWrite.All** scoped to the current PowerShell process in Microsoft Graph.

```javascript
Connect-MgGraph -Scopes "Application.ReadWrite.All" -ContextScope Process
Connect-MgGraph -Scopes "AgentIdentityBlueprint.ReadWrite.All" -ContextScope Process
```

It will then prompt you to sign in through an interactive authentication flow. The sign in user should typically be the Entra tenant admin.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/91848a65-12f6-44a3-aef3-efa5b5089da2.png align="center")

The screen confirms that the process has been granted the Graph delegated access.

In the next step, we have to identify the Application Id of the underlying scope. The application ID can be easily figured out through the Microsoft Entra admin center.

In our case we need the Application Id for **Azure Machine Learning Services**

Select any one of the App registrations in the Microsoft Entra admin center and select API permissions and in the pop up that follows navigate to the **API's my organization uses** and search for **Azure Machine Learning Services**.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/675ad7cf-f5d4-47ff-9b9d-4fc5e63fd27f.png align="center")

Note down its Application ID.

In the next step, Get the **BluePrint** Id of the Agent Identity to be used

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/ed8a7d09-efcf-4670-842d-ebed70a45ed6.png align="center")

> I am using a blue print named "BluePrint"

In the next step , we will execute a PowerShell script that assigns the delegated permissions to the blue print for resource "Azure Machine Learning Services".

```javascript
$blueprintId = "Blue Print Id of the Agent Identity"
$uri = "https://graph.microsoft.com/v1.0/applications/microsoft.graph.agentIdentityBlueprint/$blueprintId/inheritablePermissions"

$body = @{
    resourceAppId = "Azure Machine Learning Services App ID"

    inheritableScopes = @{
        "@odata.type" = "#microsoft.graph.allAllowedScopes"
        kind = "allAllowed"
    }

    inheritableRoles = @{
        "@odata.type" = "#microsoft.graph.noRoles"
        kind = "none"
    }
} | ConvertTo-Json -Depth 10

$response = Invoke-MgGraphRequest `
    -Method POST `
    -Uri $uri `
    -Headers @{ "OData-Version" = "4.0" } `
    -ContentType "application/json" `
    -Body $body `
    -ErrorAction Stop
$response
```

In the code above, I assigned **allAllowed** for the all the scopes and **none** for the roles.

> Incase you would like to update or delete the assigned permissions you can use the PATCH and DELETE options respectively.

Examples can be found [here](https://learn.microsoft.com/en-us/entra/agent-id/configure-inheritable-permissions-blueprints#update-to-disable-roles-inheritance) and [here](https://learn.microsoft.com/en-us/entra/agent-id/configure-inheritable-permissions-blueprints#delete-existing-inheritable-permissions).

For DELETE the script will be

```javascript
$blueprintId = "Blue Print Id"
$resourceId =  "Azure Machine Learning Services App ID"

$uri = "https://graph.microsoft.com/v1.0/applications/microsoft.graph.agentIdentityBlueprint/$blueprintId/inheritablePermissions/$resourceId"
$response = Invoke-MgGraphRequest `
    -Method DELETE `
    -Uri $uri `
    -Headers @{ "OData-Version" = "4.0" } `
    -ContentType "application/json" `
    -ErrorAction Stop
$response
```

In Azure portal, assign Foundry Project Manager role to the agent identity on the underlying Foundry project under which you are planning to create the Foundry agent.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/6b93c1c8-2aeb-4aa8-9ffb-16fee1a11520.png align="center")

I am deploying the agent under the **mathproject** Foundry project.

### Code

Most of the code is similar to my earlier [article](https://www.azureguru.net/agent-identity-for-ai-agents-in-microsoft-agent-framework#code) on agent identities

Add the following packages to your project

```csharp
dotnet add package Azure.AI.Projects
dotnet add package Azure.AI.Projects.Agents
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.DependencyInjection
dotnet add package Microsoft.Identity.Abstractions
dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.TokenCacheProviders.InMemory
```

In the next step, set up **appsettings.json** to configure the agent identity and Foundry settings

```json
{
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "Your Tenant Id",
        "ClientId": "Blue Print App Id",      
        "ClientCredentials": [
            {
                "SourceType": "ClientSecret",
                "ClientSecret": "Client Secret of BluePrint"
            }
        ]
    },

"Foundry": {
    "Project": "Foundry Project",        
     "AgentIdentityId": "It is the Agent Identity Application Id"
    }
}
```

**Configuration Builder >>**

```csharp
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: false)
.Build();
```

**DI container >>**

As we are using Dependency Injection, create a DI container called services.

```csharp
ServiceCollection services = new ServiceCollection();
```

**Configure services >>**

Register the required services in the application

```csharp
services.AddSingleton<IConfiguration>(configuration);
// Core Identity Web services
services.AddTokenAcquisition();
services.AddInMemoryTokenCaches();
services.AddHttpClient();
//Support for Azure token credential in your service collection:
services.AddMicrosoftIdentityAzureTokenCredential();
// Agent Identities
services.AddAgentIdentities();
// Inject MicrosoftIdentity configuration settings
services.Configure<MicrosoftIdentityApplicationOptions>(configuration.GetSection("AzureAd"));
```

**Build DI Container >>**

```csharp
ServiceProvider serviceProvider = services.BuildServiceProvider();
```

In the next steps through **MicrosoftIdentityTokenCredential** we will set up the **TokenCredentials**.

**TokenCredentials >>**

```csharp
var tokenAcquirerFactory = serviceProvider.GetRequiredService<ITokenAcquirerFactory>();
var authSchemeProvider = serviceProvider.GetRequiredService<Microsoft.Identity.Abstractions.IAuthenticationSchemeInformationProvider>(); 
```

We have used two interfaces

*   **ITokenAcquirerFactory :** It provides access to the Microsoft Identity Web token infrastructure and generates the access token to produce `ITokenAcquirer` instances.
    
*   **IAuthenticationSchemeInformationProvider :** It provides information about the authentication scheme.
    

The instances of these two interfaces are resolved from Dependency Injection.

> *Reccall : Earlier we registered* `AzureAd` *configuration as options for* [`MicrosoftIdentityApplicationOptions`*.services*](http://MicrosoftIdentityApplicationOptions.services)*.Configure(configuration.GetSection("AzureAd"));*

Remember the following details to remove any confusion

*   **Configure < MicrosoftIdentityApplicationOptions >** binds configuration values such as `TenantId`, `ClientId`, and `Instance`.
    
*   **ITokenAcquirerFactory** is a service that provides token-acquisition infrastructure.
    
*   **IAuthenticationSchemeInformationProvider** provides details of the authentication scheme
    
*   **MicrosoftIdentityTokenCredential** uses that infrastructure to acquire access tokens.
    

```csharp
TokenCredentials = new MicrosoftIdentityTokenCredential(
    tokenAcquirerFactory,
    authSchemeProvider);
 TokenCredentials.Options.WithAgentIdentity(configuration["OpenAI:AgentIdentityId"]);
TokenCredentials.Options.RequestAppToken = true;
```

The above code creates TokenCredentials for **AgentIdentityId** configured in **appsettings.json**.

At this stage we have the TokenCredentials required to create an agent on Foundry.

**AIProjectClient >>**

We define a project client for a Foundry project along with TokenCredentials

```csharp
AIProjectClient projectClient = new(new Uri(configuration["Foundry:Project"]), TokenCredentials);
```

**ProjectsAgentDefinition >>**

Here we define a project definition to create an agent on Foundry through the AIProjectClient

```csharp
ProjectsAgentDefinition agentDefinition = new DeclarativeAgentDefinition("gpt-5-mini") 
 {
     Instructions = "You are a helpful assistant that answers general questions",
 };

 projectClient.AgentAdministrationClient.CreateAgentVersion("Newagent", options: new(agentDefinition));
```

Execute the code and you will see an agent with name **Newagent** under the Foundry project.

![Microsoft Azure AI Foundry](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/ff4acbb1-a925-4be7-8b94-0c6fc16ed38d.png align="center")

### **Drawbacks**

Using this approach requires maintaining the client secrets which is not an ideal set up for production environments as it exposes inherent security risks. I am exploring an alternative OBO flow approach for agent identities. Will shortly post an article on the topic.

### Execution

![](https://cdn.hashnode.com/uploads/covers/6693c62c166ee9c594cffda0/8bec66c7-018c-4819-9305-5e7e02b2a1f7.gif align="center")

### Conclusion

In this article, I have explored how to leverage Agent Identities to enable identity-based authentication to code first approach to deploy AI agents having some drawbacks that I highlighted earlier.

With a practical example I will demonstrated on how to configure and integrate Agent Identities for an AI agent in Microsoft Foundry, enabling it to authenticate and access protected resources securely.

Thanks for reading !!!
