Microsoft Entra PIM backend
Routes approvals through Microsoft Entra Privileged Identity Management. Approvers use the native Entra PIM portal they already know — the same UX that gates Global Administrator activation. AI.Sentinel translates a tool-call approval request into a PIM role-activation request, polls for the outcome, and resumes the conversation.
Ships in AI.Sentinel.Approvals.EntraPim and is bundled into all three CLIs.
When to use it
- Enterprise tenants with Entra ID P2 and PIM already in production.
- You want the audit trail in Azure AD, not in your app database.
- Approvers are already in Entra groups/roles — no separate user list to maintain.
Required Graph permissions
Admin-consent these on your app registration:
RoleManagement.Read.DirectoryRoleManagement.ReadWrite.Directory
# Replace <APP-OBJECT-ID> with your service principal's object ID
az ad app permission admin-consent --id <APP-OBJECT-ID>
Wiring
using AI.Sentinel.Approvals.EntraPim;
services.AddSentinelEntraPimApprovalStore(opts =>
{
opts.TenantId = "00000000-1111-2222-3333-444444444444";
// Optional: defaults to system-assigned managed identity → workload identity
// → environment vars → Azure CLI. Override by registering a TokenCredential
// in DI before this call.
});
services.AddAISentinel(opts =>
{
opts.RequireApproval("delete_database", spec =>
{
spec.GrantDuration = TimeSpan.FromMinutes(15);
spec.BackendBinding = "Database Administrator"; // PIM role name
});
});
spec.BackendBinding is the PIM role name (or role-template GUID) the approval activates. Approvers configured on that role in PIM get the request.
CLI config
{
"backend": "entra-pim",
"tenantId": "00000000-1111-2222-3333-444444444444",
"defaultGrantMinutes": 15,
"tools": {
"delete_database": { "role": "Database Administrator" }
}
}
Authentication chain
By default AddSentinelEntraPimApprovalStore builds a ChainedTokenCredential:
- System-assigned managed identity (best for Azure-hosted apps)
- Workload identity federation (AKS / Azure DevOps OIDC)
- Environment variables (
AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET) - Azure CLI (
az login— dev-only fallback)
To override (e.g. inject a test credential), register a TokenCredential in DI before calling AddSentinelEntraPimApprovalStore.
Polling and rate limits
- The store polls Graph for the request status with backoff + jitter (
PollIntervaldefault1s,PollMaxBackoffdefault30s, ±20% jitter). Tune both viaEntraPimOptionsif Graph rate limits become a concern at scale. - Honors
Retry-Afteron 429/503/504 responses. - Reflective
ODataErroraccessors keep the runtime decoupled from Graph SDK internals (AOT-safe — see trim suppressions).
Approver UX
Approvers go to the Entra PIM portal → My approvals. The AI.Sentinel dashboard panel for an Entra-PIM-backed store shows pending requests as "actionable elsewhere" (the IApprovalAdmin interface is intentionally not implemented — approval state lives in Azure, not in your app).
Caller identity
The caller's ISecurityContext.Id must be a GUID matching an Entra user's objectId. Non-GUID callers are rejected at request time (ApprovalState.Denied with reason). The agent runtime is responsible for setting ISecurityContext.Id to the upstream user's Entra object ID — typically pulled from the JWT oid claim.