Passport
Creating a Managed Identity
Create managed identities via the Passport Admin API or the Passport Admin UI — name your identity after its purpose, assign it to the correct tenant, and follow naming conventions that make audit logs readable.
CreateManagedIdentityRequest
public class CreateManagedIdentityRequest
{
public required string Name { get; init; } // human-readable name (appears in audit logs)
public string? Description { get; init; } // purpose of this identity
public required string TenantId { get; init; } // must match a valid tenant
public string[]? InitialRoles { get; init; } // role names to assign immediately
public string[]? Tags { get; init; } // for filtering/organization
}
Creating via API
POST /passport/admin/managed-identities
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"name": "payroll-scheduler",
"description": "Runs the monthly payroll workflow on the 25th of each month",
"tenantId": "tenant-abc",
"initialRoles":["payroll-executor"],
"tags": ["automation", "payroll", "scheduler"]
}
// Response — SECRET SHOWN ONLY ONCE
{
"managedIdentityId": "mi-guid-1234",
"clientId": "mi-payroll-scheduler-clientid",
"clientSecret": "mics_sk_xxxxxxxxxxxxxxxxxxxxxxxx", // STORE SECURELY
"name": "payroll-scheduler",
"tenantId": "tenant-abc",
"createdAt": "2026-05-25T10:00:00Z"
}
Store the Client Secret Immediately
The clientSecret is shown only once in the creation response. It is stored as a one-way hash in Passport — it cannot be retrieved again. Store it immediately in a secrets manager (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault). If lost, generate a new secret using the credential rotation process.
Naming Conventions
Managed identity names appear directly in audit logs. A well-chosen name makes security investigations straightforward. Follow this convention:
// Good naming — describes function, not the team
"payroll-monthly-scheduler"
"hr-onboarding-integration"
"erp-data-sync-agent"
"slack-notification-sender"
"backup-export-job"
// Poor naming — vague, no context
"service1"
"automation"
"test-mi"
"john-smith-service" // DO NOT use person names
Listing Managed Identities
GET /passport/admin/managed-identities?tenantId=tenant-abc
Authorization: Bearer {admin-token}
// Response
{
"managedIdentities": [
{
"managedIdentityId": "mi-guid-1234",
"clientId": "mi-payroll-scheduler-clientid",
"name": "payroll-monthly-scheduler",
"description": "Runs the monthly payroll workflow on the 25th",
"tenantId": "tenant-abc",
"isEnabled": true,
"createdAt": "2026-05-25T10:00:00Z",
"lastUsedAt": "2026-05-25T10:05:00Z",
"roles": ["payroll-executor"],
"tags": ["automation", "payroll"]
}
],
"total": 1
}
Disabling a Managed Identity
// Disable immediately (revokes all active tokens)
POST /passport/admin/managed-identities/{managedIdentityId}/disable
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"reason": "security-incident",
"disabledBy": "admin-user-guid"
}
// Re-enable
POST /passport/admin/managed-identities/{managedIdentityId}/enable
Authorization: Bearer {admin-token}
Terraform / Infrastructure-as-Code
# Manage managed identities with Terraform (Passport provider)
resource "bizfirst_managed_identity" "payroll_scheduler" {
name = "payroll-monthly-scheduler"
description = "Runs the monthly payroll workflow"
tenant_id = var.tenant_id
roles = ["payroll-executor"]
tags = {
team = "finance"
environment = "production"
}
}
# Store the secret in Azure Key Vault
resource "azurerm_key_vault_secret" "payroll_scheduler_secret" {
name = "payroll-scheduler-client-secret"
value = bizfirst_managed_identity.payroll_scheduler.client_secret
key_vault_id = azurerm_key_vault.main.id
}