Activity log entries are retained for 12 months by default. Administrators can adjust the retention period in Admin → Settings. The GDPR retention cleanup cron job automatically purges entries older than the configured window.
Log tables at a glance
user_activity_log
This is the primary audit log. Every meaningful action performed by or on behalf of a user is written here, including page views, authentication events, admin operations, and guard page outcomes.Record structure
Encryption
Two fields in everyuser_activity_log row are encrypted using the platform’s authenticated PII encryption key:
ip_address— encrypted because an IP address is personal data under UK GDPR. Decrypted transparently for authorised staff in the activity log viewer.activity_details— a JSON blob containing event-specific context (page URLs, targeted user identities, action outcomes, etc.). Encrypted because this blob may contain names, emails, and other personal data depending on the event type.
enc:v1: prefix. The data is decrypted on-the-fly when rendered in the admin panel and is never written to application or server logs in plain text.
Activity types
Activity types follow a predictable naming pattern. The table below lists every activity type that PropOps writes, grouped by category.Authentication
Guard page flows
Guard pages are interstitial security checks shown between login and full platform access (email verification, IP location verification, document approval, and re-authentication). Every stage of every guard flow is logged.Email verification guard (verify)
IP location verification guard (ip)
Document approval guard (documents)
Re-authentication guard (reauth)
Page views
User management (staff actions)
These events are written when a staff member performs an action on another user’s account. Theactivity_details blob includes both the staff member’s identity and the target user’s identity.
Permissions management
Branch management
Tag management
Security administration
Error and system events
login_attempts
A dedicated table for raw login attempt records. This is separate fromuser_activity_log to allow efficient brute-force detection queries without decryption overhead.
Why it is logged: The security dashboard and brute-force detection logic query this table to identify suspicious IP addresses (5+ failures in 1 hour), targeted accounts (5+ failures in 24 hours), and multi-account spray attacks (3+ accounts from one IP in 24 hours). This data directly supports UK GDPR Article 33 breach notification obligations.
security_events
A secondary security-specific event log used in parallel withuser_activity_log. Currently populated by the IP guard PIN verification flow and other low-level auth events.
Why it exists alongside
user_activity_log: The security_events table is indexed for fast security-focused queries that span many users, whereas user_activity_log is the per-user audit trail. Both are written for IP guard PIN events so that security dashboards and per-user audit queries can each use the most efficient data source.
api_endpoint_usage_logs
Every API request is logged here for usage analytics, performance monitoring, and anomaly detection.
Why it is logged: Enables week-over-week API usage comparison, identification of unusual request patterns, and performance regression tracking. The security dashboard shows this week vs last week volume and highlights spikes.
ip_address is PII encrypted for the same reason as in user_activity_log.
system_security_alerts
Populated by the file integrity monitoring cron job and related automated checks.
Why it is logged: Any modification to a production application file that was not part of a deployment is a potential security incident. The cron job checksums every PHP file every hour and raises an alert on any unexpected change. All
file_integrity_violation alerts are treated as critical by the security dashboard regardless of their severity field.
What is encrypted in the logs
The following fields are encrypted with the platform’s authenticated PII encryption key (enc:v1: prefix):
All other log columns (user agent strings, activity types, timestamps, response codes) are stored unencrypted as they do not constitute personal data in isolation.
Encrypted values are decrypted transparently by the admin panel API before being returned to the browser. The raw encrypted values are never exposed to end users.
Retention and data minimisation
The GDPR retention cleanup cron job (
cleanup_gdpr_data.php) runs on a schedule and removes user_activity_log entries older than the configured retention window. This supports the UK GDPR data minimisation principle.
If your organisation requires longer retention for regulatory or contractual reasons, increase the retention period in Admin → Settings before the default 12-month window elapses. Records that have already been purged cannot be recovered.