Decisions¶
This page condenses the architecture decisions of the Base Fabric Data Platform: the written ADR on the RBAC model, and the design decisions recorded in the HLD and runbooks of the solution.
ADR: RBAC model for data processing resources¶
Status: proposed. Parts of it are implemented in the code, see What the code does today.
Context¶
The solution deploys several resources that take part in data processing: Fabric capacities, workspaces, storage accounts, Key Vaults, virtual networks and Log Analytics workspaces. A least-privilege RBAC model must allow:
- automated deployment by a service principal,
- data engineers to develop and test pipelines,
- platform engineers to manage capacity and infrastructure,
- observability without over-privileged access.
Decision¶
| Role | Scope | Purpose | Assigned to |
|---|---|---|---|
| Fabric Capacity Operator (custom) | Shared resource group | Pause and resume capacities | Logic App managed identity, platform engineers group |
| Fabric Workspace Admin | Workspace | Full workspace management | Deployment service principal, platform engineers group |
| Fabric Workspace Contributor | Workspace | Develop pipelines, notebooks, dataflows | Data engineers group |
| Fabric Workspace Member | Workspace | Run pipelines, view items | Data analysts group |
| Fabric Workspace Viewer | Workspace | Read-only on reports and dashboards | Business users group |
| Storage Blob Data Contributor | Storage account | Read and write lakehouse data | Deployment service principal, data engineers group |
| Key Vault Secrets User | Key Vault | Read secrets for connections | Deployment service principal, workspace managed identity |
| Key Vault Administrator | Key Vault | Manage the lifecycle of secrets | Deployment service principal only |
| Log Analytics Reader | Log Analytics workspace | Query pipeline logs | Data engineers, platform engineers |
The custom role Fabric Capacity Operator grants only Microsoft.Fabric/capacities/read, write, suspend/action and
resume/action. It is custom because no built-in role gives pause and resume without broader Contributor rights, which would
also allow deleting a capacity or changing its SKU. That is not acceptable for an automation identity.
Assignment principles:
- Deployment service principal: the minimum for infrastructure as code (create secrets, configure storage, create and configure workspaces).
- Logic App managed identity: only the custom role. It cannot read secrets, change storage or reach workspace content.
- Platform engineers (Entra group): Fabric Capacity Operator for manual pause and resume, and Log Analytics Reader. No direct access to data in Lakehouses or Warehouses.
- Data engineers (Entra group): Workspace Contributor, Storage Blob Data Contributor and Key Vault Secrets User, so they can develop and test pipelines end to end.
- Data analysts and business users: Workspace Member or Viewer only. No infrastructure access.
Workspace roles are assigned inside Fabric, not with Azure RBAC, through the fabric_workspace_role_assignment resource.
Consequences¶
- All role assignments are code. No ad-hoc grants in the portal.
- The custom role limits the blast radius of automation identities.
- Entra ID groups are the unit of assignment. Individual users never get direct roles.
- Production uses the same model but needs an explicit opt-in for each group assignment.
- A new persona (for example a data steward) means updating the ADR and the Terraform variables.
Future: conditions on role assignments¶
If an automation identity must delegate access (for example a workspace identity that grants storage access to pipeline runs), Azure role assignment conditions can limit which roles it may assign. This should be evaluated when the need arises.
What the code does today¶
| Item | In the code |
|---|---|
| Custom role Fabric Capacity Operator | Implemented in the shared tier, scoped to the shared resource group. Assigned to the Logic App identities and to capacity_operator_group_ids. |
| Workspace roles | Implemented for Admin, Contributor, Member and Viewer groups, per workspace |
| Storage roles | The deployment identity gets Storage Account Contributor and Storage Blob Data Contributor on the data lake. The code does not assign storage roles to data engineers. |
| Key Vault roles | The storage identity gets Key Vault Crypto Service Encryption User. The code does not assign Key Vault roles to groups. |
| Log Analytics Reader for groups | Not assigned by this code. The Grafana identity gets Log Analytics Reader and Monitoring Reader. |
Where the ADR and the code differ, the code is what is deployed. Treat the table of roles above as the target model.
Design decisions¶
| Decision | Reason |
|---|---|
| Capacities in a shared subscription | One capacity can serve one or more environments, which lowers cost. A separate capacity per environment stays possible because each workspace names its capacity. |
| One subscription per environment, on the spoke canvas | Isolation per environment, with the platform baseline (network, DNS, policy) inherited from the spoke |
| Outbound deny by default, allow through the gateway or managed private endpoints | Prevents data exfiltration |
| A VNet data gateway per capacity, restricted per workspace | Workspaces can only use the designated gateway |
| Git only on development workspaces in the basic setup | Production is deployed through CI/CD, which is more controlled than a direct Git integration |
| Customer-managed key plus infrastructure encryption on the data lake | Control of the key and double encryption at rest |
| Credentials only in Key Vault | Never in code or configuration. Connections refer to secrets by name. |
| Optional Admin group per workspace | The workload team manages workspace users and settings without a ticket, while network policy and capacity stay with the platform |
| Terraform as the single source of truth | Reproducible, traceable, consistent. Manual changes are reverted. |
| Auto-pause is opt-in and manual resume by default | Saves cost for non-production capacities without risking production or surprising users |
| Auto-pause uses a custom least-privilege role | See the ADR above |
| Purview as shared infrastructure, automatic Fabric registration | One catalog for all workspaces, no manual source registration |
| Separate Grafana groups from Fabric groups | Different blast radius |
| Grafana is deployed as its own tier with its own state | Independent lifecycle. Dashboards are code in the configuration repository. |