Files
the_order/docs/integrations/MICROSOFT_ENTRA_VERIFIEDID.md
defiQUG 92cc41d26d Add Legal Office seal and complete Azure CDN deployment
- Add Legal Office of the Master seal (SVG design with Maltese Cross, scales of justice, legal scroll)
- Create legal-office-manifest-template.json for Legal Office credentials
- Update SEAL_MAPPING.md and DESIGN_GUIDE.md with Legal Office seal documentation
- Complete Azure CDN infrastructure deployment:
  - Resource group, storage account, and container created
  - 17 PNG seal files uploaded to Azure Blob Storage
  - All manifest templates updated with Azure URLs
  - Configuration files generated (azure-cdn-config.env)
- Add comprehensive Azure CDN setup scripts and documentation
- Fix manifest URL generation to prevent double slashes
- Verify all seals accessible via HTTPS
2025-11-12 22:03:42 -08:00

13 KiB

Microsoft Entra VerifiedID Integration

This document describes the integration with Microsoft Entra VerifiedID for verifiable credential issuance and verification.

Overview

The Order integrates with Microsoft Entra VerifiedID to:

  • Issue verifiable credentials through Microsoft's managed service
  • Verify verifiable credentials issued by Microsoft Entra VerifiedID
  • Bridge eIDAS verification with Microsoft Entra VerifiedID credential issuance
  • Integrate with Azure Logic Apps for workflow orchestration

Architecture

┌─────────────┐     ┌──────────────┐     ┌─────────────────────┐
│   Client    │────▶│ Identity     │────▶│ Entra VerifiedID    │
│             │     │ Service      │     │ API                 │
└─────────────┘     └──────────────┘     └─────────────────────┘
                            │
                            │
                            ▼
                    ┌──────────────┐
                    │ eIDAS Bridge │
                    │              │
                    │ 1. Verify    │
                    │ 2. Issue VC  │
                    └──────────────┘
                            │
                            ▼
                    ┌──────────────┐
                    │ Logic Apps   │
                    │ (Optional)   │
                    └──────────────┘

Setup

1. Microsoft Entra VerifiedID Configuration

  1. Create Azure AD App Registration

    • Go to Azure Portal → Azure Active Directory → App registrations
    • Create a new registration
    • Note the Application (client) ID and Directory (tenant) ID
  2. Configure API Permissions

    • Add permission: Verifiable Credentials Service - VerifiableCredential.Create.All
    • Add permission: Verifiable Credentials Service - VerifiableCredential.Verify.All
    • Grant admin consent
  3. Create Client Secret

    • Go to Certificates & secrets
    • Create a new client secret
    • Note the secret value (it's only shown once)
  4. Create Credential Manifest

    • Go to Azure Portal → Verified ID
    • Create a new credential manifest
    • Note the Manifest ID

2. Environment Variables

Add the following to your .env file:

# Microsoft Entra VerifiedID
ENTRA_TENANT_ID=your-tenant-id
ENTRA_CLIENT_ID=your-client-id
ENTRA_CLIENT_SECRET=your-client-secret
ENTRA_CREDENTIAL_MANIFEST_ID=your-manifest-id

# eIDAS (for bridge functionality)
EIDAS_PROVIDER_URL=https://your-eidas-provider.com
EIDAS_API_KEY=your-eidas-api-key

# Azure Logic Apps (optional)
AZURE_LOGIC_APPS_WORKFLOW_URL=https://your-logic-app.azurewebsites.net
AZURE_LOGIC_APPS_ACCESS_KEY=your-access-key
AZURE_LOGIC_APPS_MANAGED_IDENTITY_CLIENT_ID=your-managed-identity-client-id

API Endpoints

Issue Credential via Entra VerifiedID

POST /vc/issue/entra

Request body:

{
  "claims": {
    "email": "user@example.com",
    "name": "John Doe",
    "role": "member"
  },
  "pin": "1234",
  "callbackUrl": "https://your-app.com/callback"
}

Response:

{
  "requestId": "abc123",
  "url": "https://verifiedid.did.msidentity.com/...",
  "qrCode": "data:image/png;base64,...",
  "expiry": 3600
}

Verify Credential via Entra VerifiedID

POST /vc/verify/entra

Request body:

{
  "credential": {
    "id": "vc:123",
    "type": ["VerifiableCredential", "IdentityCredential"],
    "issuer": "did:web:...",
    "credentialSubject": { ... },
    "proof": { ... }
  }
}

Response:

{
  "verified": true
}

eIDAS Verification with Entra Issuance

POST /eidas/verify-and-issue

This endpoint:

  1. Verifies the eIDAS signature
  2. Issues a verifiable credential via Microsoft Entra VerifiedID
  3. Optionally triggers Azure Logic Apps workflow

Request body:

{
  "document": "base64-encoded-document",
  "userId": "user-123",
  "userEmail": "user@example.com",
  "pin": "1234"
}

Response:

{
  "verified": true,
  "credentialRequest": {
    "requestId": "abc123",
    "url": "https://verifiedid.did.msidentity.com/...",
    "qrCode": "data:image/png;base64,..."
  }
}

Usage Examples

TypeScript Client

import { EntraVerifiedIDClient } from '@the-order/auth';

const client = new EntraVerifiedIDClient({
  tenantId: process.env.ENTRA_TENANT_ID!,
  clientId: process.env.ENTRA_CLIENT_ID!,
  clientSecret: process.env.ENTRA_CLIENT_SECRET!,
  credentialManifestId: process.env.ENTRA_CREDENTIAL_MANIFEST_ID!,
});

// Issue credential
const credential = await client.issueCredential({
  claims: {
    email: 'user@example.com',
    name: 'John Doe',
  },
  pin: '1234',
});

// Verify credential
const verified = await client.verifyCredential(credential);

eIDAS Bridge

import { EIDASToEntraBridge } from '@the-order/auth';

const bridge = new EIDASToEntraBridge({
  entraVerifiedID: {
    tenantId: process.env.ENTRA_TENANT_ID!,
    clientId: process.env.ENTRA_CLIENT_ID!,
    clientSecret: process.env.ENTRA_CLIENT_SECRET!,
    credentialManifestId: process.env.ENTRA_CREDENTIAL_MANIFEST_ID!,
  },
  eidas: {
    providerUrl: process.env.EIDAS_PROVIDER_URL!,
    apiKey: process.env.EIDAS_API_KEY!,
  },
});

// Verify eIDAS and issue credential
const result = await bridge.verifyAndIssue(
  document,
  userId,
  userEmail,
  pin
);

Azure Logic Apps Integration

The integration supports optional Azure Logic Apps workflows for:

  • Document processing
  • eIDAS verification workflows
  • VC issuance workflows

Logic App Workflow Example

{
  "definition": {
    "triggers": {
      "eidas-verification": {
        "type": "Request",
        "inputs": {
          "schema": {
            "type": "object",
            "properties": {
              "documentId": { "type": "string" },
              "userId": { "type": "string" },
              "eidasProviderUrl": { "type": "string" }
            }
          }
        }
      }
    },
    "actions": {
      "process-eidas": {
        "type": "Http",
        "inputs": {
          "method": "POST",
          "uri": "@{triggerBody()['eidasProviderUrl']}/verify",
          "body": {
            "documentId": "@{triggerBody()['documentId']}"
          }
        }
      }
    }
  }
}

Security Considerations

  1. Client Secrets: Store securely in Azure Key Vault or similar
  2. Access Tokens: Automatically cached and refreshed
  3. PIN Protection: Optional PIN for credential issuance
  4. Certificate Validation: Full certificate chain validation for eIDAS
  5. Managed Identity: Use Azure Managed Identity when possible instead of client secrets

Troubleshooting

Common Issues

  1. "Failed to get access token"

    • Check tenant ID, client ID, and client secret
    • Verify API permissions are granted
    • Check that admin consent is provided
  2. "Credential manifest ID is required"

    • Ensure ENTRA_CREDENTIAL_MANIFEST_ID is set
    • Verify the manifest exists in Azure Portal
  3. "eIDAS verification failed"

    • Check eIDAS provider URL and API key
    • Verify network connectivity to eIDAS provider
    • Check certificate validity

Enhanced Features

Retry Logic

The integration includes automatic retry logic for transient failures:

  • Configurable retries: Default 3 retries with exponential backoff
  • Retryable errors: 429 (rate limit), 500, 502, 503, 504
  • Backoff strategy: Exponential backoff with configurable delays
import { EnhancedEntraVerifiedIDClient } from '@the-order/auth';

const client = new EnhancedEntraVerifiedIDClient(config, {
  maxRetries: 3,
  initialDelayMs: 1000,
  maxDelayMs: 10000,
  backoffMultiplier: 2,
});

Multi-Manifest Support

Support for multiple credential manifests:

# Environment variable (JSON format)
ENTRA_MANIFESTS='{"default":"manifest-id-1","diplomatic":"manifest-id-2","judicial":"manifest-id-3"}'
// Issue credential with specific manifest
await client.issueCredential({
  claims: { ... },
  manifestName: 'diplomatic', // Uses diplomatic manifest
});

Webhook/Callback Handling

Automatic webhook processing for issuance status updates:

POST /vc/entra/webhook

The webhook endpoint:

  • Receives status updates from Entra VerifiedID
  • Updates credential status in database
  • Publishes events for downstream processing
  • Records metrics for monitoring

GET /vc/entra/status/:requestId

Manual status check endpoint (polling fallback).

Rate Limiting

Entra-specific rate limiting to prevent API quota exhaustion:

# Environment variables
ENTRA_RATE_LIMIT_ISSUANCE=10        # Per minute
ENTRA_RATE_LIMIT_VERIFICATION=20    # Per minute
ENTRA_RATE_LIMIT_STATUS_CHECK=30    # Per minute
ENTRA_RATE_LIMIT_GLOBAL=50          # Per minute

Rate limits are applied automatically to all Entra endpoints.

Monitoring & Metrics

Comprehensive Prometheus metrics:

  • entra_api_requests_total - Total API requests by operation and status
  • entra_api_request_duration_seconds - Request duration histogram
  • entra_credentials_issued_total - Credentials issued by manifest and status
  • entra_issuance_duration_seconds - Issuance duration histogram
  • entra_credentials_verified_total - Verification results
  • entra_webhooks_received_total - Webhook events received
  • entra_active_requests - Currently active requests gauge

Access metrics at /metrics endpoint.

Automated Setup Script

Use the automated setup script for Azure configuration:

./scripts/deploy/setup-entra-automated.sh

The script:

  • Creates Azure AD App Registration
  • Configures API permissions
  • Creates client secrets
  • Stores secrets in Azure Key Vault
  • Generates environment file template

Testing

Unit Tests

cd packages/auth
pnpm test entra-verifiedid.test.ts

Integration Tests

Integration tests verify:

  • Token management and caching
  • Credential issuance flow
  • Retry logic on failures
  • Multi-manifest support
  • Webhook processing

End-to-End Testing

  1. Set up test environment variables
  2. Create test credential manifest in Azure
  3. Run E2E test suite:
    pnpm test:e2e entra
    

Deployment

Automated Deployment

  1. Run setup script:

    ./scripts/deploy/setup-entra-automated.sh
    
  2. Update environment variables in all environments

  3. Configure webhook URLs in Entra VerifiedID:

    • Production: https://api.theorder.org/vc/entra/webhook
    • Staging: https://api-staging.theorder.org/vc/entra/webhook
  4. Verify integration:

    curl -X POST https://api.theorder.org/vc/issue/entra \
      -H "Content-Type: application/json" \
      -d '{"claims": {"email": "test@example.com"}}'
    

Manual Deployment

Follow the manual steps in docs/deployment/DEPLOYMENT_STEPS_SUMMARY.md Phase 3.

Best Practices

  1. Use Enhanced Client: Always use EnhancedEntraVerifiedIDClient for production
  2. Monitor Metrics: Set up alerts on error rates and latency
  3. Configure Rate Limits: Adjust based on your Entra API quota
  4. Webhook Security: Validate webhook signatures if Entra provides them
  5. Multi-Manifest: Use manifest names for different credential types
  6. Error Handling: Implement proper error handling and logging
  7. Retry Configuration: Tune retry settings based on your needs

Credential Images

Image Format Support

Yes, SVG files can be used! The integration includes automatic SVG-to-PNG conversion for Entra VerifiedID compatibility.

Officially Supported Formats

  • PNG (Recommended)
  • JPG/JPEG
  • BMP
  • SVG (with automatic conversion)

Using SVG Files

  1. Automatic Conversion (Recommended):

    import { prepareCredentialImage } from '@the-order/auth';
    
    const image = await prepareCredentialImage(svgData, 'svg');
    // Automatically converts to PNG
    
  2. Manual Conversion:

    ./scripts/tools/convert-svg-to-png.sh logo.svg logo.png 200 200
    
  3. Prepare All Images:

    ./scripts/tools/prepare-credential-images.sh
    

See ENTRA_CREDENTIAL_IMAGES.md for detailed image guide.

References