Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Date: 2026-01-28
Research Method: Microsoft Learn MCP Server
Status: ✅ Research Complete

Executive Summary

Research confirms that Azure App Registration CAN be automated programmatically using Microsoft Graph API. This enables Encore Health OS to automatically provision Entra ID integration for organizations without manual Azure Portal steps.

Key Findings

1. ✅ Programmatic App Registration is Possible

Microsoft Graph API Endpoint:
POST /applications
Required Permissions:
  • Delegated: Application.ReadWrite.All (requires admin user)
  • Application: Application.ReadWrite.OwnedBy or Application.ReadWrite.All
Capabilities:
  • ✅ Create application registration programmatically
  • ✅ Generate client secret during creation (via passwordCredentials)
  • ✅ Configure API permissions (requiredResourceAccess)
  • ✅ Set redirect URIs, sign-in audience, etc.
Example Request:
POST https://graph.microsoft.com/v1.0/applications
Content-Type: application/json

{
  "displayName": "Encore Health OS - Organization Name",
  "passwordCredentials": [
    {
      "displayName": "Encore Health OS Integration Secret"
    }
  ],
  "requiredResourceAccess": [
    {
      "resourceAppId": "00000003-0000-0000-c000-000000000000", // Microsoft Graph
      "resourceAccess": [
        {
          "id": "df021288-bdef-4463-88db-98f22de89214", // User.ReadWrite.All
          "type": "Role"
        },
        {
          "id": "...", // LicenseAssignment.ReadWrite.All
          "type": "Role"
        }
      ]
    }
  ],
  "signInAudience": "AzureADMyOrg" // Single-tenant
}
Response Includes:
  • id - Application object ID
  • appId - Client ID (application ID)
  • passwordCredentials[0].secretText - Client secret (only shown once!)
Finding: Admin consent CAN be granted programmatically, but requires:
  1. Privileged Role Administrator or Global Administrator role
  2. Microsoft Graph API to grant app roles:
    POST /servicePrincipals/{servicePrincipalId}/appRoleAssignedTo
    
Alternative Approaches: Option A: Programmatic Grant (Requires Admin User)
  • User with admin role calls Microsoft Graph API
  • Grants permissions via AppRoleAssignment.ReadWrite.All
  • Fully automated but requires admin user session
Option B: Admin Consent URL (One-Time Manual Step)
  • Generate admin consent URL: https://login.microsoftonline.com/{tenant}/adminconsent?client_id={appId}
  • Admin visits URL once to grant consent
  • After consent, app can use application permissions
Option C: Hybrid Approach (Recommended)
  • Automate app registration
  • Generate admin consent URL
  • Store URL in organization settings
  • Admin visits URL once to complete setup
  • After consent, full automation enabled

3. Service Principal Creation

Finding: Service principal is automatically created when app registration is created. Microsoft Graph API:
POST /servicePrincipals
{
  "appId": "{application-client-id}"
}
Note: Service principal is typically auto-created, but can be explicitly created if needed.

4. Permission Grant Programmatically

Application Permissions (App Roles):
POST /servicePrincipals/{servicePrincipalId}/appRoleAssignedTo
Content-Type: application/json

{
  "principalId": "{clientServicePrincipalId}",
  "resourceId": "{microsoftGraphServicePrincipalId}",
  "appRoleId": "{permissionId}"
}
Required Permissions for Granting:
  • AppRoleAssignment.ReadWrite.All (delegated, requires admin)
  • Or use admin consent URL (one-time manual step)

5. Multi-Tenant Considerations

Finding: Each organization needs its own app registration in their Entra ID tenant. Architecture Options: Option 1: Per-Organization App Registration (Recommended)
  • Each organization has own app registration in their tenant
  • Encore Health OS stores app credentials per organization
  • Most secure, follows Microsoft best practices
  • Requires organization admin to grant consent
Option 2: Single Multi-Tenant App (Not Recommended)
  • One app registration shared across all organizations
  • Requires complex consent management
  • Security concerns with shared credentials
  • Not suitable for healthcare/PHI scenarios
Recommendation: Use Option 1 (per-organization app registration)

Implementation Strategy

Phase 1: Automated App Registration

Workflow:
  1. Organization admin enables Entra ID integration in Encore Health OS
  2. Encore Health OS calls Microsoft Graph API to create app registration
  3. App registration created with required permissions
  4. Client ID and secret stored in Supabase Vault (encrypted)
  5. Admin consent URL generated and displayed to admin
  6. Admin visits URL to grant consent
  7. After consent, integration is fully active
Edge Function: entra-register-app
  • Creates app registration via Microsoft Graph
  • Configures required permissions
  • Generates client secret
  • Returns admin consent URL
Option A: Automated (If Admin User Available)
  • Use admin user’s session to grant consent programmatically
  • Requires admin to sign in to Encore Health OS with admin role
  • Fully automated after initial admin sign-in
Option B: Manual One-Time Step (Recommended)
  • Generate admin consent URL
  • Display in UI with instructions
  • Admin visits URL once
  • After consent, integration active
Recommendation: Start with Option B (manual consent), add Option A later if needed

Phase 3: User Provisioning

After App Registration Complete:
  • Use stored client ID and secret
  • Authenticate via client credentials flow
  • Create users via POST /users
  • Assign licenses via POST /users/{id}/assignLicense

Security Considerations

1. Credential Storage

  • ✅ Store client secrets in Supabase Vault (encrypted)
  • ✅ Never log secrets or expose in API responses
  • ✅ Rotate secrets periodically (Microsoft Graph supports secret rotation)

2. Permission Scope

  • ✅ Use least-privilege permissions
  • ✅ Only request permissions actually needed
  • ✅ Document why each permission is required
  • ⚠️ Admin consent grants powerful permissions
  • ✅ Require explicit admin action (not automatic)
  • ✅ Log all consent grants for audit trail
  • ✅ Provide clear explanation of permissions requested

4. Multi-Tenant Isolation

  • ✅ Each organization’s credentials isolated
  • ✅ RLS policies enforce tenant isolation
  • ✅ No cross-organization credential access

API Endpoints Required

App Registration

  • POST /applications - Create app registration
  • GET /applications/{id} - Get app details
  • PATCH /applications/{id} - Update app
  • DELETE /applications/{id} - Delete app

Service Principal

  • POST /servicePrincipals - Create service principal (usually auto-created)
  • GET /servicePrincipals/{id} - Get service principal
  • POST /servicePrincipals/{id}/appRoleAssignedTo - Grant app role
  • Admin consent URL: https://login.microsoftonline.com/{tenant}/adminconsent?client_id={appId}
  • Or programmatic: POST /oauth2PermissionGrants (for delegated permissions)

User Provisioning (After Setup)

  • POST /users - Create user
  • POST /users/{id}/assignLicense - Assign license
  • PATCH /users/{id} - Update user
  • DELETE /users/{id} - Delete user

Code Examples

Create App Registration with Secret

// Edge function: entra-register-app
const response = await fetch('https://graph.microsoft.com/v1.0/applications', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${adminToken}`, // Admin user token
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    displayName: `Encore Health OS - ${organizationName}`,
    passwordCredentials: [
      {
        displayName: 'Encore Health OS Integration Secret',
        endDateTime: new Date(Date.now() + 2 * 365 * 24 * 60 * 60 * 1000).toISOString(), // 2 years
      },
    ],
    requiredResourceAccess: [
      {
        resourceAppId: '00000003-0000-0000-c000-000000000000', // Microsoft Graph
        resourceAccess: [
          {
            id: 'df021288-bdef-4463-88db-98f22de89214', // User.ReadWrite.All
            type: 'Role',
          },
          {
            id: '...', // LicenseAssignment.ReadWrite.All
            type: 'Role',
          },
        ],
      },
    ],
    signInAudience: 'AzureADMyOrg', // Single-tenant
  }),
});

const app = await response.json();
// app.appId = Client ID
// app.passwordCredentials[0].secretText = Client Secret (save immediately!)
const adminConsentUrl = `https://login.microsoftonline.com/${tenantId}/adminconsent?client_id=${appId}&redirect_uri=${encodeURIComponent(redirectUri)}`;
// Get Microsoft Graph service principal
const graphSp = await fetch(
  `https://graph.microsoft.com/v1.0/servicePrincipals?$filter=displayName eq 'Microsoft Graph'&$select=id,appRoles`
).then(r => r.json());

// Find permission IDs
const userReadWriteAll = graphSp.value[0].appRoles.find(
  r => r.value === 'User.ReadWrite.All'
);

// Grant app role
await fetch(
  `https://graph.microsoft.com/v1.0/servicePrincipals/${clientServicePrincipalId}/appRoleAssignedTo`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${adminToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      principalId: clientServicePrincipalId,
      resourceId: graphSp.value[0].id,
      appRoleId: userReadWriteAll.id,
    }),
  }
);

Limitations & Constraints

  • ⚠️ Cannot fully automate without admin user session
  • ✅ Can automate app registration
  • ✅ Can generate consent URL
  • ⚠️ Admin must visit URL or grant via API (requires admin session)

2. Permission Requirements

  • ⚠️ Creating app registrations requires Application.ReadWrite.All
  • ⚠️ Granting app roles requires AppRoleAssignment.ReadWrite.All
  • ✅ Both can be delegated permissions (admin user signs in)
  • ⚠️ Or use admin consent URL (one-time manual step)

3. Secret Retrieval

  • ⚠️ Client secret only shown once during creation
  • ✅ Must store immediately in secure vault
  • ⚠️ Cannot retrieve secret later (must create new one)

4. Multi-Tenant Complexity

  • ⚠️ Each organization needs own app registration
  • ✅ Can automate per organization
  • ⚠️ Requires organization’s Entra ID tenant access

Recommendations

  • ✅ Automate app registration
  • ✅ Generate admin consent URL
  • ✅ Store credentials securely
  • ⚠️ Require one-time admin consent (manual step)
  • ✅ After consent, full automation enabled

2. User Experience Flow

  1. Org admin enables Entra ID integration in Encore Health OS
  2. Encore Health OS creates app registration automatically
  3. Display admin consent URL with clear instructions
  4. Admin visits URL and grants consent
  5. Integration active, user provisioning automated

3. Future Enhancement

  • Add option for admin to sign in to Encore Health OS with admin role
  • Use admin session to grant consent programmatically
  • Fully automated flow (no manual URL visit)

References

Microsoft Learn Documentation


Document Version: 1.0
Last Updated: 2026-01-28
Research Method: Microsoft Learn MCP Server