Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
160 lines
5.4 KiB
Markdown
160 lines
5.4 KiB
Markdown
# Microsoft Entra Integration (EE) — Phase 1 Setup and Usage
|
|
|
|
## Scope
|
|
|
|
This guide documents Enterprise Edition Phase 1 of Microsoft Entra integration:
|
|
|
|
- Partner-level connection (`direct` Microsoft OAuth or `cipp` API token).
|
|
- Managed tenant discovery and tenant-to-client mapping.
|
|
- Initial/manual/recurring contact sync through Temporal workflows.
|
|
- Additive, non-destructive sync behavior.
|
|
|
|
All user-visible Entra surfaces are feature-flag gated.
|
|
|
|
## Prerequisites
|
|
|
|
- Edition: `NEXT_PUBLIC_EDITION=enterprise`
|
|
- Internal MSP user account (client portal users are denied)
|
|
- RBAC:
|
|
- View endpoints/actions: `system_settings.read`
|
|
- Connect/map/sync/resolve endpoints/actions: `system_settings.update`
|
|
|
|
## Connection Path Decision Guide
|
|
|
|
Choose one connection type per tenant:
|
|
|
|
1. `direct` (Microsoft OAuth)
|
|
- Use this when you want first-party delegated auth directly against Microsoft Graph.
|
|
- Requires Microsoft OAuth app credentials (tenant secret, env, or app secret fallback).
|
|
- Best when you control OAuth app registration and consent flow.
|
|
|
|
2. `cipp` (CIPP API)
|
|
- Use this when CIPP is your operational control plane for managed tenant/user enumeration.
|
|
- Requires CIPP base URL and API token.
|
|
- Best when your MSP already uses CIPP and wants to reuse that API boundary.
|
|
|
|
Switching connection types automatically clears stale credentials for the previous type.
|
|
|
|
## Required Secret Names
|
|
|
|
Entra secret constants are defined in `ee/server/src/lib/integrations/entra/secrets.ts`.
|
|
|
|
Shared Microsoft credential keys:
|
|
|
|
- `microsoft_client_id`
|
|
- `microsoft_client_secret`
|
|
- `microsoft_tenant_id`
|
|
|
|
Direct Entra token keys:
|
|
|
|
- `entra_direct_access_token`
|
|
- `entra_direct_refresh_token`
|
|
- `entra_direct_token_expires_at`
|
|
- `entra_direct_partner_tenant_id`
|
|
- `entra_direct_token_scope`
|
|
|
|
CIPP keys:
|
|
|
|
- `entra_cipp_base_url`
|
|
- `entra_cipp_api_token`
|
|
|
|
Secret provider compatibility:
|
|
|
|
- All Entra credentials/tokens are resolved through `getSecretProviderInstance()`.
|
|
- Tenant secrets support env/filesystem/vault provider chains (no plaintext token storage requirement in DB).
|
|
|
|
## Credential Resolution Order (Direct)
|
|
|
|
For direct Microsoft OAuth credentials, resolution order is:
|
|
|
|
1. Tenant secrets (`microsoft_client_id` + `microsoft_client_secret`, optional `microsoft_tenant_id`)
|
|
2. Environment variables (`MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET`, `MICROSOFT_TENANT_ID`)
|
|
3. App secrets (`MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET`, `MICROSOFT_TENANT_ID`)
|
|
|
|
## Feature Flags (Phase 1)
|
|
|
|
Required flags:
|
|
|
|
- `entra-integration-ui`
|
|
- `entra-integration-client-sync-action`
|
|
- `entra-integration-cipp`
|
|
- `entra-integration-field-sync`
|
|
- `entra-integration-ambiguous-queue`
|
|
|
|
Create/check default Phase 1 flag definitions through platform feature flag API:
|
|
|
|
```bash
|
|
curl -X POST \
|
|
"$BASE_URL/api/v1/platform-feature-flags" \
|
|
-H "Content-Type: application/json" \
|
|
-H "x-api-key: $MASTER_TENANT_API_KEY" \
|
|
-d '{"__action":"ensure_entra_phase1_flags"}'
|
|
```
|
|
|
|
Enable tenant targeting for a flag:
|
|
|
|
```bash
|
|
curl -X POST \
|
|
"$BASE_URL/api/v1/platform-feature-flags/$FLAG_ID/tenants" \
|
|
-H "Content-Type: application/json" \
|
|
-H "x-api-key: $MASTER_TENANT_API_KEY" \
|
|
-d '{"__action":"add","tenantId":"TENANT_UUID"}'
|
|
```
|
|
|
|
## Setup Workflow (Wizard)
|
|
|
|
The settings wizard follows four explicit write-gated steps:
|
|
|
|
1. Connect
|
|
- Choose `direct` or `cipp`.
|
|
- For direct: start OAuth, complete callback, validate connection.
|
|
- For CIPP: save base URL/token, validate tenant list access.
|
|
|
|
2. Discover Tenants
|
|
- Run discovery to populate managed Entra tenants.
|
|
|
|
3. Map Tenants to Clients
|
|
- Review `auto-matched`, `needs review`, and skipped rows.
|
|
- Confirm mappings explicitly (no hidden writes during preview).
|
|
|
|
4. Initial Sync
|
|
- Run initial sync once at least one mapping is confirmed.
|
|
|
|
## Sync Behavior and Safety Rules
|
|
|
|
Default behavior is additive/linking, not destructive:
|
|
|
|
- Email-normalized match links to existing contacts.
|
|
- No match creates new contact under mapped client.
|
|
- Multiple plausible matches queue reconciliation items.
|
|
- Name-only similarity does not auto-link.
|
|
- Sync never deletes contacts.
|
|
- Disabled/deleted upstream Entra users mark linked contacts inactive.
|
|
|
|
Field overwrite controls:
|
|
|
|
- Only fields enabled in `entra_sync_settings.field_sync_config` may overwrite local contact values.
|
|
- If a field toggle is off, local value remains authoritative.
|
|
|
|
## Manual Sync Paths
|
|
|
|
- Settings: `Sync All Tenants Now` starts all-tenant workflow.
|
|
- Client details: `Sync Entra Now` starts single-client workflow for mapped client.
|
|
- Mapping confirm flow can optionally start initial sync immediately.
|
|
|
|
All sync execution paths run via Temporal workflows and persist run + per-tenant results.
|
|
|
|
## Rollout Order (Recommended)
|
|
|
|
1. Deploy schema + EE code with all Entra flags disabled.
|
|
2. Ensure Phase 1 flags exist using `ensure_entra_phase1_flags`.
|
|
3. Enable `entra-integration-ui` for internal test tenants only.
|
|
4. For test tenants needing CIPP, enable `entra-integration-cipp`.
|
|
5. Validate discovery and mapping quality on pilot tenants.
|
|
6. Enable `entra-integration-field-sync` only after field overwrite policy is approved.
|
|
7. Enable `entra-integration-ambiguous-queue` for support teams handling reconciliation.
|
|
8. Enable `entra-integration-client-sync-action` after mapping/sync operations are stable.
|
|
9. Expand tenant targeting incrementally.
|
|
|
|
Turning UI flags off hides Entra surfaces immediately without deleting connection/mapping/run history data.
|