Add a custom approval workflow to self-service sign-up

With API connectors, you can integrate with your own custom approval workflows with self-service sign-up so you can manage which guest user accounts are created in your tenant.

This article gives an example of how to integrate with an approval system. In this example, the self-service sign-up user flow collects user data during the sign-up process and passes it to your approval system. Then, the approval system can:

  • Automatically approve the user and allow Microsoft Entra ID to create the user account.
  • Trigger a manual review. If the request is approved, the approval system uses Microsoft Graph to provision the user account. The approval system can also notify the user that their account has been created.

Important

  • Starting July 12, 2021, if Microsoft Entra B2B customers set up new Google integrations for use with self-service sign-up for their custom or line-of-business applications, authentication with Google identities won’t work until authentications are moved to system web-views. Learn more.
  • Starting September 30, 2021, Google is deprecating embedded web-view sign-in support. If your apps authenticate users with an embedded web-view and you're using Google federation with Azure AD B2C or Microsoft Entra B2B for external user invitations or self-service sign-up, Google Gmail users won't be able to authenticate. Learn more.

Register an application for your approval system

Tip

Steps in this article might vary slightly based on the portal you start from.

You need to register your approval system as an application in your Microsoft Entra tenant so it can authenticate with Microsoft Entra ID and have permission to create users. Learn more about authentication and authorization basics for Microsoft Graph.

  1. Sign in to the Microsoft Entra admin center as at least a User Administrator.
  2. Browse to Identity > Applications > App registrations, and then select New registration.
  3. Enter a Name for the application, for example, Sign-up Approvals.
  4. Select Register. You can leave other fields at their defaults.

Screenshot that highlights the Register button.

  1. Under Manage in the left menu, select API permissions, and then select Add a permission.
  2. On the Request API permissions page, select Microsoft Graph, and then select Application permissions.
  3. Under Select permissions, expand User, and then select the User.ReadWrite.All check box. This permission allows the approval system to create the user upon approval. Then select Add permissions.

Screenshot of requesting API permissions.

  1. On the API permissions page, select Grant admin consent for (your tenant name), and then select Yes.
  2. Under Manage in the left menu, select Certificates & secrets, and then select New client secret.
  3. Enter a Description for the secret, for example Approvals client secret, and select the duration for when the client secret Expires. Then select Add.
  4. Copy the value of the client secret. Client secret values can be viewed only immediately after creation. Make sure to save the secret when created, before leaving the page.

Screenshot of copying the client secret.

  1. Configure your approval system to use the Application ID as the client ID and the client secret you generated to authenticate with Microsoft Entra ID.

Create the API connectors

Next you'll create the API connectors for your self-service sign-up user flow. Your approval system API needs two connectors and corresponding endpoints, like the examples shown below. These API connectors do the following:

  • Check approval status. Send a call to the approval system immediately after a user signs-in with an identity provider to check if the user has an existing approval request or has already been denied. If your approval system only does automatic approval decisions, this API connector may not be needed. Example of a "Check approval status" API connector.

Screenshot of check approval status API connector configuration.

  • Request approval - Send a call to the approval system after a user completes the attribute collection page, but before the user account is created, to request approval. The approval request can be automatically granted or manually reviewed. Example of a "Request approval" API connector.

Screenshot of request approval API connector configuration.

To create these connectors, follow the steps in create an API connector.

Enable the API connectors in a user flow

Now you'll add the API connectors to a self-service sign-up user flow with these steps:

  1. Sign in to the Microsoft Entra admin center as at least a User Administrator.

  2. Browse to Identity > External identities > User flows, and then select the user flow you want to enable the API connector for.

  3. Select API connectors, and then select the API endpoints you want to invoke at the following steps in the user flow:

    • After federating with an identity provider during sign-up: Select your approval status API connector, for example Check approval status.
    • Before creating the user: Select your approval request API connector, for example Request approval.

Screenshot of API connector in a user flow.

  1. Select Save.

Control the sign-up flow with API responses

Your approval system can use its responses when called to control the sign-up flow.

Request and responses for the "Check approval status" API connector

Example of the request received by the API from the "Check approval status" API connector:

POST <API-endpoint>
Content-type: application/json

{
 "email": "johnsmith@fabrikam.onmicrosoft.com",
 "identities": [ //Sent for Google, Facebook, and Email One Time Passcode identity providers 
     {
     "signInType":"federated",
     "issuer":"facebook.com",
     "issuerAssignedId":"0123456789"
     }
 ],
 "displayName": "John Smith",
 "givenName":"John",
 "lastName":"Smith",
 "ui_locales":"en-US"
}

The exact claims sent to the API depend on which information is provided by the identity provider. 'email' is always sent.

Continuation response for "Check approval status"

The Check approval status API endpoint should return a continuation response if:

  • The user hasn't previously requested an approval.

Example of the continuation response:

HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "Continue"
}

Blocking response for "Check approval status"

The Check approval status API endpoint should return a blocking response if:

  • User approval is pending.
  • The user was denied and shouldn't be allowed to request approval again.

The following are examples of blocking responses:

HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "ShowBlockPage",
    "userMessage": "Your access request is already processing. You'll be notified when your request has been approved.",
}
HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "ShowBlockPage",
    "userMessage": "Your sign up request has been denied. Please contact an administrator if you believe this is an error",
}

Request and responses for the "Request approval" API connector

Example of an HTTP request received by the API from the "Request approval" API connector:

POST <API-endpoint>
Content-type: application/json

{
 "email": "johnsmith@fabrikam.onmicrosoft.com",
 "identities": [ // Sent for Google, Facebook, and Email One Time Passcode identity providers 
     {
     "signInType":"federated",
     "issuer":"facebook.com",
     "issuerAssignedId":"0123456789"
     }
 ],
 "displayName": "John Smith",
 "givenName":"John",
 "surname":"Smith",
 "jobTitle":"Supplier",
 "streetAddress":"1000 Microsoft Way",
 "city":"Seattle",
 "postalCode": "12345",
 "state":"Washington",
 "country":"United States",
 "extension_<extensions-app-id>_CustomAttribute1": "custom attribute value",
 "extension_<extensions-app-id>_CustomAttribute2": "custom attribute value",
 "ui_locales":"en-US"
}

The exact claims sent to the API depend on which information is collected from the user or is provided by the identity provider.

Continuation response for "Request approval"

The Request approval API endpoint should return a continuation response if:

  • The user can be automatically approved.

Example of the continuation response:

HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "Continue"
}

Important

If a continuation response is received, Microsoft Entra ID creates a user account and directs the user to the application.

Blocking Response for "Request approval"

The Request approval API endpoint should return a blocking response if:

  • A user approval request was created and is now pending.
  • A user approval request was automatically denied.

The following are examples of blocking responses:

HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "ShowBlockPage",
    "userMessage": "Your account is now waiting for approval. You'll be notified when your request has been approved.",
}
HTTP/1.1 200 OK
Content-type: application/json

{
    "version": "1.0.0",
    "action": "ShowBlockPage",
    "userMessage": "Your sign up request has been denied. Please contact an administrator if you believe this is an error",
}

The userMessage in the response is displayed to the user, for example:

Example pending approval page

User account creation after manual approval

After the custom approval system obtains manual approval, it creates a user account by using Microsoft Graph. The way your approval system provisions the user account depends on the identity provider that was used by the user.

For a federated Google or Facebook user and email one-time passcode

Important

The approval system should explicitly check that identities, identities[0] and identities[0].issuer are present and that identities[0].issuer equals 'facebook', 'google' or 'mail' to use this method.

If your user signed in with a Google or Facebook account or email one-time passcode, you can use the User creation API.

  1. The approval system uses receives the HTTP request from the user flow.
POST <Approvals-API-endpoint>
Content-type: application/json

{
 "email": "johnsmith@outlook.com",
 "identities": [
     {
     "signInType":"federated",
     "issuer":"facebook.com",
     "issuerAssignedId":"0123456789"
     }
 ],
 "displayName": "John Smith",
 "city": "Redmond",
 "extension_<extensions-app-id>_CustomAttribute": "custom attribute value",
 "ui_locales":"en-US"
}
  1. The approval system uses Microsoft Graph to create a user account.
POST https://graph.microsoft.com/v1.0/users
Content-type: application/json

{
 "userPrincipalName": "johnsmith_outlook.com#EXT@contoso.onmicrosoft.com",
 "accountEnabled": true,
 "mail": "johnsmith@outlook.com",
 "userType": "Guest",
 "identities": [
     {
     "signInType":"federated",
     "issuer":"facebook.com",
     "issuerAssignedId":"0123456789"
     }
 ],
 "displayName": "John Smith",
 "city": "Redmond",
 "extension_<extensions-app-id>_CustomAttribute": "custom attribute value"
}
Parameter Required Description
userPrincipalName Yes Can be generated by taking the email claim sent to the API, replacing the @character with _, and pre-pending it to #EXT@<tenant-name>.onmicrosoft.com.
accountEnabled Yes Must be set to true.
mail Yes Equivalent to the email claim sent to the API.
userType Yes Must be Guest. Designates this user as a guest user.
identities Yes The federated identity information.
<otherBuiltInAttribute> No Other built-in attributes like displayName, city, and others. Parameter names are the same as the parameters sent by the API connector.
<extension_{extensions-app-id}_CustomAttribute> No Custom attributes about the user. Parameter names are the same as the parameters sent by the API connector.

For a federated Microsoft Entra user or Microsoft account user

If a user signs in with a federated Microsoft Entra account or a Microsoft account, you must use the invitation API to create the user and then optionally the user update API to assign more attributes to the user.

  1. The approval system receives the HTTP request from the user flow.
POST <Approvals-API-endpoint>
Content-type: application/json

{
 "email": "johnsmith@fabrikam.onmicrosoft.com",
 "displayName": "John Smith",
 "city": "Redmond",
 "extension_<extensions-app-id>_CustomAttribute": "custom attribute value",
 "ui_locales":"en-US"
}
  1. The approval system creates the invitation using the email provided by the API connector.
POST https://graph.microsoft.com/v1.0/invitations
Content-type: application/json

{
    "invitedUserEmailAddress": "johnsmith@fabrikam.onmicrosoft.com",
    "inviteRedirectUrl" : "https://myapp.com"
}

Example of the response:

HTTP/1.1 201 OK
Content-type: application/json

{
    ...
    "invitedUser": {
        "id": "<generated-user-guid>"
    }
}
  1. The approval system uses the invited user's ID to update the user's account with collected user attributes (optional).
PATCH https://graph.microsoft.com/v1.0/users/<generated-user-guid>
Content-type: application/json

{
    "displayName": "John Smith",
    "city": "Redmond",
    "extension_<extensions-app-id>_AttributeName": "custom attribute value"
}

Next steps