IAM Overview
Passport IAM provides a three-layer access control model — Roles, Permission Sets, and Permissions — with support for both built-in providers (Passport, Azure AD, Okta, AWS Cognito) and custom extensions.
The Three-Layer Model
Layer 1 — Roles
Named collections of permissions. Users are assigned roles. Roles can be system-defined (Admin, Manager, User, Viewer) or tenant-custom. Role membership is resolved by IMembershipProvider.
Layer 2 — Permission Sets
Logical groupings of permission strings associated with a role. For example, the manager role includes the workflow permission set: workflow.design, workflow.initiate, workflow.view.
Layer 3 — Permissions
Atomic capability strings in dot-notation format (resource.action). Resolved by IPermissionProvider. These are the actual values checked at runtime by services and nodes.
IAM Provider Architecture
The IAM system is provider-agnostic. All identity providers implement the same six interfaces, allowing seamless operation whether Passport, Azure AD, Okta, or AWS Cognito backs the identity store.
// The 6 provider interfaces — all IAM providers implement these
namespace BizFirst.Ai.ProcessSecurity.Extended.Domain.Interfaces;
public interface IIdentityProvider // JWT → IdentityClaims
public interface IMembershipProvider // userId → group/role IDs
public interface IUserDirectoryProvider // search/get users
public interface IRoleDirectoryProvider // search/get roles
public interface IPermissionProvider // userId → permission strings
public interface IAccessDecisionProvider// userId + nodeId → allow?
| Provider | Identity Source | Role Source | Permission Source |
|---|---|---|---|
| BizFirst Passport | JWT "sub" claim | SQL IAM_UserRoles | JWT "permissions" claim or SQL |
| Azure AD / Entra ID | JWT "oid" claim | JWT "groups" or Graph API | App roles in JWT |
| Okta | JWT "sub" claim | JWT "groups" claim | Okta groups or JWT custom claims |
| AWS Cognito | JWT "sub" claim | JWT "cognito:groups" | JWT custom attributes |
Policy Evaluation Engine
Every permission check flows through IIAMPolicyEngine. The engine evaluates in this order:
Resolve Identity
IIdentityProvider.ResolveIdentityAsync(token) — extract UserId, TenantId, Email from the JWT without signature re-validation (upstream middleware already validated it).
Resolve Roles
IMembershipProvider.GetUserGroupsAsync() — returns the user's role IDs. For Passport: SQL query on IAM_UserRoles. For Azure AD: JWT "groups" claim or Microsoft Graph API call.
Resolve Permissions
IPermissionProvider.GetUserPermissionsAsync() — returns explicit permission strings. For most providers, these come from the JWT "permissions" claim.
Evaluate Policy
For each role: look up the permission set. Check if the requested permission string is in the set. Apply resource-level policy overrides. Deny by default — explicit allow required.
Access Decision
IAccessDecisionProvider.CanUserAccessAsync() — optional final gate. Returns null (no opinion), true (allow), or false (deny). A false overrides all previous allows.
Built-In Roles Summary
| Role | Level | Typical Permissions |
|---|---|---|
admin | System | All permissions — full tenant management, IAM administration |
manager | System | Workflow design and execution, form management, team user management |
user | System | Workflow initiation, form submission, read-only access to assigned resources |
viewer | System | Read-only access to workflows and forms — no execution or modification |
The BizFirstGO IAM model works identically whether you are using Passport's native identity, Azure AD, Okta, or a custom provider. The permission evaluation logic lives in IIAMPolicyEngine — not in the identity provider. External roles are mapped to BizFirstGO's permission model at the provider level.