Skip to main content
Version: Current

Advanced

Audit logging

Capture access checks and changes (upserts/deletes) by registering a custom audit sink.

using PrimusSaaS.Rbac;

public sealed class ConsoleRbacAuditSink : IRbacAuditSink
{
public void Record(RbacAuditEvent auditEvent)
{
Console.WriteLine($"{auditEvent.Timestamp:o} {auditEvent.EventType} {auditEvent.TargetType}:{auditEvent.TargetId}");
}
}

builder.Services.AddSingleton<IRbacAuditSink, ConsoleRbacAuditSink>();

Decision cache

RBAC can cache Evaluate() results through IRbacDecisionCache. If no implementation is registered, RBAC uses a no-op default (NullRbacDecisionCache).

using PrimusSaaS.Rbac;

builder.Services.AddSingleton<IRbacDecisionCache, MyRbacDecisionCache>();

Implementations should include principal, scope, action, resource, roles, and relevant attributes in cache keys to avoid cross-scope contamination.

Tenant context provider

RBAC resolves tenant scope from IRbacTenantIdProvider when request tenant is omitted. For Multi-Tenancy apps, use the bridge package:

using PrimusSaaS.MultiTenancy.Composition;

builder.Services.AddTenantRbacBridge();

This wires ambient tenant context into RBAC decisions automatically.

Role hierarchy (multiple parents)

By default, RBAC uses a strict tree (a role can inherit from a single parent). If you need multiple parents, enable it in configuration.

{
"Rbac": {
"AllowMultipleInheritance": true
}
}

Condition operators

These operators are supported for permission conditions:

  • eq, equals, =
  • ne, neq, not_equals, !=
  • in
  • contains
  • starts_with
  • ends_with
  • gt, gte, ge
  • lt, lte, le
  • exists, not_exists

Decision trace context

RbacDecision.Context contains trace metadata for each decision:

  • scope_key
  • scope_chain_length
  • token_roles_count
  • resolved_groups
  • evaluated_permissions

Use these values for troubleshooting authorization outcomes and dashboard metrics.