Skip to main content
Version: Next

Authentication

EAS's only method of authentication is through Microsoft EntraID (formally Microsoft Active Directory). This document covers the implementation and deployment models

Implementation

EAS implements the OpenID Connect (OIDC) protocol where JWT tokens issued by an IdP are validated using published JWKS keys. The frontend implements the OAuth 2.0 Authorization code flow with PKCE to login the user and the resulting JWT is sent to EAS in every request. Both the frontend and EAS leave it to the IdP to perform any custom authentication rules such as MFA and session timeouts.

Deployment Models

There are three deployment models, each with their own tradeoffs.

Zepben Managed

This deployment methodology involves Zepben setting a up a dedicated EntraID tenant for your deployment. Zepben will then configure applications to use this tenant as its authentication provider. This is a fast, low overhead way of getting your Zepben platform setup.

With this deployment style:

  • User additions/removes/role assignemnts will be managed by Zepben support
  • Users will have a separate own username and password to login, password resets will be conducted by Zepben support
    • If the email addresses belong to their own EntraID tenant, then EntraID B2B Collaboration will be used where users use the source tenant credentials to login
  • Multi-factor authentication is used and resets are managed by Zepben support
  • There are no customizations available, eg. Geo-location rules, IP rules etc.

Customer Managed

This deployment methodology allow customers to bring your own EntraID tenant for authentication. Zepben will integrate our applications to allow logins from your tenant using EntraID Single Sign On (SSO).

With this deployment style:

  • Users additions/remove/role assignments are managed by the Customer
  • Customer will manage user password/MFA resets
  • Custom authentication rules using EntraID Conditional Access can be used to control authentication requirements
  • Zepben will continue to manage application configuration in our own tenant

Setup Process

  1. Customer will provide Zepben with their EntraID tenant ID
  2. Zepben will provision EntraID Application registrations as multi tenant applications
  3. Zepben will provide a set of Enterprise Application client ids to Customer
  4. Customer will add each Enterprise Application to their tenant
  5. Customer will grant admin consent for all roles in each Enterprise Application
  6. Zepben will configure applications to trust logins from customer tenant and provide customer platform URL
  7. Customer can assign users to application roles
  8. Users can now login to the Zepben platform

Self-Hosted

This deployment model is only applicable if you are self hosting all of EAS and EWB. This deployment model is similar to the customer managed version except with the added responsbility of managing the servers and the EntraID application registrations.

Setup Process

This process require setting up the EAS and EWB applications in Microsoft EntraID. The Powershell script below is an example script that can be used to achieve this.

The script:

  • Creates the EAS and EWB applications
  • Creates Service Principals for each applications
  • Sets EAS as an SPA application
  • Creates the roles / OAuth scopes required in each application
  • Grants EAS access to retrieve data from EWB
  • Grant both applications access to Microsoft Graph user details
  • Finally, prints out the JSON snippets required to configure each application
<#
Prerequisites:
- Install-Module Microsoft.Graph -Scope CurrentUser
- You must sign in with an account that has Application.ReadWrite.All (or Global Admin) to create app registrations.
- Run: Connect-MgGraph -Scopes "Application.ReadWrite.All","Application.Read.All","Directory.ReadWrite.All"
#>

$easDisplayName = "EAS-test6"
$ewbDisplayName = "EWB-test6"

$spaRedirectUris = @(
"https://your-production-app.example.com"
)

$easRoleNames = @(
"SUPER_ADMIN",
"EWB_ADMIN",
"TIMESERIES_MODELLER",
"MODELLER",
"DEVELOPER",
"MAP_VIEWER",
"EWB_UPDATER",
"METRICS_VIEWER",
"NETWORK_MODEL_EXECUTOR",
"INTEGRATION_ADMIN",
"EWB_CUSTOMER_VIEWER",
"EWB_DIAGRAM_VIEWER",
"CUSTOMER_PII_READ",
"CUSTOMER_NON_PII_READ",
"CUSTOMER_PII_EXPORT",
"CUSTOMER_NON_PII_EXPORT"
)

$ewbRoleNames = @(
"read:ewb",
"read:customer",
"read:diagram"
)

$msGraphAppId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
$userReadScopeId = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read (delegated)

Write-Host "Connecting to Microsoft Graph. You must consent with a user who has permission to create apps..." -ForegroundColor Cyan
Connect-MgGraph -Scopes "Application.ReadWrite.All","Directory.ReadWrite.All"

$tenantId = (Get-MgContext).TenantId

function New-GuidString { [Guid]::NewGuid().ToString() }

function New-Roles {
param (
[Parameter(Mandatory = $true)]
[string[]]$Roles
)

$appRoles = @()
$oauth2PermissionScopes = @()

foreach ($r in $Roles) {
$roleId = New-GuidString

$appRole = @{
Id = $roleId
AllowedMemberTypes = @("User","Application")
DisplayName = $r
Description = $r
Value = $r
IsEnabled = $true
}
$appRoles += $appRole

$scope = @{
Id = $roleId
AdminConsentDisplayName = $r
AdminConsentDescription = $r
Type = "User"
IsEnabled = $true
UserConsentDisplayName = ""
UserConsentDescription = ""
Value = $r
}
$oauth2PermissionScopes += $scope
}

return $appRoles, $oauth2PermissionScopes
}

$requiredResourceAccess = @(
@{
ResourceAppId = $msGraphAppId
ResourceAccess = @(
@{
Id = $userReadScopeId
Type = "Scope"
}
)
}
)

# ====== EAS

Write-Host "Creating EAS application registration '$easDisplayName'..." -ForegroundColor Cyan

$spaObject = @{ RedirectUris = $spaRedirectUris }

$easRoles, $easOAuth = New-Roles -Roles $easRoleNames
$easApi = @{
RequestedAccessTokenVersion = 2
Oauth2PermissionScopes = $easOAuth
}

$eas = New-MgApplication -DisplayName $easDisplayName `
-AppRoles $easRoles `
-Api $easApi `
-Spa $spaObject `
-RequiredResourceAccess $requiredResourceAccess

if ($null -eq $eas) {
throw "Failed to create EAS application."
}

Write-Host "Application created. appId (clientId): $($eas.AppId)" -ForegroundColor Green
Write-Host "Creating EAS service principal for the app..." -ForegroundColor Cyan

$easSp = New-MgServicePrincipal -AppId $eas.AppId
Write-Host "Service principal created: objectId = $($easSp.Id)" -ForegroundColor Green

# ======= EWB

Write-Host "Creating EWB application registration '$ewbDisplayName'..." -ForegroundColor Cyan

$ewbRoles, $ewbOAuth = New-Roles -Roles $ewbRoleNames
$ewbApi = @{
RequestedAccessTokenVersion = 2
Oauth2PermissionScopes = $ewbOAuth
}

$ewb = New-MgApplication -DisplayName $ewbDisplayName `
-AppRoles $ewbRoles `
-Api $ewbApi `
-RequiredResourceAccess $requiredResourceAccess

if ($null -eq $ewb) {
throw "Failed to create EWB application."
}

Write-Host "Application created. appId (clientId): $($ewb.AppId)" -ForegroundColor Green
Write-Host "Creating EAS service principal for the app..." -ForegroundColor Cyan

$ewbSp = New-MgServicePrincipal -AppId $ewb.AppId
Write-Host "Service principal created: objectId = $($ewbSp.Id)" -ForegroundColor Green

# ======= Assign roles

foreach ($r in $ewbRoles) {
New-MgServicePrincipalAppRoleAssignment `
-ServicePrincipalId $easSp.Id `
-PrincipalId $easSp.Id `
-ResourceId $ewbSp.Id `
-AppRoleId $r.Id
}

# ======= Final Config

$frontend = @{
authType = "entraid"
domain = "https://login.microsoftonline.com/${tenantId}/v2.0"
clientId = $eas.AppId
audience = $eas.AppId
}

$trustedIssuers = @(
"https://login.microsoftonline.com/${tenantId}/v2.0"
) + $spaRedirectUris

$easConfig = @{
method = "entraid"
audience = $eas.AppId
trustedIssuers = $trustedIssuers
}

$ewbConfig = @{
authType = "entraid"
audience = $ewb.AppId
trustedIssuers = $trustedIssuers
}

Write-Host "EAS Frontend Config" -ForegroundColor Green
Write-Host (ConvertTo-Json -InputObject $frontend)

Write-Host "EAS Auth Config" -ForegroundColor Green
Write-Host (ConvertTo-Json -InputObject $easConfig)

Write-Host "EWB Auth Config" -ForegroundColor Green
Write-Host (ConvertTo-Json -InputObject $ewbConfig)

The output of the above script will look something like this.

EAS Frontend Config
{
"audience": "fce16e12-2eaa-4f5c-866b-bd4d08de23ea",
"domain": "https://login.microsoftonline.com/d884eee1-c96f-4701-8103-2ba4346db120/v2.0",
"clientId": "fce16e12-2eaa-4f5c-866b-bd4d08de23ea",
"authType": "entraid"
}
EAS Auth Config
{
"trustedIssuers": [
"https://login.microsoftonline.com/d884eee1-c96f-4701-8103-2ba4346db120/v2.0",
"https://your-production-app.example.com"
],
"audience": "fce16e12-2eaa-4f5c-866b-bd4d08de23ea",
"method": "entraid"
}
EWB Auth Config
{
"audience": "6744e920-f146-4049-b80f-8e17888a3f7b",
"trustedIssuers": [
"https://login.microsoftonline.com/d884eee1-c96f-4701-8103-2ba4346db120/v2.0",
"https://your-production-app.example.com"
],
"authType": "entraid"
}

Using the above output, refer to the configuration documentation in the relevant applications to configure authentication