Share via

How SQL RBAC works

HimanshuSinha 19,637 Reputation points Microsoft Employee Moderator
2026-06-24T18:41:08.07+00:00

I’m implementing role-based access control for a multi-tenant platform with admin, operator, auditor, and read-only personas across several services. Permissions currently differ by module, environment, and tenant, and we struggle with role sprawl, inconsistent naming, and hardcoded checks in code. I need a practical RBAC design that supports least privilege, delegated administration, and clear separation of duties while remaining easy to audit and evolve. How should I structure roles, permission groups, and inheritance; enforce policy at API and data layers; handle exceptions safely; and implement governance controls for periodic access reviews, emergency access, and change management without disrupting delivery?

Azure Role-based access control
Azure Role-based access control

An Azure service that provides fine-grained access management for Azure resources, enabling you to grant users only the rights they need to perform their jobs.

0 comments No comments

1 answer

Sort by: Most helpful
  1. Jerald Felix 14,965 Reputation points Volunteer Moderator
    2026-06-25T02:08:53.3566667+00:00

    Hello HimanshuSinha,

    Greetings! Thanks for raising this question in the Q&A forum.

    The role sprawl and inconsistent naming you are describing usually comes from designing roles around org chart titles instead of designing them around tasks, scopes, and time. A durable multi-tenant RBAC model separates four concerns, who someone is, what they can do, where they can do it, and for how long, and keeps each of those independently adjustable.

    1. Separate role definitions from role assignments

    Define a small, stable catalog of permission sets such as admin, operator, auditor, and read-only as role definitions, then keep all the variation by module, environment, and tenant in the assignment layer rather than creating new roles per combination. A common cause of role sprawl is cloning a role per tenant or per environment instead of reusing the same role definition at different scopes.

    Role definition: Operator
    Actions: read, write on workload resources
    NotActions: identity management, billing, policy changes
    
    Assignment: Operator role + Tenant A scope + Production environment scope
    Assignment: Operator role + Tenant B scope + Staging environment scope
    
    1. Use a scope hierarchy that mirrors tenant and environment boundaries

    Structure scopes so permissions inherit cleanly: platform level, tenant level, then environment level underneath each tenant. Grant broad roles only at the platform level for central functions like break glass access, and push tenant or environment specific access down to the lowest scope that still lets the operator do their job. This is what eliminates the need for one role per tenant per environment.

    1. Replace hardcoded checks with policy evaluated at both layers

    At the API layer, enforce coarse grained authorization, whether the caller's role permits the operation at all, before the request reaches business logic. At the data layer, enforce fine grained row or tenant level filtering, for example a SQL row level security predicate or a Cosmos DB partition key constraint that scopes queries to the caller's tenant regardless of what the API layer already checked. Keeping both layers means a bug in one does not expose cross tenant data.

    CREATE SECURITY POLICY TenantFilterPolicy
    ADD FILTER PREDICATE dbo.fn_securitypredicate(TenantId)
    ON dbo.Orders
    WITH (STATE = ON);
    
    1. Use groups and conditions instead of direct user assignments

    Assign roles to security groups, not individual users, and use Azure RBAC conditions or Entra ID custom security attributes to constrain what a role assignment can actually touch, for example restricting a role assignment so it can only be applied to resources tagged with a specific tenant identifier. This keeps the assignment count low and auditable as people move between teams.

    1. Handle exceptions through time bound elevation, not permanent new roles

    When someone genuinely needs broader access temporarily, use Microsoft Entra Privileged Identity Management to make them eligible for a higher privilege role rather than creating a permanent exception role. PIM access is activated for a defined window, requires justification, and automatically expires, which keeps your role catalog from growing every time an exception comes up.

    PIM eligible assignment: Admin role, eligible (not active)
    Activation: time bound, requires justification, auto expires after N hours
    
    1. Build governance around the same role catalog

    Run periodic access reviews against the same small set of role definitions using Entra ID Access Reviews, so reviewers are validating scope and membership rather than re-learning a new role each cycle. Define break glass accounts as a separate, tightly monitored role outside the normal catalog so emergency access does not get tangled into day to day role design. Treat changes to role definitions themselves as a change managed, version controlled process, since a change to a shared role definition affects every tenant and environment it is assigned to.

    1. Keep delivery unblocked while tightening this up

    Roll this out by first inventorying current direct assignments and over-permissioned service principals using the Azure Activity Log, then migrate access to the new group based, scope based model incrementally per tenant rather than a single cutover, so teams are never mid-migration without any working access path.

    If this answer helps you kindly accept the answer which will help others who have similar questions.

    Best Regards,

    Jerald Felix

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.