Tenant-wide connection inventory for Microsoft Fabric via REST API delegation.
- Create an Azure Key Vault with SPN credentials (
aad-tenant-id,fabric-spn-client-id,fabric-spn-client-secret) - Create a coordination workspace and add all data developers as members
- Have each developer share their connections with the SPN as Owner
- Import
nb_000_fabric_tether.ipynbinto the workspace - Update
KEY_VAULT_NAMEin the configuration cell - Run
run_inventory()
- Why This Approach
- Prerequisites
- Notebooks
- Usage
- Authentication
- Output Schema
- Bulk Share Utility
- Troubleshooting
- Limitations
- References
Microsoft Fabric does not provide a tenant-wide admin API for connections. The /v1/connections endpoint only returns connections the calling identity has permission to access.
This repository provides a workaround:
| Challenge | Solution |
|---|---|
No /v1/admin/connections endpoint |
SPN with delegated access from connection owners |
| Graph API complexity for principal names | Workspace role assignments as principal lookup |
| Manual inventory is tedious | Automated notebook with warehouse persistence |
Store the following secrets in Azure Key Vault:
| Secret Name | Description |
|---|---|
aad-tenant-id |
Your Azure AD tenant ID |
fabric-spn-client-id |
Service principal application (client) ID |
fabric-spn-client-secret |
Service principal client secret |
Access Requirements:
- Both the SPN and the user running the notebook must have
Getpermission on Key Vault secrets
- Create an App Registration in Azure AD
- Create a client secret
- Grant delegated permission:
Connection.ReadWrite.All - Add the SPN to a security group
- Have a Fabric Administrator enable:
Service principals can use Fabric APIs(Developer settings)- Add the SPN's security group to this setting
Create a Fabric workspace (recommended name: Fabric-Tether or Fabric Integration) that serves two purposes:
- Principal Registry: Add all data developers and Entra groups that may own connections as workspace members. This enables principal ID to display name resolution without Graph API.
- Notebook Host: The inventory notebook runs from this workspace and writes to a warehouse here.
Each developer must add the service principal as Owner on every connection they want inventoried. Without this step, the connection will not appear in the inventory.
| Notebook | Description |
|---|---|
nb_000_fabric_tether.ipynb |
Main inventory notebook - enumerates connections, resolves principals, writes to warehouse |
Update the configuration cell in the notebook:
KEY_VAULT_NAME = "your-keyvault-name" # e.g., "kv-fabric-prod"Execute the main function:
run_inventory()This will:
- Authenticate using SPN credentials from Key Vault
- Create
wh_integrationwarehouse if it doesn't exist - Fetch workspace role assignments for principal lookup
- Enumerate all connections the SPN has access to
- Fetch role assignments for each connection
- Join with principal lookup for display names
- Write results to
wh_integration.dbo.fabric_connection_inventory
[2025-01-25 10:30:00] ============================================================
[2025-01-25 10:30:00] FABRIC TETHER - CONNECTION INVENTORY
[2025-01-25 10:30:00] ============================================================
[2025-01-25 10:30:00] Rate limiting enabled: 100 requests/minute
[2025-01-25 10:30:00] Initializing token manager...
[2025-01-25 10:30:00] Loading SPN credentials from Key Vault...
[2025-01-25 10:30:01] SPN credentials loaded successfully
[2025-01-25 10:30:01] SPN token acquired (expires ~11:30:01)
[2025-01-25 10:30:01] Checking if warehouse 'wh_integration' exists...
[2025-01-25 10:30:02] Warehouse exists (ID: abc123...)
[2025-01-25 10:30:02] Fetching workspace role assignments for principal lookup...
[2025-01-25 10:30:03] Fetched 25 principals from workspace role assignments
[2025-01-25 10:30:03] ============================================================
[2025-01-25 10:30:03] REFRESH: fabric_connection_inventory
[2025-01-25 10:30:03] ============================================================
[2025-01-25 10:30:03] Fetching all connections...
[2025-01-25 10:30:04] ... page 1: 50 connections
[2025-01-25 10:30:04] Fetched 50 total connections (1 pages)
[2025-01-25 10:30:04] Fetching role assignments for each connection...
[2025-01-25 10:30:10] ... processed 50/50 connections (150 rows)
[2025-01-25 10:30:10] Writing 150 rows to wh_integration.dbo.fabric_connection_inventory...
[2025-01-25 10:30:15] Write complete
[2025-01-25 10:30:15] ============================================================
[2025-01-25 10:30:15] EXECUTION SUMMARY
[2025-01-25 10:30:15] ============================================================
[2025-01-25 10:30:15] fabric_connection_inventory [OK] 150 rows
[2025-01-25 10:30:15] ------------------------------------------------------------
[2025-01-25 10:30:15] Total: 1 tables | 1 succeeded | 0 failed | 15.0s elapsed
[2025-01-25 10:30:15] ============================================================
Service Principal Authentication Required
This notebook uses service principal (SPN) authentication exclusively via Azure Key Vault.
Requirements:
- A Fabric Administrator must enable
Service principals can use Fabric APIs(Developer settings)- The SPN's security group must be added to this tenant setting
- SPN credentials must be stored in Azure Key Vault
- Both the SPN and notebook user need Key Vault secret read access
- Consistency: Items (warehouse) are owned by the SPN, not individual users
- Automation: Supports scheduled/unattended execution
- Security: Credentials stored in Key Vault, not in notebook
| Column | Data Type | Source |
|---|---|---|
connection_id |
VARCHAR | connections.id |
connection_name |
VARCHAR | connections.displayName |
connectivity_type |
VARCHAR | connections.connectivityType |
gateway_id |
VARCHAR | connections.gatewayId |
connection_type |
VARCHAR | connections.connectionDetails.type |
connection_path |
VARCHAR | connections.connectionDetails.path |
privacy_level |
VARCHAR | connections.privacyLevel |
credential_type |
VARCHAR | connections.credentialDetails.credentialType |
sso_type |
VARCHAR | connections.credentialDetails.singleSignOnType |
connection_encryption |
VARCHAR | connections.credentialDetails.connectionEncryption |
principal_id |
VARCHAR | roleAssignments.principal.id |
principal_type |
VARCHAR | roleAssignments.principal.type |
principal_role |
VARCHAR | roleAssignments.role |
principal_display_name |
VARCHAR | Joined from workspace role assignments |
user_principal_name |
VARCHAR | Joined from workspace role assignments |
inventory_timestamp |
TIMESTAMP | current_timestamp() |
| Value | Description |
|---|---|
ShareableCloud |
Cloud connection that can be shared |
PersonalCloud |
Personal cloud connection |
OnPremisesGateway |
On-premises data gateway connection |
OnPremisesGatewayPersonal |
Personal on-premises gateway connection |
VirtualNetworkGateway |
VNet data gateway connection |
| Value | Description |
|---|---|
Owner |
Full control including delete and permission management |
UserWithReshare |
Can use and share the connection |
User |
Can use but not share the connection |
The notebook includes a bulk_share_connections() function for programmatically sharing connections.
- Onboarding new team members to existing connections
- Granting the SPN access to newly created connections
- Batch-updating connection permissions
# Initialize (required)
global _rate_limiter
_rate_limiter = RateLimiter(REQUESTS_PER_MINUTE)
token_manager = TokenManager(KEY_VAULT_URL, buffer_minutes=TOKEN_REFRESH_BUFFER_MINUTES)
headers = token_manager.get_headers()
# Share connections with the SPN
result = bulk_share_connections(
headers,
connection_ids=["conn-guid-1", "conn-guid-2"],
principal_ids=["spn-object-id"],
role="Owner",
principal_type="ServicePrincipal",
token_manager=token_manager
)
print(f"Succeeded: {len(result['succeeded'])}, Failed: {len(result['failed'])}")| Parameter | Type | Description |
|---|---|---|
connection_ids |
list[str] |
List of connection GUIDs to share |
principal_ids |
list[str] |
List of Entra Object IDs to grant access |
role |
str |
Owner, User, or UserWithReshare (default: Owner) |
principal_type |
str |
User, Group, or ServicePrincipal (default: User) |
| Error | Cause | Solution |
|---|---|---|
Failed to retrieve SPN credentials from Key Vault |
Key Vault secrets missing or access denied | Verify secret names and ensure user has Get permission |
SPN token acquisition failed |
Invalid SPN credentials or tenant settings | Verify client ID/secret and tenant admin settings |
Max retries exceeded |
API rate limiting | Reduce REQUESTS_PER_MINUTE or wait and retry |
401 Unauthorized |
Token expired or insufficient permissions | Verify SPN has Connection.ReadWrite.All and is in allowed security group |
No connections found |
SPN has no connection access | Have connection owners share their connections with the SPN as Owner |
Principal display name is null |
Principal not in coordination workspace | Add the principal (user/group) to the workspace as a member |
| Limitation | Impact |
|---|---|
| Coverage is not automatic | New connections must be manually shared with the SPN before appearing in inventory |
| Departed employees | Connections owned solely by departed users become orphaned and invisible unless ownership was transferred |
| Personal cloud connections | PersonalCloud connections may not be shareable depending on tenant settings |
| Display name gaps | Principals not added to the coordination workspace will have null display names |
| No created/modified dates | The API does not expose connection creation or modification timestamps |
| Full overwrite | Each run completely replaces the inventory table; no incremental updates |