Source: https://atomic-works-test.docs-staging.pageloop.ai/integrations/identity-access-management/on-prem-active-directory-setup-for-user-provisioning

# On-prem Active Directory: Setup for user provisioning

User provisioning is essential to keep access and identity in sync during onboarding, offboarding, and role changes. With Atomicwork, you can automate user provisioning to on-premise Active Directory (AD) using Microsoft Entra's API-driven provisioning framework, eliminating manual effort and reducing security risks.

Based on updates to any system of record, such as your HR or payroll platforms, you can trigger workflows in Atomicwork that provision users in on-prem AD, sync them to Azure AD through AD Connect, and start follow-up actions such as notifications or access assignments.

This ensures:

- **Consistency:** User data is reliably synced across systems.
- **Efficiency:** Workflows replace manual steps and reduce provisioning time.
- **Security:** Accounts are automatically deactivated or updated when needed.
- **Scalability:** The process handles a large number of provisioning tasks without extra overhead.

## How it works

The integration uses Microsoft's secure, SCIM-based provisioning API and Atomicwork's [webhook actions in workflows](/product/enterprise-workflows/actions-and-integrations/webhook-actions) to automate user provisioning.

1. Your system of record, such as an HRIS, registers an event like a new hire or role change.

2. Atomicwork captures the event through a service catalog item and creates a new request.

3. The request triggers the user provisioning workflow in Atomicwork, which:

   - Authenticates through a registered service principal to fetch an OAuth token.
   - Sends a SCIM API request with user details to the Azure provisioning app endpoint for on-prem AD. The API payload includes a unique identifier called `externalId` to ensure identity consistency across systems and avoid duplicate provisioning.

4. The Microsoft Entra Provisioning Agent, installed on your on-prem server, processes the request and creates or updates the user in AD.

5. Azure AD Connect syncs the user to Azure AD.

6. Atomicwork proceeds with any additional actions, such as user creation within Atomicwork or sending alerts to relevant teams.

> \[!NOTE]
> This setup creates the AD account and syncs it to Entra ID. Mailbox provisioning must be handled separately by your Exchange topology, such as Exchange Online or Exchange hybrid, and should be tracked as a downstream child ticket.

## Prerequisites

Before you begin, confirm:

- **Microsoft Entra ID P1 license** with a seat for every user you will provision. P1 is also required for Atomicwork to poll provisioning logs.
- **A domain-joined Windows Server host** for the Entra provisioning agent. Use Windows Server 2016, 2019, or 2022 with 4 GB or more RAM, .NET Framework 4.7.1 or later, and network access to your domain controllers on TCP/389 (LDAP) and TCP/3268 (Global Catalog).
- **AD schema at Windows Server 2016 or later.** The `msDS-ExternalDirectoryObjectId` attribute must be present.
- **Notification email set on the provisioning app.** Jobs are quarantined if this is blank.
- **Matching attribute configured.** In the Entra provisioning app's attribute mappings, set `employeeId`, or your equivalent, as the matching attribute for `externalId`.

## What is the externalId and why does it matter?

The `externalId` is a core concept in SCIM-based identity provisioning. It serves as a client-side identifier to uniquely match a user across different systems.

On-prem AD does not include an `externalId` attribute by default, but it can be mapped to fields like `employeeID` or custom extension attributes.

This mapping is crucial to:

- Avoid duplicate user creation when retries happen.
- Enable idempotent provisioning behavior.
- Support reliable matching across sync cycles.

Azure AD Connect Cloud Provisioning, for instance, typically maps `externalId` to the `employeeID` field in AD.

## Setup for onboarding user provisioning

### Step 1: Create an enterprise application for provisioning in Microsoft Entra

1. Go to the Microsoft Entra admin portal and navigate to **Enterprise Applications > New application**.

2. Search for and select **API-driven provisioning to on-premises Active Directory**.

3. Provide a name for your application and create the app.

4. Grant the required permissions:

   - **SynchronizationData-User.Upload:** Allows Atomicwork to send user data to Microsoft Entra for provisioning.
   - **ProvisioningLog.Read.All:** Allows Atomicwork to poll provisioning logs to confirm the user was created before proceeding.

5. Open the newly created app and select the **Provisioning** tab.

6. Under **Settings**, set the **notification email**. This is required. Jobs are quarantined if this is blank.

7. Configure attribute mappings to align the SCIM user schema with your on-prem AD attributes. Set the matching attribute, typically `employeeId` to `externalId`, so retries update the existing user instead of creating duplicates.

8. Click **Start provisioning** to activate the service.

9. Copy the **Provisioning API Endpoint** to your clipboard.

For additional details or FAQs, see [Microsoft's guide to creating the API-driven inbound provisioning app](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/inbound-provisioning-api-configure-app).

### Step 2: Install the Microsoft Entra provisioning agent

1. Download the agent from the Entra portal and install it on your domain-joined server.

2. Configure the agent in the Entra admin center and authenticate it with your Azure AD account.

For detailed steps, see [Microsoft's guide to installing the Microsoft Entra provisioning agent](https://learn.microsoft.com/en-us/entra/identity/hybrid/cloud-sync/how-to-install).

### Step 3: Configure a service principal to call the provisioning app

To access the provisioning app securely, configure a service principal in Azure AD. See [Microsoft's guide to granting access to the inbound provisioning API](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/inbound-provisioning-api-grant-access) for further details.

Copy the **client ID**, **tenant ID**, and the created **client secret**.

### Step 4: Set up a webhook-based workflow in Atomicwork

1. Go to your Atomicwork tenant, such as `https://yourcompany.atomicwork.com`, and navigate to **Settings > Your Workspace name > Workflows**.

2. Create a new workflow for on-prem AD user provisioning.

3. Set up the trigger based on how your system-of-record data enters Atomicwork, such as through a service catalog request.

4. Use the **Azure action - Generate unique email from name** to create the user email ID from the given name information.

5. Configure a **Create a webhook** action to generate a token to access the provisioning app:

   - Choose the **POST** method.

   - Use the following API URL, replacing `{tenant_id}` with your tenant ID:

     ```text
     https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
     ```

   - Include the client ID and client secret from the service principal in the request body:

     ```json
     {
       "client_id": "{client_id}",
       "client_secret": "{client_secret}",
       "scope": "https://graph.microsoft.com/.default",
       "grant_type": "client_credentials"
     }
     ```

   - Test the connection and click **Done**.

6. Configure another webhook action to create or update the user in on-prem AD:

   - Choose the **POST** method.

   - Paste the **Provisioning API Endpoint** from your app.

   - Add these headers:

     ```text
     Authorization: Bearer {access_token}
     Content-type: application/scim+json
     ```

     The access token is available as an output placeholder from the previous action.

   - Add the SCIM payload with the required placeholders in the request body. Ensure `externalId` is mapped to the correct attribute from your input data, such as `employeeId`.

     ```json
     {
       "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
       "Operations": [
         {
           "method": "POST",
           "bulkId": "bulk-user-create",
           "path": "/Users",
           "data": {
             "schemas": [
               "urn:ietf:params:scim:schemas:core:2.0:User",
               "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
             ],
             "externalId": "{{request.service_item.employee_id}}",
             "userName": "{{action.response.body.email}}",
             "active": true,
             "name": {
               "formatted": "{{request.service_item.employee_name}} {{request.service_item.last_name}}",
               "familyName": "{{request.service_item.last_name}}",
               "givenName": "{{request.service_item.employee_name}}"
             },
             "displayName": "{{request.service_item.employee_name}} {{request.service_item.last_name}}",
             "nickName": "{{action.fetch_email.response.body.email?split('@')[0]}}",
             "emails": [
               {
                 "value": "{{action.response.body.email}}",
                 "type": "work",
                 "primary": true
               }
             ],
             "title": "{{request.service_item.position_title}}",
             "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
               "department": "{{request.service_item.users_department}}",
               "manager": {
                 "value": "{{action.fetch_manager.response.body.employeeId}}",
                 "displayName": "{{action.fetch_manager.response.body.givenName}} {{action.fetch_manager.response.body.surname}}"
               }
             }
           }
         }
       ],
       "failOnErrors": null
     }
     ```

   - Test the connection and click **Done**.

7. Add a **Wait** action to allow the provisioning agent to write the account and for up-sync to publish it to Entra ID. Entra Cloud Sync typically completes in 5-10 minutes. Entra Connect Sync can take up to 30 minutes.

8. Follow the wait with the **Azure action - Get user details from email** to confirm the user exists in Entra ID before proceeding. If the user is not found, raise an exception for manual review instead of continuing.

9. Use the **Azure action - Reset a user's password** to either auto-generate a password or force the user to reset it on the next login.

10. Notify the user of the update by using the **Send an email** action with the required information.

11. Add additional actions to the workflow to suit your onboarding flow.

12. Click **Publish** to activate the workflow.

## Setup for offboarding user provisioning

To manage user provisioning during offboarding:

1. Follow steps 1 to 3 from the onboarding setup.

2. In step 4, when adding the SCIM payload, set the `active` property to `false`.

After sending the disable, add these hardening steps to the workflow:

- **Revoke active sessions.** Setting `active: false` blocks new sign-ins but does not terminate existing cloud sessions. Add a webhook action to call Microsoft Graph's `revokeSignInSessions` endpoint on the user to end active sessions immediately.
- **Remove licenses.** Remove the user from licensing groups so their licenses are released.
- **Convert the mailbox to shared.** If you use Exchange Online, convert the mailbox to shared so it can be delegated and retained.

> \[!TIP]
> Disable accounts instead of deleting them. Deletion should follow a separate policy-driven timeline, typically 30-90 days after disable, once mailbox contents are archived and files are reassigned.

By combining Microsoft Entra's provisioning framework with Atomicwork's workflow engine, organizations can automate user onboarding and offboarding into on-premises AD and Azure AD. This improves consistency, reduces operational overhead, and strengthens employee lifecycle experiences.
