Skip to content
English
  • There are no suggestions because the search field is empty.

Microsoft Entra ID

The EQTY Governance Platform integrates with Microsoft Entra ID (formerly Azure Active Directory) for enterprise-grade authentication and authorization.

Required app registrations:

  • Governance Platform Backend API – Web application for backend API authentication and token validation
  • Microsoft Graph API Access – Separate app registration for user and organization management via Microsoft Graph
  • Governance Worker – M2M confidential client for automated governance workflow execution
  • Governance Studio SPA – Single Page Application for frontend authentication

This guide covers:

  • Creating app registrations in Entra ID (Azure CLI or Portal)
  • Configuring API permissions and scopes
  • Setting up Microsoft Graph access
  • Post-installation organization and admin user setup
  • Configuring the Helm chart for Entra ID
  • Microsoft Entra ID tenant (Azure AD tenant)
  • Azure CLI installed and configured (for CLI method)
  • Permissions to create app registrations in the tenant
  • Tenant ID (found in Azure Portal > Microsoft Entra ID > Overview)

Add the following to the values.yaml and secrets.yaml files. Placeholders will be filled in throughout the steps below.

values.yaml:


    
auth-service :
config :
idp :
provider : " entra "
issuer : " https://login.microsoftonline.com/ /v2.0 " # Filled in after step 1
entra :
tenantId : " " # Filled in after step 1
defaultRoles : " user "
governance-service :
config :
authProvider : " entra "
entraTenantId : " " # Filled in after step 1
governance-studio :
config :
authProvider : " entra "
entraTenantId : " " # Filled in after step 1
entraClientId : " " # Filled in after step 5
entraScopes : " openid profile email offline_access api:// /access_as_user " # Filled in after steps 2 & 5

secrets.yaml:


    
global :
secrets :
create : true
auth :
provider : " entra "
entra :
secretName : " platform-entra "
values :
clientId : " " # Filled in after step 2
clientSecret : " " # Filled in after step 2
tenantId : " " # Filled in after step 1
graphClientId : " " # Filled in after step 3
graphClientSecret : " " # Filled in after step 3
governanceWorker :
secretName : " platform-governance-worker "
values :
encryptionKey : " " # Generate: openssl rand -base64 32
clientId : " " # Filled in after step 4
clientSecret : " " # Filled in after step 4
Section titled “Quick Start (CLI Method - Recommended)”

The tenant ID can be found in Azure Portal > Microsoft Entra ID > Overview. Login to Azure with the tenant:

Terminal window

    
az login --tenant

Verify the correct tenant:

Terminal window

    
az account show

Update values.yaml with the tenant ID.

values.yaml -> auth-service.config.idp:


    
issuer : " https://login.microsoftonline.com/ /v2.0 "
entra :
tenantId : " "

values.yaml -> governance-service.config:


    
entraTenantId : " "

values.yaml -> governance-studio.config:


    
entraTenantId : " "

Update secrets.yaml with the tenant ID.

secrets.yaml -> global.secrets.auth.entra.values:


    
tenantId : " "

2. Create Backend API App Registration

Section titled “2. Create Backend API App Registration”

Create the backend API app registration. Replace with the governance platform domain (e.g. governance.example.com):

Terminal window

    
az ad app create \
--display-name " EQTY Governance Platform Backend " \
--sign-in-audience AzureADMyOrg \
--enable-id-token-issuance true \
--enable-access-token-issuance true \
--web-redirect-uris " https:// /callback "

Save the appId and id from the output:

  • appId is the Client ID
  • id is the Object ID

Store both as variables for use in subsequent commands:

Terminal window

    
BACKEND_CLIENT_ID = " "
BACKEND_OBJECT_ID = " "

Create a service principal and set the application ID URI:

Terminal window

    
az ad sp create --id $BACKEND_CLIENT_ID
az ad app update --id $BACKEND_CLIENT_ID \
--identifier-uris " api:// $BACKEND_CLIENT_ID "

Generate a unique ID for the API scope:

Terminal window

    
uuidgen

Save this UUID — it will be used as SCOPE_ID in the next step.

Create a file named backend-scope.json with the following content. Replace SCOPE_ID with the UUID from above:


    
{
"api" : {
"requestedAccessTokenVersion" : 2 ,
"oauth2PermissionScopes" : [
{
"id" : " SCOPE_ID " ,
"adminConsentDescription" : " Allow the application to access EQTY Governance Platform on behalf of the signed-in user " ,
"adminConsentDisplayName" : " Access EQTY Governance Platform " ,
"isEnabled" : true ,
"type" : " User " ,
"userConsentDescription" : " Allow the application to access EQTY Governance Platform on your behalf " ,
"userConsentDisplayName" : " Access EQTY Governance Platform " ,
"value" : " access_as_user "
}
]
}
}

Add the API scope to the app registration:

Terminal window

    
az rest --method PATCH \
--uri " https://graph.microsoft.com/v1.0/applications/ $BACKEND_OBJECT_ID " \
--headers " Content-Type=application/json " \
--body @backend-scope.json

Create a client secret for the backend app:

Terminal window

    
az ad app credential reset \
--id $BACKEND_CLIENT_ID \
--append \
--query password \
--output tsv

Save the client secret — it cannot be retrieved later.

Update secrets.yaml with the backend credentials.

secrets.yaml -> global.secrets.auth.entra.values:


    
clientId : " "
clientSecret : " "

Update values.yaml with the backend client ID (used in the scopes string).

values.yaml -> governance-studio.config:


    
entraScopes : " openid profile email offline_access api:// /access_as_user "

3. Create Graph API Access App Registration

Section titled “3. Create Graph API Access App Registration”

Create the Graph API access app registration:

Terminal window

    
az ad app create \
--display-name " EQTY Governance Platform Graph API " \
--sign-in-audience AzureADMyOrg

Save the appId from the output — this is the Graph API Client ID.

Store it as a variable for use in subsequent commands:

Terminal window

    
GRAPH_CLIENT_ID = " "

Create a service principal for the app:

Terminal window

    
az ad sp create --id $GRAPH_CLIENT_ID

Add Microsoft Graph API permissions for reading users and organization information:

Terminal window

    
az ad app permission add \
--id $GRAPH_CLIENT_ID \
--api 00000003-0000-0000-c000-000000000000 \
--api-permissions df021288-bdef-4463-88db-98f22de89214=Role 498476ce-e0fe-48b0-b801-37ba7e2685c6=Role

This adds:

  • User.Read.All (df021288-bdef-4463-88db-98f22de89214) – Read all users’ full profiles
  • Organization.Read.All (498476ce-e0fe-48b0-b801-37ba7e2685c6) – Read organization information

Grant admin consent for the API permissions (requires admin privileges):

Terminal window

    
az ad app permission admin-consent --id $GRAPH_CLIENT_ID

Create a client secret for the Graph API app:

Terminal window

    
az ad app credential reset \
--id $GRAPH_CLIENT_ID \
--append \
--query password \
--output tsv

Save the client secret — it cannot be retrieved later.

Update secrets.yaml with the Graph API credentials.

secrets.yaml -> global.secrets.auth.entra.values:


    
graphClientId : " "
graphClientSecret : " "

4. Create Governance Worker App Registration

Section titled “4. Create Governance Worker App Registration”

The Governance Worker is a confidential M2M (machine-to-machine) client used for automated governance workflow execution.

Create the Governance Worker app registration:

Terminal window

    
az ad app create \
--display-name " EQTY Governance Worker " \
--sign-in-audience AzureADMyOrg

Save the appId from the output — this is the Worker Client ID.

Store it as a variable for use in subsequent commands:

Terminal window

    
WORKER_CLIENT_ID = " "

Create a service principal for the app:

Terminal window

    
az ad sp create --id $WORKER_CLIENT_ID

Create a client secret for the Worker app:

Terminal window

    
az ad app credential reset \
--id $WORKER_CLIENT_ID \
--append \
--query password \
--output tsv

Save the client secret — it cannot be retrieved later.

Generate an encryption key for the worker:

Terminal window

    
openssl rand -base64 32

Update secrets.yaml with the worker credentials.

secrets.yaml -> global.secrets.governanceWorker.values:


    
encryptionKey : " "
clientId : " "
clientSecret : " "

5. Create Frontend SPA App Registration

Section titled “5. Create Frontend SPA App Registration”

Create the SPA app registration:

Terminal window

    
az ad app create \
--display-name " EQTY Governance Studio " \
--sign-in-audience AzureADMyOrg \
--enable-id-token-issuance true \
--enable-access-token-issuance true

Save the appId and id from the output:

  • appId is the SPA Client ID
  • id is the SPA Object ID

Store both as variables:

Terminal window

    
SPA_CLIENT_ID = " "
SPA_OBJECT_ID = " "

Configure SPA redirect URIs and set token version to v2.0. Replace with the governance platform domain:

Terminal window

    
az rest --method PATCH \
--uri " https://graph.microsoft.com/v1.0/applications/ $SPA_OBJECT_ID " \
--headers " Content-Type=application/json " \
--body " { \" spa \" :{ \" redirectUris \" :[ \" https:// \" ]}, \" api \" :{ \" requestedAccessTokenVersion \" :2}} "

Create a service principal for the SPA app:

Terminal window

    
az ad sp create --id $SPA_CLIENT_ID

Get the backend API scope ID:

Terminal window

    
az ad app show --id $BACKEND_CLIENT_ID --query ' api.oauth2PermissionScopes[0].id ' -o tsv

Save this scope ID — it will be used in the next command.

Grant the SPA access to the backend API. Replace with the value from above:

Terminal window

    
az ad app permission add \
--id $SPA_CLIENT_ID \
--api $BACKEND_CLIENT_ID \
--api-permissions =Scope

Optionally, grant admin consent for the API permission:

Terminal window

    
az ad app permission admin-consent --id $SPA_CLIENT_ID

Note: Admin consent may require higher privileges. If this fails, grant consent later through the Azure Portal.

Update values.yaml with the SPA client ID.

values.yaml -> governance-studio.config:


    
entraClientId : " "
Click to expand Azure Portal instructions

1. Create Backend API App Registration

Section titled “1. Create Backend API App Registration”
  • Navigate to Azure Portal > Microsoft Entra ID > App registrations
  • Click “New registration”
  • Name: “EQTY Governance Platform Backend”
  • Supported account types: “Accounts in this organizational directory only”
  • Redirect URI: Web, https:// /callback
  • Click “Register”
  • Note the Application (client) ID and Directory (tenant) ID
  • Navigate to “Manifest”
  • Find “accessTokenAcceptedVersion” and set it to 2 (for v2.0 tokens)
  • Click “Save”
  • Navigate to “Expose an API”
  • Set Application ID URI: api://
  • Add a scope:
    • Scope name: access_as_user
    • Admin consent display name: “Access EQTY Governance Platform”
    • Admin consent description: “Allow the application to access EQTY Governance Platform on behalf of the signed-in user”
    • State: Enabled
    • Click “Add scope”
  • Navigate to “Certificates & secrets”
  • Click “New client secret”
  • Description: “Governance Platform Secret”
  • Expires: 24 months (or the organization’s policy)
  • Click “Add”
  • Copy the secret Value immediately — it won’t be shown again

Update values.yaml with the tenant ID and backend credentials.

values.yaml -> auth-service.config.idp:


     
issuer : " https://login.microsoftonline.com/ /v2.0 "
entra :
tenantId : " "

values.yaml -> governance-service.config:


     
entraTenantId : " "

values.yaml -> governance-studio.config:


     
entraTenantId : " "
entraScopes : " openid profile email offline_access api:// /access_as_user "

Update secrets.yaml with the backend credentials.

secrets.yaml -> global.secrets.auth.entra.values:


     
clientId : " "
clientSecret : " "
tenantId : " "

2. Create Graph API Access App Registration

Section titled “2. Create Graph API Access App Registration”
  • Create another app registration: “EQTY Governance Platform Graph API”
  • Navigate to “API permissions”
  • Click “Add a permission”
  • Select “Microsoft Graph” > “Application permissions”
  • Add: User.Read.All, Organization.Read.All
  • Click “Add permissions”
  • Click “Grant admin consent” (requires admin role)
  • Navigate to “Certificates & secrets”
  • Create a client secret
  • Save the secret value

Update secrets.yaml with the Graph API credentials.

secrets.yaml -> global.secrets.auth.entra.values:


     
graphClientId : " "
graphClientSecret : " "

3. Create Governance Worker App Registration

Section titled “3. Create Governance Worker App Registration”
  • Create app registration: “EQTY Governance Worker”
  • Supported account types: “Accounts in this organizational directory only”
  • No redirect URI needed (M2M client)
  • Click “Register”
  • Navigate to “Certificates & secrets”
  • Create a client secret
  • Save the secret value

Generate an encryption key for the worker:

Terminal window

     
openssl rand -base64 32

Update secrets.yaml with the worker credentials.

secrets.yaml -> global.secrets.governanceWorker.values:


     
encryptionKey : " "
clientId : " "
clientSecret : " "
  • Create app registration: “EQTY Governance Studio”
  • Navigate to “Manifest”
  • Find “accessTokenAcceptedVersion” and set it to 2 (for v2.0 tokens)
  • Click “Save”
  • Navigate to “Authentication”
  • Click “Add a platform” > “Single-page application”
  • Redirect URIs: https://
  • Check “ID tokens” under Implicit grant and hybrid flows
  • Check “Access tokens” under Implicit grant and hybrid flows
  • Click “Configure”
  • Navigate to “API permissions”
  • Click “Add a permission”
  • Select “My APIs”
  • Select “EQTY Governance Platform Backend”
  • Check the access_as_user scope
  • Click “Add permissions”
  • Optional: Click “Grant admin consent”

Update values.yaml with the SPA client ID.

values.yaml -> governance-studio.config:


     
entraClientId : " "

Post-Installation: Create Organization and Admin User

Section titled “Post-Installation: Create Organization and Admin User”

After deploying the platform, create an organization and admin user:


    
# Add to values.yaml
entra :
createOrganization : true
organizationName : " your-org-name "
displayName : " Organization Display Name "
createPlatformAdmin : true
platformAdminEmail : " admin@example.onmicrosoft.com " # Must exist in Entra
tenantId : " "

This will:

  • Create an organization in the governance database
  • Look up the Entra user by email via Graph API
  • Create a platform-admin user record linked to the Entra user

Verify the OIDC discovery endpoint:

Terminal window

    
curl " https://login.microsoftonline.com/ /v2.0/.well-known/openid-configuration "

Test token issuance with backend API credentials:

Terminal window

    
curl -X POST " https://login.microsoftonline.com/ /oauth2/v2.0/token " \
-H " Content-Type: application/x-www-form-urlencoded " \
-d " client_id= " \
-d " client_secret= " \
-d " scope=api:// /.default " \
-d " grant_type=client_credentials "

Test Graph API access:

Terminal window

    
curl -X POST " https://login.microsoftonline.com/ /oauth2/v2.0/token " \
-H " Content-Type: application/x-www-form-urlencoded " \
-d " client_id= " \
-d " client_secret= " \
-d " scope=https://graph.microsoft.com/.default " \
-d " grant_type=client_credentials "

If both commands succeed and return access tokens, the Entra configuration is correct.

  • Use Certificate Authentication: For production, consider using certificates instead of client secrets
  • Rotate Secrets: Regularly rotate client secrets (recommended: every 6-12 months)
  • Conditional Access: Implement Conditional Access policies for enhanced security
  • Multi-Factor Authentication: Require MFA for all users
  • Least Privilege: Only grant the minimum required Graph API permissions
  • Monitor Sign-ins: Enable sign-in logs and monitor for suspicious activity
  • App Consent Policies: Configure app consent policies to control which apps users can consent to
  • “AADSTS65001: The user or administrator has not consented to use the application” — Solution: Grant admin consent for API permissions in the Azure Portal
  • “AADSTS700016: Application not found in the directory” — Solution: Verify the client ID is correct and the app registration exists in the tenant
  • “Invalid scope” — Solution: Ensure the entraScopes configuration includes api:// /access_as_user
  • Graph API returns 403 Forbidden — Solution: Verify admin consent was granted for Graph API permissions