RBAC Integration Guide (.NET)
Follow the five-step integration guide below. Choose the storage adapter that fits your environment.
Step 1: Install the package
In-Memory adapter (development and testing):
dotnet add package PrimusSaaS.Rbac
dotnet add package PrimusSaaS.Rbac.InMemory
EF Core adapter (production database):
dotnet add package PrimusSaaS.Rbac
dotnet add package PrimusSaaS.Rbac.EFCore
Step 2: Configure Program.cs
In-Memory adapter:
using PrimusSaaS.Rbac;
using PrimusSaaS.Rbac.InMemory;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPrimusRbacInMemory(options =>
builder.Configuration.GetSection("Rbac").Bind(options));
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
EF Core adapter:
Replace AppDbContext with your application's DbContext.
using Microsoft.EntityFrameworkCore;
using PrimusSaaS.Rbac;
using PrimusSaaS.Rbac.EFCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddPrimusRbacEfCore<AppDbContext>(options =>
builder.Configuration.GetSection("Rbac").Bind(options));
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
Update your DbContext model configuration:
using PrimusSaaS.Rbac.EFCore;
public class AppDbContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.AddPrimusRbac();
}
}
Step 3: Configure appsettings.json
In-Memory adapter:
{
"Rbac": {
"SeedMode": "none",
"AllowMultipleInheritance": false
}
}
EF Core adapter:
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=primus_rbac;Trusted_Connection=True;"
},
"Rbac": {
"SeedMode": "none",
"AllowMultipleInheritance": false
}
}
Seed modes:
none: no preloaded roles or permissions.minimal: adds a singlerole:administratorwithperm:all.sample: adds example roles, permissions, and groups.
How to get configuration values
ConnectionStrings:DefaultConnectionis your standard database connection string (SQL Server, PostgreSQL, or SQLite).Rbac:SeedModecontrols optional starter data (none,minimal,sample).Rbac:AllowMultipleInheritanceallows more than one parent role. Keepfalsefor a strict tree.
Optional: If you want to select the adapter via configuration, add Rbac:Store and branch in Program.cs. Use database for EF Core or in-memory for the In-Memory adapter.
Step 4: Configure endpoints
Expose RBAC endpoints using IRbacService. The access check endpoint is required. The admin UI expects the role, permission, group, membership, assignment, snapshot, and reset endpoints shown below.
using Microsoft.AspNetCore.Mvc;
using PrimusSaaS.Rbac;
[ApiController]
[Route("api/rbac")]
public class RbacController : ControllerBase
{
private readonly IRbacService _rbac;
public RbacController(IRbacService rbac) => _rbac = rbac;
[HttpPost("check")]
public IActionResult Check([FromBody] RbacAccessRequest request)
{
var decision = _rbac.Evaluate(request);
return Ok(decision);
}
[HttpGet("roles")]
public IActionResult ListRoles([FromQuery] string? applicationId = null, [FromQuery] string? tenantId = null)
=> Ok(_rbac.ListRoles(applicationId, tenantId));
[HttpPost("roles")]
public IActionResult UpsertRole([FromBody] RbacRole role)
{
_rbac.UpsertRole(role);
return Ok(role);
}
[HttpDelete("roles/{roleId}")]
public IActionResult DeleteRole(string roleId)
{
_rbac.DeleteRole(roleId);
return Ok();
}
[HttpGet("permissions")]
public IActionResult ListPermissions([FromQuery] string? applicationId = null, [FromQuery] string? tenantId = null)
=> Ok(_rbac.ListPermissions(applicationId, tenantId));
[HttpPost("permissions")]
public IActionResult UpsertPermission([FromBody] RbacPermission permission)
{
_rbac.UpsertPermission(permission);
return Ok(permission);
}
[HttpDelete("permissions/{permissionId}")]
public IActionResult DeletePermission(string permissionId)
{
_rbac.DeletePermission(permissionId);
return Ok();
}
[HttpGet("groups")]
public IActionResult ListGroups([FromQuery] string? applicationId = null, [FromQuery] string? tenantId = null)
=> Ok(_rbac.ListGroups(applicationId, tenantId));
[HttpPost("groups")]
public IActionResult UpsertGroup([FromBody] RbacGroup group)
{
_rbac.UpsertGroup(group);
return Ok(group);
}
[HttpDelete("groups/{groupId}")]
public IActionResult DeleteGroup(string groupId)
{
_rbac.DeleteGroup(groupId);
return Ok();
}
[HttpGet("memberships")]
public IActionResult ListMemberships([FromQuery] string? principalId = null, [FromQuery] string? groupId = null)
=> Ok(_rbac.ListMemberships(principalId, groupId));
[HttpPost("memberships")]
public IActionResult UpsertMembership([FromBody] RbacMembership membership)
{
_rbac.UpsertMembership(membership);
return Ok(membership);
}
[HttpDelete("memberships/{membershipId}")]
public IActionResult DeleteMembership(string membershipId)
{
_rbac.DeleteMembership(membershipId);
return Ok();
}
[HttpGet("assignments/{principalId}")]
public IActionResult ListAssignments(string principalId)
=> Ok(_rbac.ListAssignments(principalId));
[HttpPost("assignments")]
public IActionResult UpsertAssignment([FromBody] RbacAssignment assignment)
{
_rbac.UpsertAssignment(assignment);
return Ok(assignment);
}
[HttpDelete("assignments/{assignmentId}")]
public IActionResult DeleteAssignment(string assignmentId)
{
_rbac.DeleteAssignment(assignmentId);
return Ok();
}
[HttpGet("snapshot")]
public IActionResult Snapshot() => Ok(_rbac.Snapshot());
[HttpPost("reset")]
public IActionResult Reset()
{
_rbac.Reset();
return Ok();
}
}
Secure these endpoints with your authentication layer before exposing them to the UI.
Step 5: Test the endpoint
curl -X POST http://localhost:5000/api/rbac/check \
-H "Content-Type: application/json" \
-d '{
"principalId": "user-123",
"principalType": "user",
"roles": ["Builder"],
"action": "write",
"resource": "resource:main",
"applicationId": "app-sales",
"tenantId": "tenant-001",
"attributes": { "status": "active", "region": "us", "amount": 1200 }
}'
You should receive a response with allowed set to true or false, plus the matched role and permission identifiers.
See the Advanced guide for audit logging and condition operators.