Activity logging provides a complete audit trail of all resource-related actions in NetBird Selfservice. Every create, update, delete, approval, and status change is recorded with full context for compliance and troubleshooting.
What Gets Logged
NetBird Selfservice logs every action that affects network resources:
Approval Workflow
Requested
Approved
Denied
Cancelled
ResourceLog Model
Activity logs are stored in the resource_logs table using the ResourceLog model:
Log Fields
// From ResourceLog.php:11-18
protected $fillable = [
'netbird_id' ,
'action' ,
'resource_name' ,
'resource_address' ,
'performed_by' ,
'changes' ,
];
Field Type Description netbird_idstring NetBird resource ID (null for requests) actionstring Type of action performed resource_namestring Name of the resource resource_addressstring IP, CIDR, or domain performed_bystring Name of the user who performed the action changesarray JSON object with detailed changes created_attimestamp When the action occurred
Changes Field
The changes field is cast to an array and stores action-specific details:
// From ResourceLog.php:20-24
protected function casts () : array
{
return [
'changes' => 'array' ,
];
}
Action Types
All actions are defined in the ResourceAction enum:
// From ResourceAction.php:6-15
enum ResourceAction : string
{
case Created = 'created' ;
case Approved = 'approved' ;
case Updated = 'updated' ;
case Deleted = 'deleted' ;
case Denied = 'denied' ;
case Requested = 'requested' ;
case Cancelled = 'cancelled' ;
case Enabled = 'enabled' ;
case Disabled = 'disabled' ;
}
Action Categories
Creation Actions
Modification Actions
Workflow Actions
Deletion Actions
Created
Direct creation by admin users
Logs: name, address, description, enabled status
Approved
Resource created via approval workflow
Logs: requester info, approved resource details
Updated
Changes to existing resource
Logs: modified fields and new values
Enabled / Disabled
Status toggle actions
Logs: new enabled status
Requested
New approval request submitted
Logs: requester, resource details
Denied
Request rejected by admin
Logs: admin who denied, reason if provided
Cancelled
Request cancelled by requester
Logs: who cancelled, when
Deleted
Resource permanently removed
Logs: resource details before deletion
Logging Implementation
Helper Method
The ResourceLog model provides a static helper method for easy logging:
// From ResourceLog.php:27-43
public static function logAction (
string $action ,
string $resourceName ,
? string $netbirdId = null ,
? string $resourceAddress = null ,
? string $performedBy = null ,
? array $changes = null
) : self {
return self :: create ([
'action' => $action ,
'resource_name' => $resourceName ,
'netbird_id' => $netbirdId ,
'resource_address' => $resourceAddress ,
'performed_by' => $performedBy ,
'changes' => $changes ,
]);
}
Example: Logging a Resource Creation
// From CreateResourceAction.php:46-58
ResourceLog :: logAction (
action : ResourceAction :: Created -> value ,
resourceName : $name ,
netbirdId : $result [ 'id' ],
resourceAddress : $address ,
performedBy : $user -> name ,
changes : [
'name' => $name ,
'address' => $address ,
'description' => $description ,
'enabled' => $enabled ,
]
);
Example: Logging an Update
// From UpdateResourceAction.php:41-53
ResourceLog :: logAction (
action : ResourceAction :: Updated -> value ,
resourceName : $name ,
netbirdId : $resourceId ,
resourceAddress : $address ,
performedBy : $user -> name ,
changes : [
'name' => $name ,
'address' => $address ,
'description' => $description ,
'enabled' => $enabled ,
]
);
Every action class that modifies resources includes a corresponding ResourceLog::logAction() call to ensure complete audit coverage.
Viewing Activity Logs
Activity logs can be viewed through the admin dashboard or queried directly:
Recent Activity
// Get the 50 most recent logs
$recentLogs = ResourceLog :: orderBy ( 'created_at' , 'desc' )
-> limit ( 50 )
-> get ();
Filter by Action
// Get all approval actions
$approvals = ResourceLog :: where ( 'action' , ResourceAction :: Approved -> value )
-> orderBy ( 'created_at' , 'desc' )
-> get ();
Filter by Resource
// Get all logs for a specific resource
$resourceLogs = ResourceLog :: where ( 'netbird_id' , $resourceId )
-> orderBy ( 'created_at' , 'desc' )
-> get ();
Filter by User
// Get all actions performed by a specific user
$userActions = ResourceLog :: where ( 'performed_by' , $userName )
-> orderBy ( 'created_at' , 'desc' )
-> get ();
Audit Trail Use Cases
Compliance & Reporting Demonstrate who accessed what resources and when for regulatory compliance (SOC 2, HIPAA, etc.)
Security Investigations Track suspicious activity or unauthorized resource changes with complete attribution
Troubleshooting Identify when and why a resource was modified when investigating connectivity issues
Change Management Review the complete history of resource changes for documentation and rollback
Activity Log Badges
The system provides visual indicators for different action types:
// From ResourceAction.php:32-40
public function badgeClasses () : string
{
return match ( $this ) {
self :: Created , self :: Approved , self :: Enabled =>
'bg-green-100 text-green-800 dark:bg-green-900/50 dark:text-green-300' ,
self :: Updated =>
'bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-300' ,
self :: Deleted , self :: Denied =>
'bg-red-100 text-red-800 dark:bg-red-900/50 dark:text-red-300' ,
self :: Requested =>
'bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-300' ,
self :: Cancelled , self :: Disabled =>
'bg-zinc-100 text-zinc-800 dark:bg-zinc-700/50 dark:text-zinc-300' ,
};
}
This creates color-coded badges:
🟢 Green : Positive actions (created, approved, enabled)
🔵 Blue : Modifications (updated)
🔴 Red : Destructive actions (deleted, denied)
🟡 Amber : Pending actions (requested)
⚫ Gray : Neutral actions (cancelled, disabled)
Changes Tracking
The changes field captures action-specific details:
For Create/Update Actions
{
"name" : "Production API" ,
"address" : "api.example.com" ,
"description" : "Main production API endpoint" ,
"enabled" : true
}
For Toggle Actions
For Request Actions
{
"name" : "Database Server" ,
"address" : "10.50.1.100" ,
"description" : "Access to production database" ,
"enabled" : true ,
"requested_by" : "John Doe"
}
For Delete Actions
{
"name" : "Legacy Service" ,
"address" : "192.168.1.50" ,
"description" : "Deprecated service endpoint"
}
Pending Resource Logging
When a request is submitted, the PendingResource model provides a method to format changes for logging:
// From PendingResource.php:51-60
public function toLogChanges () : array
{
return [
'name' => $this -> name ,
'address' => $this -> address ,
'description' => $this -> description ,
'enabled' => $this -> enabled ,
'requested_by' => $this -> requested_by ,
];
}
This ensures consistent formatting across all request-related log entries.
Log Retention
Currently, logs are retained indefinitely. Consider implementing a retention policy based on your compliance requirements.
Suggested Retention Policies
Depending on your compliance requirements:
Use Case Suggested Retention General auditing 90 days SOC 2 compliance 1 year HIPAA compliance 6 years Financial industry 7 years
Implementing Log Cleanup
Example scheduled job to clean old logs:
// In app/Console/Kernel.php
$schedule -> call ( function () {
ResourceLog :: where ( 'created_at' , '<' , now () -> subDays ( 90 )) -> delete ();
}) -> daily ();
Querying Logs
Advanced Queries
Get logs with complex filters:
// Resources modified in the last 24 hours
$recentChanges = ResourceLog :: whereIn ( 'action' , [
ResourceAction :: Created -> value ,
ResourceAction :: Updated -> value ,
ResourceAction :: Deleted -> value ,
])
-> where ( 'created_at' , '>=' , now () -> subDay ())
-> orderBy ( 'created_at' , 'desc' )
-> get ();
// All denied requests
$deniedRequests = ResourceLog :: where ( 'action' , ResourceAction :: Denied -> value )
-> with ( 'user' ) // If you add a user relationship
-> orderBy ( 'created_at' , 'desc' )
-> get ();
Export Logs
Generate CSV export for compliance reporting:
$logs = ResourceLog :: orderBy ( 'created_at' , 'desc' ) -> get ();
$csv = Writer :: createFromString ( '' );
$csv -> insertOne ([ 'Date' , 'Action' , 'Resource' , 'Address' , 'Performed By' ]);
foreach ( $logs as $log ) {
$csv -> insertOne ([
$log -> created_at -> format ( 'Y-m-d H:i:s' ),
$log -> action ,
$log -> resource_name ,
$log -> resource_address ,
$log -> performed_by ,
]);
}
return response ( $csv -> toString ())
-> header ( 'Content-Type' , 'text/csv' )
-> header ( 'Content-Disposition' , 'attachment; filename="resource_logs.csv"' );
Best Practices
Never Delete Logs Logs are your audit trail. Archive old logs instead of deleting them if storage is a concern
Include Context Always include the user name and resource details so logs are self-documenting
Regular Reviews Periodically review logs to identify patterns, anomalies, or training opportunities
Secure Access Restrict log viewing to admins and compliance officers - logs contain sensitive information
Integration with External Systems
Sending Logs to SIEM
For enterprise deployments, stream logs to your Security Information and Event Management (SIEM) system:
// In ResourceLog model after creating a log
protected static function booted ()
{
static :: created ( function ( $log ) {
// Send to external SIEM
SiemService :: send ([
'timestamp' => $log -> created_at ,
'action' => $log -> action ,
'resource' => $log -> resource_name ,
'user' => $log -> performed_by ,
'changes' => $log -> changes ,
]);
});
}
Webhook Notifications
Trigger webhooks on specific actions for real-time alerting:
if ( $action === ResourceAction :: Deleted -> value ) {
WebhookService :: notify ( 'resource.deleted' , [
'resource' => $resourceName ,
'deleted_by' => $performedBy ,
'deleted_at' => now (),
]);
}
Summary
Activity logging in NetBird Selfservice provides:
✅ Complete audit trail of all resource operations
✅ User attribution for every action
✅ Detailed change tracking with before/after states
✅ Compliance support for regulatory requirements
✅ Troubleshooting data for investigating issues
✅ Security monitoring for detecting unauthorized changes
Every action that modifies resources is automatically logged with full context, creating a permanent, tamper-evident record of your network access management.