Enterprise Audit Trail

Full audit logging with 23 entity fields, module auto-detection, correlation tracking, real-time SignalR broadcasting, and 45+ event types across 13 categories.

SCRIPE's enterprise audit trail captures every significant action across the platform — from authentication events and entity mutations to permission changes, security incidents, and guardian protection enforcement. Each audit entry records 23 fields including CorrelationId for request tracing, TenantId for multi-tenant isolation, ModuleTag for module-level filtering, and IpAddress/UserAgent for forensic analysis. Events are broadcast in real-time via SignalR to connected dashboards.

Audit Trail Architecture

Audit Trail Data Flow
User Action
AuditMiddleware — HTTP request capture
AuditBehavior — AstraFlow mediator pipeline
AuditService — Module auto-detect
AuditLogs Table — Persistent storage
SignalR Hub — Real-time broadcast

AuditLog Entity Schema (23 Fields)

The AuditLog entity captures comprehensive context for every auditable event. Old and new values are stored as JSON snapshots for full change history and regulatory compliance. The entity includes forensic data (IpAddress, UserAgent) and operational metadata (DurationMs, StatusCode, Metadata).

ColumnTypeNullablePurpose
IdGuidNoUnique audit entry identifier (auto-generated)
EventTypestring(50)NoEvent classification — see Event Types table below
HttpMethodstring(10)YesHTTP verb (GET, POST, PUT, DELETE)
Endpointstring(500)YesAPI path that was called (e.g., /api/admins/123)
EntityTypestring(100)YesEntity affected (Admin, Role, Tenant, Edition, etc.)
EntityIdstring(100)YesEncrypted entity ID (AES-256 encrypted)
OldValuesJSON (nvarchar max)YesPrevious state snapshot — stored for update/delete operations
NewValuesJSON (nvarchar max)YesNew state snapshot — stored for create/update operations
ChangedPropertiesstring(1000)YesComma-separated list of changed field names
UserIdGuidYesWho performed the action (null for anonymous/system)
TenantIdGuidYesTenant context — used for scoping in tenant dashboards
Usernamestring(100)YesDisplay name of the user who performed the action
IsAdminboolNoWhether the user is an admin (for client-user distinction)
IpAddressstring(50)YesClient IP address (IPv4 or IPv6)
UserAgentstring(500)YesBrowser/device user agent string
CorrelationIdstring(50)YesLinks all audit entries from the same HTTP request
ModuleTagstring(50)YesAuto-detected module (Identity, Entitlements, System, etc.)
StatusCodeintYesHTTP response status code (200, 400, 401, 403, 500, etc.)
DurationMslongYesRequest processing time in milliseconds
IsSuccessboolNoWhether the operation succeeded (default: true)
ErrorMessagestring(max)YesError details if operation failed
MetadataJSON (nvarchar max)YesAdditional context data as JSON (e.g., batch counts, custom data)
TimestampDateTimeNoUTC timestamp of the event (default: DateTime.UtcNow)

Module Auto-Detection

The AuditService automatically determines which module generated each audit event using a 3-priority detection chain: (1) Event-type hardcoded mapping for auth events, (2) API endpoint path-based mapping, (3) Entity type name-based mapping. Unknown modules are auto-capitalized from the URL segment. This eliminates manual tagging and ensures consistent module attribution.

Detection SourceExample InputDetected ModulePriority
Event Type (hardcoded)Login, LoginFailed, LogoutIdentityHighest — event-based override
Endpoint path/api/admins/123IdentityPrimary — URL-based detection
Endpoint path/api/rolesIdentityPrimary
Endpoint path/api/tenantsIdentityPrimary
Endpoint path/api/editionsEntitlementsPrimary
Endpoint path/api/featuresEntitlementsPrimary
Endpoint path/api/subscriptionsEntitlementsPrimary
Endpoint path/api/audit-logsSystemPrimary
Endpoint path/api/productsProducts (auto-capitalized)Fallback — unknown modules auto-mapped
Entity Type nameAdmin, Role, TenantIdentitySecondary — entity-based detection
Entity Type nameEdition, FeatureEntitlementsSecondary
AuditService.cs — Module Detection LogicC#
private string DetectModule(AuditLog log)
{
    // Priority 1: Event-type hardcoded mapping
    if (log.EventType is AuditEventTypes.Login
        or AuditEventTypes.LoginFailed
        or AuditEventTypes.Logout
        or AuditEventTypes.TokenRefresh)
        return "Identity";

    // Priority 2: Endpoint path-based mapping
    if (!string.IsNullOrEmpty(log.Endpoint))
    {
        var segment = ExtractFirstSegment(log.Endpoint);
        return _endpointModuleMap.GetValueOrDefault(
            segment, Capitalize(segment));
    }

    // Priority 3: Entity type-based mapping
    if (!string.IsNullOrEmpty(log.EntityType))
        return _entityModuleMap.GetValueOrDefault(
            log.EntityType, "System");

    return "System"; // Fallback
}

Audit Event Types (45+)

CategoryEvent TypesDescription
AuthenticationLogin, LoginFailed, Logout, TokenRefreshUser session lifecycle events
CRUD OperationsCreate, Update, DeleteEntity data mutations with old/new value snapshots
SecurityAccessDenied, PrivilegeEscalationAttempt, AdminImpersonationSecurity-sensitive or blocked actions
PasswordPasswordChange, PasswordReset, PasswordChangedCredential management events
AccountAccountLocked, AccountUnlocked, AdminStatusChangedAccount state changes
2FATwoFactorEnabled, TwoFactorDisabled, TwoFactorVerified, BackupCodeUsed, BackupCodesRegeneratedMulti-factor authentication lifecycle
SessionSessionRevoked, AllSessionsRevokedSession management and forced logout
RBACRoleAssigned, RoleUnassigned, PermissionGranted, PermissionRevoked, ScopeChangedAccess control changes
TenantTenantAccess, HierarchyAccess, TenantPermissionsUpdated, BulkTenantCascadeDeleteTenant hierarchy and cross-tenant operations
Bulk OperationsBulkAdminDelete, BulkAdminStatusUpdateBatch mutations affecting multiple entities
ProfileProfileUpdatedUser self-service profile changes
GuardianGuardianAdminDeleteBlocked, GuardianAdminTransferBlocked, GuardianAdminDemoteBlocked, GuardianAdminDeactivateBlocked, GuardianRoleDeleteBlocked, GuardianRolePermissionBlocked, GuardianTenantCreatedProtection system enforcement — prevents destruction of critical resources
SystemRequest, ErrorHTTP request logging and unhandled error tracking

Real-Time Broadcasting

Audit events (excluding routine HTTP Request logs to avoid flooding) are broadcast via SignalR to connected clients. Events are scoped by tenant — tenant admins only see their own tenant's events via tenant-specific groups, while super admins receive all events via the global group.

SignalR Audit BroadcastingC#
// Audit events are broadcast to connected dashboards in real-time.
// Routine HTTP request logs (EventType == "Request") are excluded
// to avoid flooding the WebSocket channel.

if (log.EventType != AuditEventTypes.Request)
{
    var dto = MapToSignalRDto(log);

    // 1. Tenant-specific group (tenant admins see their own events)
    if (log.TenantId.HasValue)
    {
        await _hubContext.Clients
            .Group(HubGroupNames.ForTenant(log.TenantId.Value))
            .AuditEvent(dto);
    }

    // 2. Global group (super admins see everything)
    await _hubContext.Clients
        .Group(HubGroupNames.Global)
        .AuditEvent(dto);
}

Audit Log Query API

The audit log query endpoint supports comprehensive filtering with 12 parameters. All filters are optional and can be combined. Results are paginated (default: 20 items, max: 100) and sorted by timestamp descending. Encrypted IDs are used for UserId and TenantId filters.

AuditLog Query ExamplesShell
# Get all audit logs (paginated)
GET /api/audit-logs?page=1&pageSize=20

# Filter by event type
GET /api/audit-logs?eventType=Login&page=1&pageSize=50

# Filter by module
GET /api/audit-logs?moduleTag=Identity

# Filter by date range
GET /api/audit-logs?dateFrom=2026-04-01&dateTo=2026-04-06

# Filter by user
GET /api/audit-logs?userId=<encrypted-id>

# Trace a request (find all logs from one HTTP request)
GET /api/audit-logs?correlationId=abc-123-def

# Combined filters
GET /api/audit-logs?eventType=Create&entityType=Admin&moduleTag=Identity&dateFrom=2026-04-01
Filter ParameterTypeDescription
eventTypestringFilter by AuditEventType (Login, Create, Update, Delete, etc.)
entityTypestringFilter by entity name (Admin, Role, Tenant, Edition)
userIdstring (encrypted)Filter by the user who performed the action
tenantIdstring (encrypted)Filter by tenant context
moduleTagstringFilter by module (Identity, Entitlements, System)
dateFromdatetimeStart of date range (ISO 8601 format)
dateTodatetimeEnd of date range (ISO 8601 format)
correlationIdstringTrace all entries from a single HTTP request
isSuccessboolFilter by success/failure status
searchstringFull-text search across Endpoint, EntityType, Username
pageintPage number (default: 1)
pageSizeintItems per page (default: 20, max: 100)