Audit Trails
On this page
- Overview
- Built-In Audit Log
- Audit Log Schema
- Query Patterns
- Who Accessed Patient Data?
- What Changed Today?
- Failed Access Attempts
- Activity by User
- Programmatic Access
- Rust
- Python
- Custom Audit Tables
- Compliance Reports
- HIPAA Audit Report
- Suspicious Activity Report
- Access Without Justification
- Alerting on Suspicious Activity
- Tamper Detection
- Retention Policy
- Best Practices
- 1. Always Provide Justification for PHI Access
- 2. Log All Access, Not Just Modifications
- 3. Capture Client Context
- 4. Review Audit Logs Regularly
- 5. Test Audit Trail Completeness
- Export Audit Logs
- Related Documentation
Implement comprehensive audit logging in Kimberlite applications.
Overview
Kimberlite provides audit trails by default—every write is logged. This recipe shows how to:
- Query audit logs
- Track who did what and when
- Generate compliance reports
- Implement custom audit logic
Built-In Audit Log
Every operation is automatically logged:
-- Query the system audit log
SELECT * FROM __audit
WHERE entity_type = 'Patient'
AND entity_id = 123
ORDER BY timestamp DESC;
Result:
| timestamp | user_id | operation | entity_type | entity_id | details |
|---------------------|---------|-----------|-------------|-----------|-----------------|
| 2024-01-15 10:30:00 | 456 | UPDATE | Patient | 123 | name changed |
| 2024-01-14 09:15:00 | 789 | READ | Patient | 123 | viewed record |
| 2024-01-10 14:20:00 | 456 | CREATE | Patient | 123 | initial insert |
Audit Log Schema
The system audit log includes:
Query Patterns
Who Accessed Patient Data?
SELECT
user_id,
operation,
timestamp,
ip_address
FROM __audit
WHERE entity_type = 'Patient'
AND entity_id = 123
AND timestamp > NOW - INTERVAL '30 days'
ORDER BY timestamp DESC;
What Changed Today?
SELECT
entity_type,
entity_id,
operation,
user_id,
timestamp
FROM __audit
WHERE timestamp > CURRENT_DATE
AND operation IN ('CREATE', 'UPDATE', 'DELETE')
ORDER BY timestamp DESC;
Failed Access Attempts
SELECT
user_id,
entity_type,
entity_id,
timestamp,
error_code
FROM __audit
WHERE operation = 'READ'
AND success = false
ORDER BY timestamp DESC
LIMIT 100;
Activity by User
SELECT
user_id,
COUNT(*) as operation_count,
MIN(timestamp) as first_activity,
MAX(timestamp) as last_activity
FROM __audit
WHERE timestamp > NOW - INTERVAL '24 hours'
GROUP BY user_id
ORDER BY operation_count DESC;
Programmatic Access
Rust
use Client;
Python
=
=
=
=
=
=
return
Custom Audit Tables
For application-specific auditing:
-- Custom audit table for sensitive operations
(
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
action TEXT NOT NULL,
patient_id BIGINT,
phi_accessed BOOLEAN, -- Was PHI accessed?
justification TEXT, -- Required for PHI access
timestamp TIMESTAMP NOT NULL,
ip_address TEXT,
user_agent TEXT
);
ON hipaa_audit_log(patient_id);
ON hipaa_audit_log(timestamp);
Log PHI access:
Compliance Reports
HIPAA Audit Report
-- All PHI access in the last year
SELECT
user_id,
action,
patient_id,
justification,
timestamp,
ip_address
FROM hipaa_audit_log
WHERE phi_accessed = true
AND timestamp > NOW - INTERVAL '1 year'
ORDER BY timestamp DESC;
Suspicious Activity Report
-- Users who accessed >100 patient records in 1 hour
SELECT
user_id,
COUNT(DISTINCT patient_id) as patients_accessed,
MIN(timestamp) as window_start,
MAX(timestamp) as window_end
FROM hipaa_audit_log
WHERE phi_accessed = true
AND timestamp > NOW - INTERVAL '1 hour'
GROUP BY user_id
HAVING COUNT(DISTINCT patient_id) > 100;
Access Without Justification
-- PHI access without proper justification
SELECT * FROM hipaa_audit_log
WHERE phi_accessed = true
AND (justification IS NULL OR justification = '')
AND timestamp > NOW - INTERVAL '30 days';
Alerting on Suspicious Activity
use Client;
Tamper Detection
Audit logs are tamper-evident via hash chaining:
Retention Policy
Configure audit log retention:
// Keep audit logs for 7 years (HIPAA requirement)
let retention = from_secs;
db.set_audit_retention?;
Legal hold: Audit logs under legal hold are never deleted.
Best Practices
1. Always Provide Justification for PHI Access
// Bad: No justification
audit.log_access?;
// Good: Clear justification
audit.log_access?;
2. Log All Access, Not Just Modifications
-- Log reads too (required for HIPAA)
INSERT INTO __audit (operation, entity_type, entity_id, user_id)
VALUES ('READ', 'Patient', 123, current_user_id);
3. Capture Client Context
4. Review Audit Logs Regularly
# Weekly audit review
# Monthly compliance check
5. Test Audit Trail Completeness
Export Audit Logs
Generate compliance reports:
// Export audit log for regulators
db.export_audit_log?;
Related Documentation
- Compliance - Compliance architecture
- Time-Travel Queries - Historical data access
- Multi-Tenant Queries - Tenant isolation
Key Takeaway: Kimberlite provides audit trails by default. Every operation is logged, tamper-evident, and queryable. Build on this foundation for compliance-specific requirements.