LLD - razmipatel/Random GitHub Wiki
This Low-Level Design (LLD) describes the implementation of the SailPoint IdentityIQ (IIQ) integration with Microsoft Entra ID using iRequest (BMC Remedy) as the request and approval front-end.
It details:
- Entra ID connector configuration in SailPoint
- Entra ID app registrations and Graph permissions
- Secret management in CyberArk
- SailPoint application and identity configuration (including plugin-specific details)
- REST APIs exposed by the SailPoint EntraID User & Group Management plugin
- iRequest → SailPoint integration
- Oracle entitlement catalogue for form lookups
- Quarterly access review and certification design
The design is aligned with the approved HLD and requirements for SailPoint–Entra ID integration via iRequest and the EntraID User and Group Management Plugin.
In scope:
-
B2B guest identity lifecycle in Entra ID (create, update, delete) via SailPoint.
-
PIM-based Azure RBAC group access for standard, privileged (AZZ) and B2B users.
-
Entra ID built-in role management (PIM-eligible assignments).
HLD Appendix - SailPoint and En…
-
M365/Compliance roles exposed via Entra/role groups, where technically feasible.
-
iRequest integration via custom SailPoint REST APIs.
-
Quarterly attestation for:
- B2B identities
- Azure RBAC cloud-only groups (AZZ-RBAC)
- Entra PIM roles
- M365 role groups
Out of scope:
- Creation of privileged AZZ accounts and CyberArk account onboarding.
HLD Appendix - SailPoint and En…
- Non-Entra workloads not explicitly listed in the HLD.
-
HLD – HLD Appendix – SailPoint and Entra ID Integration via iRequest
HLD Appendix - SailPoint and En…
-
Requirements – Requirements – SailPoint Entra ID iRequest Form Development
Requirements - SailPoint Entra …
- Plugin Design – IdentityIQ–EntraID User and Group Management Plugin Design Document
The solution automates:
- B2B user creation/deletion and lifecycle management in Entra ID via SailPoint.
- Azure RBAC cloud-only group access (AZZ-RBAC) using PIM eligibility for staff, AZZ and B2B accounts.
- Entra built-in roles and M365 role assignments via updated PUR forms.
- Quarterly access reviews for B2B, groups and roles.
Key components:
-
iRequest (BMC Remedy) – Access request & approval engine (TPAA, AELZ, PUR forms).
-
SailPoint IdentityIQ – Identity governance platform, hosting:
- Entra ID application & connector
- EntraID User & Group Management plugin (custom REST APIs)
- IIQ rules for PowerShell-based PIM group operations
-
Microsoft Entra ID – Identity platform and Graph API endpoint.
-
CyberArk – Secret storage for connector/service principal credentials.
-
Oracle DB – Entitlement catalogue for iRequest form lookups.
-
iRequest (TPAA / AELZ / PUR)
-
Captures business requests for:
- B2B onboarding/leavers (TPAA)
- Non-privileged AZZ-RBAC access (AELZ)
- Privileged AZZ-RBAC, Entra built-in roles & M365 roles (PUR)
-
-
API Broker (e.g. Jitterbit / iPaaS)
- Handles REST calls from iRequest to SailPoint.
- Implements routing, transformation and error handling.
-
SailPoint IdentityIQ
- Hosts Entra ID application and connector.
- Hosts EntraID User & Group Management plugin with REST endpoints.
- Executes provisioning via connector/PowerShell.
- Manages campaigns and attestation.
-
Microsoft Entra ID
- Single Azure tenant used by ELZ and Entra identity.
- Exposed via Graph API for user, group, role and PIM operations.
-
CyberArk
- Safes for connector and PowerShell client credentials.
-
Oracle Entitlement DB
- Stores flattened entitlement catalogues for iRequest dropdowns.
See Section 11 for detailed flow descriptions and diagram guidance.
-
Application Name:
EntraID-Prod(patternEntraID-<Env>). -
Connector type: SailPoint Entra ID connector (successor to legacy Azure AD connector).
-
Tenant: AIB production Entra tenant.
-
Authentication: OAuth2 client credentials via Entra app registration (Section 4.2).
-
Usage:
- Aggregation of users, groups and built-in roles (native support).
- Provisioning of B2B guest users (invite), group membership and role assignments where supported.
-
Full aggregation – Daily load of:
- All users (
userType = MemberandGuest). - All relevant groups (incl.
AZZ-RBAC-*patterns). - All Entra built-in roles.
- All users (
-
Incremental aggregation – Intra-day deltas using connector delta support (where available).
-
Built-in role aggregation is supported natively; M365 role groups and PIM group eligibility are not.
-
PowerShell is retained for:
HLD Appendix - SailPoint and En…
- Aggregating M365 compliance/admin role groups.
- Managing PIM-eligible membership for Entra groups.
A dedicated Service Principal is used for the EntraID connector.
-
Example Name:
spn-sailpoint-entra-connector-prod. - Audience: Single-tenant (AIB).
- Auth: Client credentials (client ID + secret).
Graph Application Permissions (minimum):
-
User.Read.All,User.Invite.All– B2B invites & user read. -
Group.Read.All,Group.ReadWrite.All– group management. -
Directory.Read.All,Directory.ReadWrite.All– directory objects and role assignment where needed. -
RoleManagement.Read.Directory,RoleManagement.ReadWrite.Directory– PIM/built-in role assignments.
For Fire-and-Forget PIM group operations, a separate client is used by the PowerShell rules.
Required Graph permissions:
Group.ReadWrite.AllGroupMember.ReadWrite.AllPrivilegedEligibilitySchedule.Read.AzureADGroupPrivilegedEligibilitySchedule.ReadWrite.AzureADGroupPrivilegedEligibilitySchedule.Remove.AzureADGroupUser.Read
-
Connector and PowerShell client secrets are stored in dedicated CyberArk safes (e.g.
SAFE_SailPoint_Entra_Connector_Prod). -
SailPoint retrieves credentials at runtime via CyberArk integration:
- IdentityIQ/IQService uses SPAdmin or application identity to call CyberArk.
- Secrets are not stored in clear text in IIQ configuration, XML or rules.
The EntraID application in IIQ is configured with extended account schema attributes to support PIM roles.
| Attribute | Description | Multi-valued | Entitlement | Managed | Schema Object Type |
|---|---|---|---|---|---|
azureEligibleRoles |
List of Azure Eligible Roles | Yes | Yes | Yes | azureEligibleRole |
azureActiveRoles |
List of Azure Active Roles | Yes | Yes | Yes | azureActiveRole |
azureADEligibleRoles |
List of Entra ID Eligible Roles | Yes | Yes | Yes | azureADEligibleRole |
azureADActiveRoles |
List of Entra ID Active Roles | Yes | Yes | Yes | azureADActiveRole |
These attributes support:
- Representation of PIM-eligible and active role assignments in the identity warehouse.
- Inclusion of these roles in quarterly access reviews.
The EntraID application’s Create Account provisioning policy includes the following Guest User B2B attributes:
| Policy Attribute Display Name | Attribute Name | Form Section | Type |
|---|---|---|---|
con_prov_policy_azure_ad_invitedUserEmailAddress |
invitedUserEmailAddress |
Guest User B2B | string |
con_prov_policy_azure_ad_inviteRedirectUrl |
inviteRedirectUrl |
Guest User B2B | string |
con_prov_policy_azure_ad_displayName |
invitedUserDisplayName |
Guest User B2B | string |
con_prov_policy_azure_ad_sendInvitationMessage |
sendInvitationMessage |
Guest User B2B | boolean |
con_prov_policy_azure_ad_usageLocation |
invitedUserUsageLocation |
Guest User B2B | string |
These are populated from the plugin createB2BUser API payload and drive the Graph invitation.
The Delete Account policy uses:
AIB-EntraIDPluginDesignDoc
| Attribute Name | Type | Section |
|---|---|---|
nativeIdentity |
string | Account |
The provisioning policy ensures that the correct Entra account is deleted when the corresponding B2B identity is removed.
A new identity type B2BUser is introduced in IIQ.
Configuration snippet in Identity Configuration (identityTypeDefinitions):
<IdentityTypeDefinition displayName="B2B User" name="B2BUser"> <DisallowedAttributes> <String>softwareVersion</String> <String>administrator</String> <String>description</String> </DisallowedAttributes></IdentityTypeDefinition>
All B2B identities created via REST services:
- Must be of type
B2BUser. - Carry attributes: FirstName, LastName, UserName, Email, PartnerCompany, Manager, StartDate, EndDate, and optionally StaffID (for correlation with staff identity).
The UserName/displayName format is standardized as:
FirstName LastName (Partner Company)AIB-EntraIDPluginDesignDoc
Due to connector limitations, PIM group eligibility is managed via a Fire-and-Forget pattern.
Two rules are implemented:
-
EntraId Powershell – Beanshell(After Provisioning Rule)-
Runs on IQService.
-
Creates a synthetic account request for a “fake identity”.
-
Triggers provisioning for this fake account to execute the PowerShell rule with parameters:
-
username,groupname,operation(“Add”/“Remove”).
-
-
-
EntraId Powershell – PS Code(PowerShell Rule)- Executes PIM group add/remove operations via Graph PIM APIs using the PIM client app registration.
- Updates PIM eligibility in Entra; the resulting PIM eligibility details are not fully aggregatable in IIQ.
The LLD explicitly records that eligible PIM group memberships managed solely through this path cannot be fully validated via standard aggregation and will require carefully designed review evidence.
SailPoint APIs are secured using IIQ’s built-in OAuth client function and Service Provider (SP) rights.
-
An OAuth client is created in IIQ (Global Settings → API Authentication).
-
A proxy user is assigned which has the SP Right:
-
EntraIDUserGroupManagementPluginRight.
-
-
The OAuth client’s client ID and secret are issued to the integration layer (iRequest / API Broker).
At runtime:
-
API Broker calls IIQ token endpoint with client credentials.
-
The access token is used in
Authorization: Bearer <token>when calling plugin REST endpoints. -
IIQ validates:
- Token authenticity and expiry.
- Proxy user entitlement to
EntraIDUserGroupManagementPluginRight.
-
Failure to meet these conditions results in
403 Forbidden.
From the HLD:
- Standard AIB staff identity – Source: SAP HR/On-prem AD; correlated via 5-digit staff ID.
-
Privileged AZZ identities – Pattern
azz_<staffID>; used for privileged administration (out of scope for creation here). -
B2B Guest identities – Type
B2BUser; attributes include Username, Email, FirstName, LastName, PartnerCompany, Manager, StaffID (when present), Start/End dates.
One human may own multiple identities (staff + AZZ + B2B), linked via staff ID and correlation rules.
-
Create – via TPAA form, plugin
createB2BUserAPI, Entra invite, base group assignment. -
Update – attribute changes triggered by new TPAA submissions or upstream HR changes (manager, end date, partner).
-
Terminate – via TPAA “Remove” or campaign-driven revocation:
- Remove AZZ-RBAC and role memberships.
- Disable and then delete guest account in Entra (Delete Account policy).
Example mapping for B2B user creation:
| IIQ Identity Attribute | Entra Attribute |
|---|---|
firstName |
givenName |
lastName |
surname |
userName |
displayName (FirstName LastName (Partner)) |
email |
invitedUserEmailAddress |
partnerCompany |
Extension / directory attribute |
manager |
Manager object ID resolved via staff ID |
startDate / endDate
|
Entra extension attributes |
-
Pattern:
AZZ-RBAC-B2B-<Partner>(e.g.AZZ-RBAC-B2B-Globant).HLD Appendix - SailPoint and En…
-
Auto-assigned during B2B creation (or flagged if group is missing).
-
Used for:
- Conditional Access scoping.
- Visibility and reporting of B2B identities.
-
Identification via Entra group attributes maintained by IDM/Security:
-
Privileged = N. -
iRequest = Y(request-able via AELZ). -
Owner = <staffID>andDeputy = <staffID>.
-
-
Request Path: AELZ form in iRequest.
-
Provisioning:
- iRequest → API Broker → plugin
addRemoveGroupfor Entra group membership. - For PIM-eligible non-privileged groups, optionally
addRemovePIMGroupis also used (where appropriate).
- iRequest → API Broker → plugin
-
Identification:
-
Privileged = Y,iRequest = Y.
-
-
Principal:
- Only AZZ identities (
azz_<staffID>) are permitted membership.
- Only AZZ identities (
-
Request Path:
- Updated PUR form in iRequest.
-
Provisioning:
-
addRemovePIMGroupfor PIM-eligible group membership of AZZ account. -
addRemoveGroupif backing static groups are also required.
-
- Entra built-in roles are aggregated by the Entra connector and exposed as entitlements via
azureADEligibleRoles/azureADActiveRoles. - Requested via updated PUR form.
HLD Appendix - SailPoint and En…
- Assigned/removed via plugin
addRemoveEligibleRole, producing PIM eligible role assignments in Entra.
-
Represented as role groups in Entra/M365 (e.g. Defender, Exchange, Purview).
-
Aggregated via PowerShell-based process (separate from standard connector aggregation).
-
Requested via PUR form.
-
Provisioned via:
-
addRemoveGroupfor M365 role groups, and/or -
addRemovePIMGroupwhere PIM-eligible role groups exist.
-
- Transport: HTTPS (TLS 1.2+) end-to-end.
- Network: Internal AIB network between iRequest, API Broker and SailPoint.
- Authentication: IIQ OAuth client (Section 5.5).
- Authorisation: SP Right
EntraIDUserGroupManagementPluginRighton proxy user.
Based on the HLD flows:
| iRequest Form | Use Case | Plugin API(s) |
|---|---|---|
| TPAA | B2B Onboarding / Removal |
createB2BUser, deleteB2BUser
|
| AELZ | Non-privileged AZZ-RBAC group access |
addRemoveGroup (optionally addRemovePIMGroup) |
| PUR | Privileged AZZ-RBAC groups |
addRemovePIMGroup, addRemoveGroup
|
| PUR | Entra built-in roles | addRemoveEligibleRole |
| PUR | M365 role groups |
addRemoveGroup / addRemovePIMGroup
|
-
iRequest composes JSON payload according to plugin API contract (Section 8).
-
API Broker:
- Obtains OAuth token from IIQ.
- Calls appropriate plugin endpoint with payload.
-
Plugin:
-
Validates inputs, performs IIQ/Entra operations and returns:
-
200 OKwith"Success"on success, -
400 Bad Requestwith detailed error message, or -
403 Forbiddenif unauthorised.
-
-
Base Path:
/identityiq/plugin/rest/EntraIDUserGroupManager/…
-
Auth: OAuth2 bearer token associated to proxy user with SP Right
EntraIDUserGroupManagementPluginRight. -
Content Type:
application/json. -
Response Codes:
AIB-EntraIDPluginDesignDoc
-
200 OK– operation completed successfully. -
400 Bad Request– validation / functional errors. -
403 Forbidden– caller not authorised.
-
-
Method:
POST -
URL:
/createB2BUser -
Function:
- Creates B2B identity in IIQ with identity type
B2BUser. - Uses EntraID Create Account policy to invite guest user in Entra.
- Assigns default partner base group if present.
- Creates B2B identity in IIQ with identity type
Input JSON:
{ "firstname": "<FirstName>", "lastname": "<LastName>", "email": "<EmailAddress>", "partner": "<PartnerCompany>", "manager": "<ManagerUserNameInIIQ>", "startDate": "MM/DD/YYYY", "endDate": "MM/DD/YYYY"}
Success:
- HTTP 200, body:
"Success".
Error Handling (HTTP 400):
AIB-EntraIDPluginDesignDoc
- Manager not present in IIQ.
- Mandatory inputs missing.
- Default partner group missing – B2B user created but Entra account not created; message indicates partial failure.
-
Method:
DELETE -
URL:
/deleteB2BUserAIB-EntraIDPluginDesignDoc
-
Function:
- Deletes Entra guest account via Delete Account policy.
- Deletes B2B identity in IIQ.
Input JSON: same structure as createB2BUser.
Success:
- HTTP 200,
"Success".
Error Handling (HTTP 400):
- Non-existent user in IIQ.
- Mandatory inputs missing.
-
Method:
POST -
URL:
/addRemovePIMGroup -
Function:
- Fire-and-Forget: add/remove user as PIM-eligible member of an Entra group via PowerShell rules.
Input JSON:
{ "username": "<User Name>", "groupname": "<EntraID Role>", "operation": "Add/Remove"}
Success:
- HTTP 200,
"Success"(no synchronous verification with Entra PIM).
Error Handling (HTTP 400):
- User not present in IIQ.
- Group not present in IIQ (requires Entra aggregation).
- Invalid
operation. - User has no Entra account.
- Mandatory inputs missing.
-
Method:
PUT -
URL:
/addRemoveGroup -
Function:
- Add/remove standard Entra groups (e.g. AZZ-RBAC groups).
Input JSON:
{ "username": "<User Name>", "groupname": "<Group Name>", "operation": "Add/Remove"}
Success:
- HTTP 200,
"Success".
Error Handling (HTTP 400):
- User already a member when adding.
- User not present in IIQ.
- Group not present in IIQ (aggregation gap).
- Invalid
operation. - User without Entra account.
- Mandatory inputs missing.
-
Method:
PUT -
URL:
/addRemoveEligibleRole -
Function:
- Add/remove Entra ID eligible roles for users with Entra accounts (PIM roles).
Input JSON:
{ "username": "<User Name>", "rolename": "<EntraID Role>", "operation": "Add/Remove"}
Success:
- HTTP 200,
"Success".
Error Handling (HTTP 400):
- User not present in IIQ.
- Role not present in IIQ.
- Invalid
operation. - User without Entra account.
- User already has role (Add) or does not have role (Remove).
- Mandatory inputs missing.
iRequest forms require performant, filtered entitlement lookups (e.g. per tenant, value stream, entitlement type). These are served from an external Oracle database populated from SailPoint.
Table: ENTITLEMENT_CATALOG (example)
| Column | Type | Description |
|---|---|---|
ENT_ID |
VARCHAR2 | Unique entitlement identifier (IIQ object ID / name) |
ENT_CODE |
VARCHAR2 | Group or role name |
ENT_TYPE |
VARCHAR2 |
B2B_BASE, AZZ_RBAC_PRIV, AZZ_RBAC_NONPRIV, ENTRA_ROLE, M365_ROLE
|
TENANT |
VARCHAR2 | Azure tenant code |
VALUE_STREAM |
VARCHAR2 | ELZ value stream |
PRIVILEGED_FLAG |
CHAR(1) |
Y / N
|
IREQUEST_FLAG |
CHAR(1) |
Y / N (request-able) |
OWNER_STAFF_ID |
VARCHAR2 | Primary owner |
DEPUTY_STAFF_ID |
VARCHAR2 | Deputy owner |
LAST_SYNC_TS |
DATE | Last synchronisation timestamp |
-
A SailPoint task/ETL process periodically exports:
- Groups and roles where
iRequest = Y.
- Groups and roles where
-
Integration (e.g. via iPaaS/SQL*Loader) loads this into Oracle on a schedule (e.g. hourly).
-
iRequest form logic queries Oracle with filters (tenant, value stream, entitlement type, privileged flag) to populate dropdowns.
Implementation details of the ETL job are explicitly out of scope of this project, but the logical contract is in scope.
Quarterly campaigns are configured in SailPoint for:
-
B2B Accounts – All identities of type
B2BUser. - Azure RBAC Groups (AZZ-RBAC) – Both non-privileged and privileged groups.
-
Entra PIM Roles – Based on
azureADEligibleRoles/azureADActiveRoles. - M365 Role Groups – Where aggregatable via connector/PowerShell.
- B2B – Manager of B2B user and/or B2B sponsor/partner owner.
-
Groups/Roles – Group/role Owner (
OwnerStaffId) or Deputy. - Fallback – Security or Platform owner for unassigned objects.
-
Review actions:
Keep,Remove,Reassign,Comment. -
Revocations trigger:
- B2B account disable/delete (Delete Account policy & plugin).
- Group/role membership removal via the same plugin APIs (
addRemoveGroup,addRemovePIMGroup,addRemoveEligibleRole).
-
Campaign results stored in IIQ and exportable for audit.
-
Plugin APIs generate audit records for all operations:
-
Create,Delete,EntitlementAdd,EntitlementRemovewith contextual attributes (identity, application, entitlement, native identity, message).
-
Below are textual descriptions you can use as a basis for draw.io/Visio diagrams.
Elements:
-
SailPoint IdentityIQ
- EntraID Application & Connector
- EntraID User & Group Management Plugin
- PowerShell Rules
-
CyberArk Safe(s)
-
Microsoft Entra ID (Graph)
Flow:
- Connector initialises; retrieves client secret from CyberArk via SPAdmin service identity.
- Connector obtains OAuth token from Entra using app registration.
- Connector performs aggregation (users, groups, built-in roles).
- Provisioning events (B2B create, group/role assignment) call Graph through connector.
- For PIM group eligibility, IIQ rules trigger PowerShell script which uses a second app registration to call PIM APIs.
Elements:
- User
- iRequest (TPAA / AELZ / PUR)
- API Broker (Jitterbit)
- SailPoint EntraID Plugin
- EntraID Connector / PowerShell
- Microsoft Entra ID
Flow:
-
User submits TPAA/AELZ/PUR form in iRequest.
-
iRequest runs approval workflow.
-
On approval, API Broker:
- Gets IIQ OAuth token.
- Calls appropriate plugin REST endpoint.
-
Plugin validates payload and:
- For B2B: creates identity, invokes EntraID Create Account policy.
- For groups: calls
addRemoveGroupand optionallyaddRemovePIMGroup. - For roles: calls
addRemoveEligibleRole.
-
Connector/PowerShell updates Entra/PIM.
-
Plugin returns success/error; API Broker updates Work Order/iRequest and surfaces status to requester.
Elements:
- SailPoint Campaign Engine
- Reviewer (Manager / Owner)
- Provisioning Engine
- Plugin APIs
- Entra/PIM
Flow:
- Quarterly campaign launched for selected scopes.
- Reviewer completes certification decisions.
- Revocation decisions create provisioning tasks.
- Provisioning engine calls plugin APIs to remove group/role membership or delete B2B accounts.
- Entra/PIM state is updated; IIQ aggregation confirms final state.
- Campaign closure generates evidence and reports.