Skip to content

Commit 3ecbdc2

Browse files
jmprieurjennyf19
andauthored
Adding a 3P doc for Agent Ids (#3444)
* Adding a 3P doc * Update src/Microsoft.Identity.Web.AgentIdentities/README.AgentIdentities.md Co-authored-by: jennyf19 <jeferrie@microsoft.com> * Update src/Microsoft.Identity.Web.AgentIdentities/README.AgentIdentities.md Co-authored-by: jennyf19 <jeferrie@microsoft.com> --------- Co-authored-by: jennyf19 <jeferrie@microsoft.com>
1 parent 3ac5fa7 commit 3ecbdc2

File tree

1 file changed

+292
-0
lines changed

1 file changed

+292
-0
lines changed
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# Microsoft.Identity.Web.AgentIdentities
2+
3+
## Overview
4+
5+
The Microsoft.Identity.Web.AgentIdentities NuGet package provides support for Agent Identities in Microsoft Entra ID. It enables applications to securely authenticate and acquire tokens for agent applications, agent identities, and agent user identities, which is useful for autonomous agents, interactive agents acting on behalf of their user, and agents having their own user identity.
6+
7+
This package is part of the [Microsoft.Identity.Web](https://github.com/AzureAD/microsoft-identity-web) suite of libraries and was introduced in version 3.10.0.
8+
9+
## Key Concepts
10+
11+
### Agent Applications
12+
13+
An agent application has a special application registration in Microsoft Entra ID that has permissions to act on behalf of Agent identities or Agent User identities, through Federated Identity Credentials (FIC). It's represented by its application ID (Agent Application Client ID). The agent application is configured with credentials (typically FIC+MSI or client certificates) and permissions to acquire tokens for itself to call graph. This is the app that you develop. It's a confidential client application, usually a web API. The only permissions it can have are maintain (create / delete) Agent Identities (using the Microsoft Graph)
14+
15+
### Agent Identity
16+
17+
An agent identity is a special service principal in Microsoft Entra ID. It represents an identity that the agent application created and is authorized to impersonate. It doesn't have credentials on its own. The agent application can acquire tokens on behalf of the agent identity provided the user or tenant admin consented for the agent identity to the corresponding scopes. Autonomous agents acquire app tokens on behalf of the agent identity. Interactive agents called with a user token acquire user tokens on behalf of the agent identity.
18+
19+
### Agent User Identity
20+
21+
An agent user identity is an Agent identity that can also act as a user (think of an agent identity that would have its own mailbox, or would report to you in the directory). An agent application can acquire a token on behalf of an agent user identity.
22+
23+
### Federated Identity Credentials (FIC)
24+
25+
FIC is a trust mechanism in Microsoft Entra ID that enables applications to trust each other using OpenID Connect (OIDC) tokens. In the context of agent identities, FICs are used to establish trust between the agent application and agent identities, and agent identities and agent user identities
26+
27+
## Installation
28+
29+
```bash
30+
dotnet add package Microsoft.Identity.Web.AgentIdentities
31+
```
32+
33+
## Usage
34+
35+
### 1. Configure Services
36+
37+
First, register the required services in your application:
38+
39+
```csharp
40+
// Add the core Identity Web services
41+
services.AddTokenAcquisition();
42+
services.AddInMemoryTokenCaches();
43+
services.AddHttpClient();
44+
45+
// Add Microsoft Graph integration if needed.
46+
// Requires the Microsoft.Identity.Web.GraphServiceClient package
47+
services.AddMicrosoftGraph();
48+
49+
// Add Agent Identities support
50+
services.AddAgentIdentities();
51+
```
52+
53+
### 2. Configure the Agent Application
54+
55+
Configure your application with the necessary credentials using appsettings.json:
56+
57+
```json
58+
{
59+
"AzureAd": {
60+
"Instance": "https://login.microsoftonline.com/",
61+
"TenantId": "your-tenant-id",
62+
"ClientId": "agent-application-client-id",
63+
64+
"ClientCredentials": [
65+
{
66+
"SourceType": "StoreWithDistinguishedName",
67+
"CertificateStorePath": "LocalMachine/My",
68+
"CertificateDistinguishedName": "CN=YourCertificateName"
69+
}
70+
71+
// Or for Federation Identity Credential with Managed Identity:
72+
// {
73+
// "SourceType": "SignedAssertionFromManagedIdentity",
74+
// "ManagedIdentityClientId": "managed-identity-client-id" // Omit for system-assigned
75+
// }
76+
]
77+
}
78+
}
79+
```
80+
81+
Or, if you prefer, configure programmatically:
82+
83+
```csharp
84+
// Configure the information about the agent application
85+
services.Configure<MicrosoftIdentityApplicationOptions>(
86+
options =>
87+
{
88+
options.Instance = "https://login.microsoftonline.com/";
89+
options.TenantId = "your-tenant-id";
90+
options.ClientId = "agent-application-client-id";
91+
options.ClientCredentials = [
92+
CertificateDescription.FromStoreWithDistinguishedName(
93+
"CN=YourCertificateName", StoreLocation.LocalMachine, StoreName.My)
94+
];
95+
});
96+
```
97+
98+
See https://aka.ms/ms-id-web/credential-description for all the ways to express credentials.
99+
100+
On ASP.NET Core, use the override of services.Configure taking an authentication shceme.
101+
102+
### 3. Use Agent Identities
103+
104+
#### Agent Identity
105+
106+
##### Autonomous agent
107+
108+
For your autonomous agent application to acquire **app** tokens for an agent identity:
109+
110+
```csharp
111+
// Get the required services from the DI container
112+
IAuthorizationHeaderProvider authorizationHeaderProvider =
113+
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
114+
115+
// Configure options for the agent identity
116+
string agentIdentity = "agent-identity-guid";
117+
var options = new AuthorizationHeaderProviderOptions()
118+
.WithAgentIdentity(agentIdentity);
119+
120+
// Acquire an access token for the agent identity
121+
string authHeader = await authorizationHeaderProvider
122+
.CreateAuthorizationHeaderForAppAsync("https://resource/.default", options);
123+
124+
// The authHeader contains "Bearer " + the access token (or another protocol
125+
// depending on the options)
126+
```
127+
128+
##### Interactive agent
129+
130+
For your interactive agent application to acquire **user** tokens for an agent identity on behalf of the user calling the web API:
131+
132+
```csharp
133+
// Get the required services from the DI container
134+
IAuthorizationHeaderProvider authorizationHeaderProvider =
135+
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
136+
137+
// Configure options for the agent identity
138+
string agentIdentity = "agent-identity-guid";
139+
var options = new AuthorizationHeaderProviderOptions()
140+
.WithAgentIdentity(agentIdentity);
141+
142+
// Acquire an access token for the agent identity
143+
string authHeader = await authorizationHeaderProvider
144+
.CreateAuthorizationHeaderForAppAsync(["https://resource/.default"], options);
145+
146+
// The authHeader contains "Bearer " + the access token (or another protocol
147+
// depending on the options)
148+
149+
150+
#### Agent User Identity
151+
152+
For your agent application to acquire tokens on behalf of a agent user identity:
153+
154+
```csharp
155+
// Get the required services
156+
IAuthorizationHeaderProvider authorizationHeaderProvider =
157+
serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();
158+
159+
// Configure options for the agent user identity
160+
string agentIdentity = "agent-identity-client-id";
161+
string userUpn = "user@contoso.com";
162+
var options = new AuthorizationHeaderProviderOptions()
163+
.WithAgentUserIdentity(agentIdentity, userUpn);
164+
165+
// Create a ClaimsPrincipal to enable token caching
166+
ClaimsPrincipal user = new ClaimsPrincipal();
167+
168+
// Acquire a user token
169+
string authHeader = await authorizationHeaderProvider
170+
.CreateAuthorizationHeaderForUserAsync(
171+
scopes: ["https://graph.microsoft.com/.default"],
172+
options: options,
173+
user: user);
174+
175+
// The user object now has claims including uid and utid. If you use it
176+
// in another call it will use the cached token.
177+
```
178+
179+
### 4. Microsoft Graph Integration
180+
181+
#### Using Agent Identity with Microsoft Graph:
182+
183+
```csharp
184+
// Get the GraphServiceClient
185+
GraphServiceClient graphServiceClient = serviceProvider.GetRequiredService<GraphServiceClient>();
186+
187+
// Call Microsoft Graph APIs with the agent identity
188+
var applications = await graphServiceClient.Applications
189+
.GetAsync(r => r.Options.WithAuthenticationOptions(options =>
190+
{
191+
options.WithAgentIdentity(agentIdentity);
192+
options.RequestAppToken = true;
193+
}));
194+
```
195+
196+
#### Using Agent User Identity with Microsoft Graph:
197+
198+
```csharp
199+
// Get the GraphServiceClient
200+
GraphServiceClient graphServiceClient = serviceProvider.GetRequiredService<GraphServiceClient>();
201+
202+
// Call Microsoft Graph APIs with the agent user identity
203+
var me = await graphServiceClient.Me
204+
.GetAsync(r => r.Options.WithAuthenticationOptions(options =>
205+
options.WithAgentUserIdentity(agentIdentity, userUpn)));
206+
```
207+
208+
### 5. Downstream API Integration
209+
210+
To call other APIs using the IDownstreamApi abstraction:
211+
212+
```csharp
213+
// Get the IDownstreamApi service
214+
IDownstreamApi downstreamApi = serviceProvider.GetRequiredService<IDownstreamApi>();
215+
216+
// Call API with agent identity
217+
var response = await downstreamApi.GetForAppAsync<string>(
218+
"MyApi",
219+
options => options.WithAgentIdentity(agentIdentity));
220+
221+
// Call API with agent user identity
222+
var userResponse = await downstreamApi.GetForUserAsync<string>(
223+
"MyApi",
224+
options => options.WithAgentUserIdentity(agentIdentity, userUpn));
225+
```
226+
227+
## Prerequisites
228+
229+
### Microsoft Entra ID Configuration
230+
231+
1. **Agent Application Configuration**:
232+
- Register an agent application with the graph SDK
233+
- Add client credentials for the agent application
234+
- Grant appropriate API permissions, such as Application.ReadWrite.All to create agent identities
235+
- Example configuration in JSON:
236+
```json
237+
{
238+
"AzureAd": {
239+
"Instance": "https://login.microsoftonline.com/",
240+
"TenantId": "your-tenant-id",
241+
"ClientId": "agent-application-id",
242+
"ClientCredentials": [
243+
{
244+
"SourceType": "StoreWithDistinguishedName",
245+
"CertificateStorePath": "LocalMachine/My",
246+
"CertificateDistinguishedName": "CN=YourCertName"
247+
}
248+
]
249+
}
250+
}
251+
```
252+
253+
2. **Agent Identity Configuration**:
254+
- Have the agent create an agent identity
255+
- Grant appropriate API permissions based on what your agent identity needs to do
256+
257+
3. **User Permission**:
258+
- For agent user identity scenarios, ensure appropriate user permissions are configured.
259+
260+
## How It Works
261+
262+
Under the hood, the Microsoft.Identity.Web.AgentIdentities package:
263+
264+
1. Uses Federated Identity Credentials (FIC) to establish trust between the agent application and agent identity and between the agent identity and the agent user identity.
265+
2. Acquires FIC tokens using the `GetFicTokenAsync` method
266+
3. Uses the FIC tokens to authenticate as the agent identity
267+
4. For agent user identities, it leverages MSAL extensions to perform user token acquisition
268+
269+
## Troubleshooting
270+
271+
### Common Issues
272+
273+
1. **Missing FIC Configuration**: Ensure Federated Identity Credentials are properly configured in Microsoft Entra ID between the agent application and agent identity.
274+
275+
2. **Permission Issues**: Verify the agent application has sufficient permissions to manage agent identities and that the agent identities have enough permissions to call the downstream APIs.
276+
277+
3. **Certificate Problems**: If you use a client certificate, make sure the certificate is registered in the app registration, and properly installed and accessible by the code of the agent application.
278+
279+
4. **Token Acquisition Failures**: Enable logging to diagnose token acquisition failures:
280+
```csharp
281+
services.AddLogging(builder => {
282+
builder.AddConsole();
283+
builder.SetMinimumLevel(LogLevel.Debug);
284+
});
285+
```
286+
287+
## Resources
288+
289+
- [Microsoft Entra ID documentation](https://docs.microsoft.com/en-us/azure/active-directory/)
290+
- [Microsoft Identity Web documentation](https://github.com/AzureAD/microsoft-identity-web/wiki)
291+
- [Workload Identity Federation](https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation)
292+
- [Microsoft Graph SDK documentation](https://docs.microsoft.com/en-us/graph/sdks/sdks-overview)

0 commit comments

Comments
 (0)