A proof-of-concept platform that enables a consortium of institutions to discover and share Microsoft Purview Data Products across organizational boundaries using OneLake shortcuts and Microsoft Fabric.
┌─────────────────────────┐ ┌──────────────────────────┐
│ React SPA (Vite) │────▶│ ASP.NET Core 8 Web API │
│ Fluent UI v9 │ │ Microsoft.Identity.Web │
│ MSAL.js │ │ Serilog │
│ port 5173 │ │ port 7001 │
└─────────────────────────┘ └──────────┬───────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ Azure SQL DB │ │ Azure AI Search │ │ Purview APIs │
│ EF Core 8 │ │ Catalog index │ │ Data Products │
└────────────────┘ └───────────────────┘ └──────────────────┘
┌──────────────────────────┐
│ Azure Functions v4 │
│ Timer: every 6 hours │
│ HTTP: on-demand scan │
└──────────────────────────┘
| Project | Type | Purpose |
|---|---|---|
PurviewConsortium.Core |
Class Library | Domain entities, enums, interfaces |
PurviewConsortium.Infrastructure |
Class Library | EF Core, repositories, Purview/Search services |
PurviewConsortium.Api |
ASP.NET Core Web API | REST endpoints, auth, controllers |
PurviewConsortium.Functions |
Azure Functions (isolated) | Scheduled & on-demand Purview scanning |
PurviewConsortium.Web |
React + Vite SPA | Frontend UI with Fluent UI v9 |
- .NET 8 SDK
- Node.js 18+
- Docker (for SQL Server)
- Azure Functions Core Tools v4
- An Azure subscription with:
- Microsoft Entra ID app registration (multi-tenant)
- Azure AI Search service
- Microsoft Purview account(s)
docker-compose up -d sqlserverCopy and edit settings:
# API — update AzureAd, ConnectionStrings, and AzureAISearch sections
# in src/PurviewConsortium.Api/appsettings.jsoncd src/PurviewConsortium.Infrastructure
dotnet ef database update --startup-project ../PurviewConsortium.ApiIf this is the first time, create the initial migration:
dotnet ef migrations add InitialCreate --startup-project ../PurviewConsortium.Api
cd src/PurviewConsortium.Api
dotnet runThe API will start on https://localhost:7001 (or http://localhost:5001).
cd src/PurviewConsortium.Web
cp .env.example .env
# Edit .env with your Entra ID ClientId and TenantId
npm run devThe SPA will start on http://localhost:5173 and proxy API calls to the backend.
cd src/PurviewConsortium.Functions
func start- Go to Azure Portal → Microsoft Entra ID → App registrations → New registration
- Name:
Purview Consortium - Supported account types: Accounts in any organizational directory (Multi-tenant)
- Redirect URI:
http://localhost:5173(SPA) - Configure:
- Expose an API: Set Application ID URI to
api://<client-id>, add scope.default - API permissions:
Microsoft.Purview→DataMap.Read,DataMap.Write(delegated) - App roles: Create
Consortium.Admin,Institution.Admin,Data.Consumer - Certificates & secrets: Create a client secret for the API backend
- Expose an API: Set Application ID URI to
- Each member institution must grant admin consent for the app in their tenant
| Variable | Source | Description | Default |
|---|---|---|---|
PURVIEW_CONSORTIUM_USE_REAL_DATABASE |
Environment | Switch between in-memory (false) and SQL Server (true) databases. Takes precedence over config file. | false (in-memory) |
UseRealDatabase |
appsettings.json |
Alternative to env var; ignored if PURVIEW_CONSORTIUM_USE_REAL_DATABASE is set |
false (in-memory) |
AzureAd:ClientId |
appsettings.json |
App registration client ID | — |
AzureAd:ClientSecret |
appsettings.json |
App registration secret | — |
AzureAd:TenantId |
appsettings.json |
common for multi-tenant |
— |
ConnectionStrings:DefaultConnection |
appsettings.json |
SQL Server connection string | — |
AzureAISearch:Endpoint |
appsettings.json |
Azure AI Search endpoint | — |
AzureAISearch:ApiKey |
appsettings.json |
Azure AI Search admin key | — |
AzureAISearch:IndexName |
appsettings.json |
Search index name | consortium-catalog |
| Variable | Description |
|---|---|
VITE_AZURE_CLIENT_ID |
Same app registration client ID |
VITE_AZURE_TENANT_ID |
common for multi-tenant |
| Method | Route | Description |
|---|---|---|
| GET | /api/catalog/products |
Search/list Data Products |
| GET | /api/catalog/products/{id} |
Get product detail |
| GET | /api/catalog/stats |
Dashboard statistics |
| GET | /api/catalog/filters |
Available filter values |
| POST | /api/requests |
Submit access request |
| GET | /api/requests |
List user's requests |
| GET | /api/requests/{id} |
Get request detail |
| PATCH | /api/requests/{id}/status |
Update request status |
| DELETE | /api/requests/{id} |
Cancel request |
| GET | /api/requests/{id}/fulfillment |
Get fulfillment steps |
| GET | /api/admin/institutions |
List institutions |
| POST | /api/admin/institutions |
Register institution |
| PUT | /api/admin/institutions/{id} |
Update institution |
| DELETE | /api/admin/institutions/{id} |
Deactivate institution |
| POST | /api/admin/institutions/{id}/scan |
Trigger institution scan |
| GET | /api/admin/sync/history |
Get sync history |
| POST | /api/admin/sync/trigger |
Trigger full scan |
| # | Decision | Choice |
|---|---|---|
| 1 | Backend framework | ASP.NET Core 8 (C#) |
| 2 | Frontend framework | React + Vite SPA |
| 3 | Auth model | Single multi-tenant app registration |
| 4 | OneLake shortcuts | Guided manual (PoC), automate later |
| 5 | Search | Azure AI Search |
| 6 | Notifications | Email only |
| 7 | Tagging | Glossary term "Consortium-Shareable" |
| 8 | Scope | Data Products only |
| 9 | Database | Single DB, no RLS |
| 10 | Purview API | Data Products API (preview) |
Internal / Proof of Concept — Not for production use.