Flow Studio
Passport API Client
The IPassportClient interface — how identity executors call Passport IAM from the backend, request/response shapes, and the caching layer.
IPassportClient Interface
public interface IPassportClient
{
Task<PassportUser?> LookupUserAsync(
UserLookupRequest request,
CancellationToken ct = default);
Task<IReadOnlyList<PassportUser>> GetRoleMembersAsync(
RoleMembersRequest request,
CancellationToken ct = default);
Task<bool> CheckPermissionAsync(
PermissionCheckRequest request,
CancellationToken ct = default);
Task<PassportUser?> GetUserByIdAsync(
string userId,
string tenantId,
CancellationToken ct = default);
}
public record UserLookupRequest
{
public string LookupBy { get; init; } = default!; // email | employeeId | username | userId
public string Value { get; init; } = default!;
public bool IncludeRoles { get; init; }
public string TenantId { get; init; } = default!;
}
public record PassportUser
{
public string UserId { get; init; } = default!;
public string Email { get; init; } = default!;
public string DisplayName { get; init; } = default!;
public string? Username { get; init; }
public string? EmployeeId { get; init; }
public bool IsActive { get; init; }
public string[] Roles { get; init; } = [];
public string? ManagerId { get; init; }
public string? Department { get; init; }
}
Caching Layer
The CachedPassportClient decorator wraps HttpPassportClient and caches responses for 60 seconds per execution to reduce Passport API calls:
// DI registration
services.AddHttpClient<IPassportClient, HttpPassportClient>();
services.Decorate<IPassportClient, CachedPassportClient>();
// CachedPassportClient uses IMemoryCache with sliding 60-second expiry per (tenantId, lookupKey)
DI Registration in Executors
// Executors inject IPassportClient via constructor
public class UserLookupExecutor : BaseNodeExecutor<UserLookupConfig>
{
private readonly IPassportClient _passport;
private readonly IExpressionEvaluator _evaluator;
public UserLookupExecutor(IPassportClient passport, IExpressionEvaluator evaluator)
{
_passport = passport;
_evaluator = evaluator;
}
// ...
}
Custom executors: If you build a custom node that needs identity data, inject
IPassportClient directly — do not call Passport HTTP endpoints yourself. This ensures you benefit from tenant scoping enforcement, caching, and circuit breaker protection built into the client implementation.