SaasSuite.Audit
26.3.3.2
dotnet add package SaasSuite.Audit --version 26.3.3.2
NuGet\Install-Package SaasSuite.Audit -Version 26.3.3.2
<PackageReference Include="SaasSuite.Audit" Version="26.3.3.2" />
<PackageVersion Include="SaasSuite.Audit" Version="26.3.3.2" />
<PackageReference Include="SaasSuite.Audit" />
paket add SaasSuite.Audit --version 26.3.3.2
#r "nuget: SaasSuite.Audit, 26.3.3.2"
#:package SaasSuite.Audit@26.3.3.2
#addin nuget:?package=SaasSuite.Audit&version=26.3.3.2
#tool nuget:?package=SaasSuite.Audit&version=26.3.3.2
SaasSuite.Audit
Audit logging for multi-tenant SaaS applications with comprehensive event tracking and querying capabilities.
Overview
SaasSuite.Audit provides a complete audit logging solution for tracking user actions, system events, and resource changes in multi-tenant applications. It captures who did what, when, and provides powerful querying capabilities for compliance and security monitoring.
Features
- Event Logging: Record user actions and system events
- Multi-Tenant: Full tenant isolation for audit events
- Rich Metadata: Capture additional context and metadata
- Flexible Querying: Filter by date range, action, resource, and tenant
- Admin View: Cross-tenant audit trail for administrators
- Thread-Safe: Concurrent event recording
- Extensible: Easy to implement custom storage backends
Installation
dotnet add package SaasSuite.Audit
dotnet add package SaasSuite.Core
Quick Start
1. Register Services
builder.Services.AddSaasAudit();
2. Log Audit Events
using SaasSuite.Audit.Interfaces;
public class InvoiceController : ControllerBase
{
private readonly IAuditService _auditService;
public InvoiceController(IAuditService auditService)
{
_auditService = auditService;
}
[HttpPost]
public async Task<IActionResult> CreateInvoice(InvoiceDto dto)
{
// Create invoice logic...
// Log the audit event
await _auditService.LogAsync(
tenantId: new TenantId("tenant-123"),
userId: User.Identity.Name,
action: "Create",
resource: "Invoice",
details: $"Created invoice {invoice.Id} for amount ${invoice.Total}",
metadata: new Dictionary<string, string>
{
{ "InvoiceId", invoice.Id },
{ "Amount", invoice.Total.ToString() }
});
return Ok(invoice);
}
}
Core Concepts
Audit Event Structure
public class AuditEvent
{
public string Id { get; set; } // Unique event ID
public TenantId TenantId { get; set; } // Tenant who owns this event
public string UserId { get; set; } // User who performed the action
public string Action { get; set; } // Action type (Create, Update, Delete)
public string Resource { get; set; } // Resource affected (Invoice, User, etc.)
public string? Details { get; set; } // Additional details
public DateTime Timestamp { get; set; } // When it happened
public string? IpAddress { get; set; } // IP address (optional)
public IDictionary<string, string> Metadata { get; set; } // Additional key-value data
}
Usage Examples
Log User Actions
// Login event
await _auditService.LogAsync(
tenantId,
userId: user.Email,
action: "Login",
resource: "Authentication",
details: "User logged in successfully",
metadata: new Dictionary<string, string>
{
{ "LoginMethod", "OAuth" },
{ "Provider", "Google" }
});
// Update event
await _auditService.LogAsync(
tenantId,
userId: currentUser.Id,
action: "Update",
resource: "Subscription",
details: $"Changed plan from {oldPlan} to {newPlan}",
metadata: new Dictionary<string, string>
{
{ "OldPlan", oldPlan },
{ "NewPlan", newPlan },
{ "EffectiveDate", effectiveDate.ToString() }
});
// Delete event
await _auditService.LogAsync(
tenantId,
userId: currentUser.Id,
action: "Delete",
resource: "Document",
details: $"Deleted document: {document.Name}",
metadata: new Dictionary<string, string>
{
{ "DocumentId", document.Id },
{ "DocumentName", document.Name }
});
Query Audit Events
// Get all events for a tenant
var events = await _auditService.GetEventsAsync(
tenantId,
startDate: DateTime.UtcNow.AddDays(-30),
endDate: DateTime.UtcNow);
// Filter by action
var deleteEvents = await _auditService.GetEventsAsync(
tenantId,
action: "Delete",
startDate: DateTime.UtcNow.AddDays(-7));
// Filter by resource
var invoiceEvents = await _auditService.GetEventsAsync(
tenantId,
resource: "Invoice",
startDate: DateTime.UtcNow.AddMonths(-1));
// Combined filters
var recentUpdates = await _auditService.GetEventsAsync(
tenantId,
startDate: DateTime.UtcNow.AddHours(-24),
action: "Update",
resource: "Subscription");
Admin View (Cross-Tenant)
// Get all events across all tenants
var allEvents = await _auditService.GetAllEventsAsync(
startDate: DateTime.UtcNow.AddDays(-7),
endDate: DateTime.UtcNow);
// Find all delete operations across tenants
var allDeletes = await _auditService.GetAllEventsAsync(
action: "Delete",
startDate: DateTime.UtcNow.AddDays(-30));
Common Actions
Standard action names for consistency:
- Authentication:
Login,Logout,PasswordChange,MfaEnabled - CRUD:
Create,Read,Update,Delete - Subscription:
Subscribe,Upgrade,Downgrade,Cancel,Renew - Billing:
InvoiceGenerated,PaymentReceived,RefundIssued - User Management:
UserInvited,UserRemoved,RoleChanged,PermissionGranted - Configuration:
SettingChanged,FeatureEnabled,FeatureDisabled
Common Resources
Standard resource names:
- User Management:
User,Role,Permission,ApiKey - Billing:
Invoice,Payment,Subscription,Refund - Content:
Document,File,Folder,Attachment - Configuration:
Setting,Feature,Integration - System:
Authentication,Authorization,Configuration
Custom Storage Implementation
The default implementation uses in-memory storage. For production, implement a custom backend:
using SaasSuite.Audit.Interfaces;
public class DatabaseAuditService : IAuditService
{
private readonly IDbContext _dbContext;
public DatabaseAuditService(IDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<AuditEvent> LogAsync(
TenantId tenantId,
string userId,
string action,
string resource,
string? details = null,
IDictionary<string, string>? metadata = null,
CancellationToken cancellationToken = default)
{
var auditEvent = new AuditEvent
{
TenantId = tenantId,
UserId = userId,
Action = action,
Resource = resource,
Details = details,
Metadata = metadata ?? new Dictionary<string, string>()
};
await _dbContext.AuditEvents.AddAsync(auditEvent, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
return auditEvent;
}
// Implement other methods...
}
// Register custom implementation
builder.Services.AddSaasAudit<DatabaseAuditService>();
Integration with Other Packages
- SaasSuite.Core: Tenant-aware audit logging
- SaasSuite.Compliance: GDPR audit trail for data access
- SaasSuite.DataProtection: Audit sensitive data operations
Best Practices
- Log Important Actions: Focus on security-relevant and compliance-required events
- Include Context: Add metadata to make events searchable and meaningful
- Consistent Naming: Use standard action and resource names across your application
- User Identification: Always include the user ID performing the action
- Timestamp Accuracy: Use UTC timestamps for consistency
- Storage Considerations: Implement database storage for production use
- Retention Policies: Archive or purge old events based on compliance requirements
- Query Performance: Index tenant ID, timestamp, action, and resource fields
Storage
The default in-memory implementation is suitable for development and testing. For production use:
- Implement
IAuditServicewith your database backend - Consider using time-series databases for high-volume scenarios
- Implement data retention and archival policies
- Index frequently queried fields
Related Packages
- SaasSuite.Core: Core multi-tenancy features
- SaasSuite.Compliance: Compliance and GDPR support
- SaasSuite.DataProtection: Data protection features
License
This package is licensed under the Apache License 2.0. See the LICENSE file in the repository root for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- SaasSuite.Core (>= 26.3.3.2)
-
net6.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- SaasSuite.Core (>= 26.3.3.2)
-
net7.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- SaasSuite.Core (>= 26.3.3.2)
-
net8.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- SaasSuite.Core (>= 26.3.3.2)
-
net9.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- SaasSuite.Core (>= 26.3.3.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SaasSuite.Audit:
| Package | Downloads |
|---|---|
|
SaasSuite
Convenience meta-package that bundles the core SaaS building blocks. Includes SaasSuite.Core, SaasSuite.Features, SaasSuite.Seats, SaasSuite.Quotas, SaasSuite.Metering, SaasSuite.Billing, SaasSuite.Subscriptions, SaasSuite.Audit, and SaasSuite.Migration. Integrations live in separate packages and are not included. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 26.3.3.2 | 118 | 3/3/2026 |