Skip to main content

Docker Compose Deployment with OAuth (ARM64)

This guide describes the additional steps required to secure the ALP-CONNEX Management Platform with Microsoft Entra ID (formerly Azure AD). It builds on the base deployment guide and covers only the additional configurations needed.

After completing these steps, access to the Management UI and the API will be restricted to authenticated users of your organization.

Prerequisites

In addition to the prerequisites from the base deployment guide:

RequirementDescription
Microsoft Entra IDAccess to the Azure Portal with permissions to create App Registrations
HTTPSHTTPS is recommended for production use (e.g. via a reverse proxy)

Step 1 — App Registrations in Entra ID

In the Azure Portal under Microsoft Entra ID → App registrations, two registrations must be created:

API Registration (for the Backend)

  1. Click New registration
  2. Enter a name, e.g. AlpConnex-API
  3. Select Single tenant (this organization only)
  4. Click Register
  5. Navigate to Expose an APIAdd a scope
    • Scope name: access_as_user
    • Who can consent: Admins and users
    • Confirm with Add scope
  6. Note down the following values:
ValueWhere to find
Tenant IDOverview page → Directory (tenant) ID
API Client IDOverview page → Application (client) ID
Application ID URIExpose an API → automatically generated as api://<API_CLIENT_ID>

SPA Registration (for the Frontend)

  1. Click New registration
  2. Enter a name, e.g. AlpConnex-Web
  3. Select Single tenant
  4. Under Redirect URI, select the type Single-page application (SPA) and enter the frontend URL, e.g. http://<HOST_IP>:4200/
  5. Click Register
  6. Navigate to API permissionsAdd a permissionMy APIs → Select AlpConnex-API → Enable access_as_userAdd permissions
  7. Click Grant admin consent
  8. Note down:
ValueWhere to find
SPA Client IDOverview page → Application (client) ID

Step 2 — Additional Environment Variables (.env)

Add the following variables to the .env file from the base deployment guide:

# ──────────────────────────────────────────
# OAuth / Microsoft Entra ID
# ──────────────────────────────────────────
# All values come from the App Registrations in the Azure Portal (see Step 1).

# Tenant ID — Directory (tenant) ID from the Entra ID overview
AZURE_TENANT_ID=00000000-0000-0000-0000-000000000000

# Client ID of the API registration (Backend)
AZURE_API_CLIENT_ID=00000000-0000-0000-0000-000000000000

# Client ID of the SPA registration (Frontend)
AZURE_SPA_CLIENT_ID=00000000-0000-0000-0000-000000000000

# ──────────────────────────────────────────
# Backend — AzureAd Configuration
# ──────────────────────────────────────────
# Microsoft login endpoint (always the same, only change for national cloud deployments)
AZUREAD_INSTANCE=https://login.microsoftonline.com/

# Audience URI — derived from the API Client ID
AZUREAD_AUDIENCE=api://00000000-0000-0000-0000-000000000000

# Default scope for the OpenAPI documentation
AZUREAD_SCOPES=api://00000000-0000-0000-0000-000000000000/.default

# Redirect URI for the Scalar API Explorer
# Replace <HOST_IP> with your host IP (derived from HOST_IP)
SCALAR_REDIRECT_URI=http://192.168.1.100:8080/scalar/oauth2-redirect

# ──────────────────────────────────────────
# Frontend — MSAL Configuration
# ──────────────────────────────────────────
# Authority URL — login endpoint + Tenant ID
MSAL_AUTHORITY=https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000

# Scope for API access
MSAL_SCOPE=api://00000000-0000-0000-0000-000000000000/access_as_user

Important: Replace all placeholders (00000000-...) with the actual values from your App Registrations. The values for AZUREAD_AUDIENCE, AZUREAD_SCOPES, MSAL_AUTHORITY, and MSAL_SCOPE are composed of the Tenant ID and API Client ID.

Step 3 — Docker Compose Changes

Modify the backend and frontend services in your docker-compose.yaml. The remaining services (database, valkey, iec104-server, mqtt-client, mosquitto) remain unchanged.

Backend — Additional Environment Variables

Add the following environment variables to the backend service:

  backend:
image: registry.alpscale.io/alp-connex/alp-connex-management-api:${TAG_MANAGEMENT}
environment:
ASPNETCORE_URLS: http://+:8080
ASPNETCORE_ENVIRONMENT: Production
ConnectionStrings__alpconnexdb: >-
Host=database;Port=5432;Database=${POSTGRES_DB};
Username=${POSTGRES_USER};Password=${POSTGRES_PASSWORD}
ConnectionStrings__redis: valkey:6379
Cors__AllowedOrigins: "http://${HOST_IP}:4200"

# ── OAuth / Entra ID ──────────────────
AzureAd__Instance: "${AZUREAD_INSTANCE}"
AzureAd__TenantId: "${AZURE_TENANT_ID}"
AzureAd__ClientId: "${AZURE_API_CLIENT_ID}"
AzureAd__Audience: "${AZUREAD_AUDIENCE}"
AzureAd__Scopes: "${AZUREAD_SCOPES}"
Scalar__ClientId: "${AZURE_SPA_CLIENT_ID}"
Scalar__RedirectUri: "${SCALAR_REDIRECT_URI}"
ports:
- "8080:8080"
depends_on:
database:
condition: service_healthy
valkey:
condition: service_healthy
restart: unless-stopped
networks:
- connector-net
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

Frontend — Additional Environment Variables

Add the OAuth variables to the frontend service:

  frontend:
image: registry.alpscale.io/alp-connex/alp-connex-management-frontend:${TAG_MANAGEMENT}
ports:
- "4200:8080"
environment:
API_URL: "http://${HOST_IP}:8080"

# ── OAuth / Entra ID ──────────────────
MSAL_CLIENT_ID: "${AZURE_SPA_CLIENT_ID}"
MSAL_AUTHORITY: "${MSAL_AUTHORITY}"
MSAL_SCOPE: "${MSAL_SCOPE}"
depends_on:
backend:
condition: service_started
restart: unless-stopped
networks:
- connector-net
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

Overview of All OAuth Parameters

Variable in .envDescriptionSource
AZURE_TENANT_IDTenant ID of your organizationEntra ID → Overview → Directory (tenant) ID
AZURE_API_CLIENT_IDClient ID of the API App RegistrationAPI Registration → Application (client) ID
AZURE_SPA_CLIENT_IDClient ID of the SPA App RegistrationSPA Registration → Application (client) ID
AZUREAD_INSTANCEMicrosoft login endpointAlways https://login.microsoftonline.com/
AZUREAD_AUDIENCEAudience URI of the APIapi://<AZURE_API_CLIENT_ID>
AZUREAD_SCOPESDefault scope for OpenAPI docsapi://<AZURE_API_CLIENT_ID>/.default
SCALAR_REDIRECT_URIOAuth2 redirect for Scalar API Explorerhttp://<HOST_IP>:8080/scalar/oauth2-redirect
MSAL_AUTHORITYLogin endpoint + Tenant IDhttps://login.microsoftonline.com/<TENANT_ID>
MSAL_SCOPEScope for API access (Frontend)api://<AZURE_API_CLIENT_ID>/access_as_user

Start and Verify

Start the stack as described in the base deployment guide:

docker compose up -d
docker compose logs -f

Test Login

  1. Open http://<HOST_IP>:4200 in your browser
  2. You will be automatically redirected to the Microsoft sign-in page
  3. Sign in with a user from your organization
  4. After successful sign-in, you will be taken to the Management UI

Test API Explorer

  1. Open http://<HOST_IP>:8080/scalar/v1 in your browser
  2. Click Authorize
  3. Sign in — after that, API requests can be sent directly from the Explorer

Troubleshooting

SymptomCauseSolution
Redirect loop after loginRedirect URI mismatchIn the SPA Registration under Authentication, verify that http://<HOST_IP>:4200/ is entered exactly (including the trailing /)
AADSTS700054 — Response type not supportedWrong Redirect URI typeRedirect URI must be of type SPA, not Web
401 Unauthorized on API requestsToken validation failedCheck AZURE_API_CLIENT_ID and AZURE_TENANT_ID in the .env file
CORS error in browserFrontend URL not in Cors__AllowedOriginsHOST_IP in .env must match the IP/hostname actually used in the browser
Login works but API access is deniedMissing API Permission or no Admin ConsentIn the Azure Portal under the SPA Registration → API permissions, verify that access_as_user has the status Granted

This guide supplements the base deployment guide. For connector-specific configuration, see the IEC 104 Connector and MQTT Connector documentation.