useAudit
Comprehensive audit logging for compliance, security monitoring, and forensic analysis.
Compliance Support: SOC 2, ISO 27001, HIPAA, PCI DSS audit requirements
Import
import { useAudit } from '@heliorim/sdk-react';Type Signature
interface AuditState {
logs: AuditLog[];
filters: AuditFilters;
isLoading: boolean;
error: Error | null;
retention: RetentionPolicy;
}
interface AuditActions {
log: (event: AuditEvent) => Promise<void>;
query: (filters: AuditFilters) => Promise<AuditLog[]>;
export: (format: ExportFormat, filters?: AuditFilters) => Promise<Blob>;
getRetention: () => Promise<RetentionPolicy>;
setRetention: (policy: RetentionPolicy) => Promise<void>;
archive: (before: Date) => Promise<void>;
search: (query: string) => Promise<AuditLog[]>;
getCompliance: (standard: ComplianceStandard) => Promise<ComplianceReport>;
}
interface AuditLog {
id: string;
timestamp: number;
eventType: EventType;
actor: Actor;
action: string;
resource: Resource;
result: 'success' | 'failure' | 'error';
metadata: Record<string, any>;
ip: string;
userAgent?: string;
location?: GeoLocation;
riskScore?: number;
}
interface AuditEvent {
type: EventType;
action: string;
resource?: Resource;
metadata?: Record<string, any>;
severity?: 'low' | 'medium' | 'high' | 'critical';
}
interface Actor {
id: string;
type: 'user' | 'system' | 'api' | 'admin';
email?: string;
name?: string;
roles?: string[];
}
interface Resource {
type: string;
id: string;
name?: string;
owner?: string;
}
interface AuditFilters {
startDate?: Date;
endDate?: Date;
eventTypes?: EventType[];
actors?: string[];
resources?: string[];
results?: ('success' | 'failure' | 'error')[];
severity?: ('low' | 'medium' | 'high' | 'critical')[];
}
type EventType =
| 'authentication'
| 'authorization'
| 'data_access'
| 'data_modification'
| 'configuration_change'
| 'user_management'
| 'security_event'
| 'system_event';
type UseAuditReturn = AuditState & AuditActions;Basic Usage
function AuditMonitoring() {
const {
logs,
log,
query,
search,
export: exportLogs
} = useAudit();
const { user } = useAuth();
// Log authentication events
useEffect(() => {
if (user) {
log({
type: 'authentication',
action: 'login_success',
resource: {
type: 'session',
id: user.sessionId,
owner: user.id
},
metadata: {
method: 'passkey',
deviceTrust: 85
}
});
}
}, [user]);
// Log sensitive data access
const accessSensitiveData = async (dataId: string) => {
await log({
type: 'data_access',
action: 'view_sensitive_data',
resource: {
type: 'document',
id: dataId,
name: 'Financial Report Q4'
},
severity: 'high',
metadata: {
classification: 'confidential',
reason: 'audit_review'
}
});
// Perform the actual data access
const data = await fetchSensitiveData(dataId);
return data;
};
// Query recent security events
const getSecurityEvents = async () => {
const events = await query({
eventTypes: ['security_event', 'authentication'],
results: ['failure', 'error'],
startDate: new Date(Date.now() - 24 * 60 * 60 * 1000), // Last 24 hours
severity: ['high', 'critical']
});
return events;
};
// Export for compliance
const generateComplianceReport = async () => {
const blob = await exportLogs('csv', {
startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), // Last 30 days
eventTypes: ['authentication', 'authorization', 'data_access']
});
// Download the report
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `audit-report-${Date.now()}.csv`;
a.click();
};
return (
<div className="audit-monitoring">
<h3>Audit Log Viewer</h3>
<div className="filters">
<button onClick={getSecurityEvents}>
Show Security Events
</button>
<button onClick={generateComplianceReport}>
Export Compliance Report
</button>
</div>
<div className="audit-logs">
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>Event</th>
<th>Actor</th>
<th>Action</th>
<th>Resource</th>
<th>Result</th>
</tr>
</thead>
<tbody>
{logs.map(log => (
<tr key={log.id} className={log.result === 'failure' ? 'error' : ''}>
<td>{new Date(log.timestamp).toLocaleString()}</td>
<td>{log.eventType}</td>
<td>{log.actor.email ?? log.actor.id}</td>
<td>{log.action}</td>
<td>{log.resource?.name ?? log.resource?.id}</td>
<td>{log.result}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}Event Logging Patterns
Authentication & Authorization
function AuthenticationAudit() {
const { log } = useAudit();
const { authenticate } = usePasskey();
const auditedAuthentication = async () => {
const startTime = Date.now();
try {
await authenticate();
// Log successful authentication
await log({
type: 'authentication',
action: 'passkey_authentication',
metadata: {
duration: Date.now() - startTime,
userVerification: true,
authenticatorType: 'platform'
}
});
} catch (error: any) {
// Log failed authentication
await log({
type: 'authentication',
action: 'passkey_authentication_failed',
severity: 'high',
metadata: {
duration: Date.now() - startTime,
errorCode: error.name,
errorMessage: error.message,
attemptNumber: getAttemptCount()
}
});
// Check for suspicious patterns
if (getAttemptCount() > 3) {
await log({
type: 'security_event',
action: 'multiple_failed_attempts',
severity: 'critical',
metadata: {
attempts: getAttemptCount(),
blockApplied: true
}
});
}
throw error;
}
};
const auditedAuthorization = async (resource: string, action: string) => {
const hasPermission = await checkPermission(resource, action);
await log({
type: 'authorization',
action: hasPermission ? 'access_granted' : 'access_denied',
resource: {
type: 'api_endpoint',
id: resource,
name: action
},
metadata: {
requiredPermission: action,
userPermissions: getUserPermissions(),
result: hasPermission
}
});
if (!hasPermission) {
throw new Error('Access denied');
}
};
return { auditedAuthentication, auditedAuthorization };
}Data Operations
function DataOperationAudit() {
const { log } = useAudit();
const auditedDataRead = async (dataId: string, classification: string) => {
const data = await fetchData(dataId);
await log({
type: 'data_access',
action: 'read',
resource: {
type: 'data_object',
id: dataId,
name: data.name
},
metadata: {
classification,
size: JSON.stringify(data).length,
fields: Object.keys(data)
},
severity: classification === 'sensitive' ? 'high' : 'low'
});
return data;
};
const auditedDataModification = async (
dataId: string,
oldData: any,
newData: any
) => {
const changes = computeChanges(oldData, newData);
await log({
type: 'data_modification',
action: 'update',
resource: {
type: 'data_object',
id: dataId
},
metadata: {
changeCount: changes.length,
changes: changes.map(c => ({
field: c.field,
oldValue: maskSensitive(c.oldValue),
newValue: maskSensitive(c.newValue)
})),
backup: createBackupReference(oldData)
},
severity: 'medium'
});
return await updateData(dataId, newData);
};
const auditedDataDeletion = async (dataId: string, reason: string) => {
const data = await fetchData(dataId);
// Create backup before deletion
const backupId = await createBackup(data);
await log({
type: 'data_modification',
action: 'delete',
resource: {
type: 'data_object',
id: dataId,
name: data.name
},
metadata: {
reason,
backupId,
permanentDeletion: false,
scheduledPurge: Date.now() + 30 * 24 * 60 * 60 * 1000 // 30 days
},
severity: 'high'
});
return await softDelete(dataId);
};
return { auditedDataRead, auditedDataModification, auditedDataDeletion };
}Configuration Changes
function ConfigurationAudit() {
const { log } = useAudit();
const auditConfigChange = async (
configType: string,
oldConfig: any,
newConfig: any,
approvedBy?: string
) => {
const changes = diff(oldConfig, newConfig);
await log({
type: 'configuration_change',
action: 'update_configuration',
resource: {
type: 'configuration',
id: configType,
name: `${configType} Settings`
},
metadata: {
changes,
previousValues: oldConfig,
newValues: newConfig,
approvedBy,
rollbackAvailable: true,
validationPassed: await validateConfig(newConfig)
},
severity: isSecurityConfig(configType) ? 'high' : 'medium'
});
};
const auditPermissionChange = async (
userId: string,
oldRoles: string[],
newRoles: string[],
reason: string
) => {
const added = newRoles.filter(r => !oldRoles.includes(r));
const removed = oldRoles.filter(r => !newRoles.includes(r));
await log({
type: 'user_management',
action: 'permission_change',
resource: {
type: 'user',
id: userId
},
metadata: {
rolesAdded: added,
rolesRemoved: removed,
reason,
approvalRequired: added.includes('admin'),
effectiveDate: Date.now()
},
severity: added.includes('admin') ? 'critical' : 'medium'
});
};
return { auditConfigChange, auditPermissionChange };
}Compliance Reporting
Compliance Standards
function ComplianceReporting() {
const { getCompliance, export: exportAudit } = useAudit();
const generateSOC2Report = async () => {
const report = await getCompliance('SOC2');
return {
period: report.period,
controls: {
security: report.controls.filter(c => c.category === 'security'),
availability: report.controls.filter(c => c.category === 'availability'),
integrity: report.controls.filter(c => c.category === 'integrity'),
confidentiality: report.controls.filter(c => c.category === 'confidentiality'),
privacy: report.controls.filter(c => c.category === 'privacy')
},
evidence: report.evidence,
exceptions: report.exceptions,
recommendations: report.recommendations
};
};
const generateHIPAAReport = async () => {
const report = await getCompliance('HIPAA');
// Check for PHI access
const phiAccess = await query({
eventTypes: ['data_access'],
metadata: { dataType: 'PHI' }
});
return {
administrativeSafeguards: report.administrativeSafeguards,
physicalSafeguards: report.physicalSafeguards,
technicalSafeguards: report.technicalSafeguards,
phiAccessLog: phiAccess,
breachAssessment: report.breachAssessment,
trainingCompliance: report.trainingRecords
};
};
const generateGDPRReport = async () => {
const report = await getCompliance('GDPR');
return {
dataProcessingActivities: report.processingActivities,
consentRecords: report.consentManagement,
dataSubjectRequests: report.subjectRequests,
dataBreaches: report.breaches,
privacyImpactAssessments: report.PIAs,
crossBorderTransfers: report.transfers
};
};
return (
<div className="compliance-reporting">
<h3>Compliance Reports</h3>
<button onClick={generateSOC2Report}>
Generate SOC 2 Report
</button>
<button onClick={generateHIPAAReport}>
Generate HIPAA Report
</button>
<button onClick={generateGDPRReport}>
Generate GDPR Report
</button>
</div>
);
}Advanced Features
Real-time Monitoring
function RealTimeMonitoring() {
const { logs, log } = useAudit();
const [alerts, setAlerts] = useState<Alert[]>([]);
// Monitor for suspicious patterns
useEffect(() => {
const checkPatterns = () => {
// Multiple failed attempts from same IP
const recentFailures = logs.filter(l =>
l.result === 'failure' &&
l.timestamp > Date.now() - 5 * 60 * 1000 // Last 5 minutes
);
const ipCounts = recentFailures.reduce((acc, log) => {
acc[log.ip] = (acc[log.ip] ?? 0) + 1;
return acc;
}, {} as Record<string, number>);
Object.entries(ipCounts).forEach(([ip, count]) => {
if (count > 5) {
const alert: Alert = {
type: 'brute_force',
severity: 'critical',
message: `Multiple failed attempts from IP: ${ip}`,
timestamp: Date.now()
};
setAlerts(prev => [...prev, alert]);
// Log security event
log({
type: 'security_event',
action: 'brute_force_detected',
severity: 'critical',
metadata: { ip, attempts: count }
});
}
});
// Unusual access patterns
const unusualHours = logs.filter(l => {
const hour = new Date(l.timestamp).getHours();
return (hour < 6 ?? hour > 22) && l.eventType === 'data_access';
});
if (unusualHours.length > 0) {
setAlerts(prev => [...prev, {
type: 'unusual_activity',
severity: 'medium',
message: 'Data access during unusual hours detected',
timestamp: Date.now()
}]);
}
};
const interval = setInterval(checkPatterns, 30000); // Check every 30 seconds
return () => clearInterval(interval);
}, [logs]);
return (
<div className="real-time-monitoring">
<h3>Security Alerts</h3>
{alerts.map((alert, i) => (
<div key={i} className={`alert ${alert.severity}`}>
<span>{new Date(alert.timestamp).toLocaleString()}</span>
<span>{alert.message}</span>
</div>
))}
</div>
);
}Retention Management
function RetentionManagement() {
const { getRetention, setRetention, archive } = useAudit();
const [policy, setPolicy] = useState<RetentionPolicy | null>(null);
useEffect(() => {
getRetention().then(setPolicy);
}, []);
const updateRetentionPolicy = async (newPolicy: Partial<RetentionPolicy>) => {
await setRetention({
...policy!,
...newPolicy
});
setPolicy(await getRetention());
};
const archiveOldLogs = async () => {
const cutoffDate = new Date();
cutoffDate.setMonth(cutoffDate.getMonth() - policy!.archiveAfterMonths);
await archive(cutoffDate);
console.log(`Archived logs older than ${cutoffDate.toLocaleDateString()}`);
};
return (
<div className="retention-management">
<h3>Retention Policy</h3>
{policy && (
<div>
<label>
Retain logs for (days):
<input
type="number"
value={policy.retentionDays}
onChange={(e) => updateRetentionPolicy({
retentionDays: parseInt(e.target.value)
})}
/>
</label>
<label>
Archive after (months):
<input
type="number"
value={policy.archiveAfterMonths}
onChange={(e) => updateRetentionPolicy({
archiveAfterMonths: parseInt(e.target.value)
})}
/>
</label>
<label>
<input
type="checkbox"
checked={policy.compressArchives}
onChange={(e) => updateRetentionPolicy({
compressArchives: e.target.checked
})}
/>
Compress archived logs
</label>
<button onClick={archiveOldLogs}>
Archive Old Logs Now
</button>
</div>
)}
</div>
);
}Security Considerations
Audit Log Protection:
- Audit logs are immutable once written
- Cryptographic signatures ensure integrity
- Logs are encrypted at rest
- Access requires special audit permissions
- Deletion requires multiple approvals
Best Practices
✓ Recommended
- Log all authentication attempts
- Include sufficient context in metadata
- Implement real-time alerting
- Regular compliance report generation
- Automated log archival
- Separate audit log storage
- Regular audit log reviews
⚠️ Avoid
- Logging sensitive data in plaintext
- Deleting audit logs prematurely
- Ignoring failed authentication patterns
- Manual log management
- Insufficient log detail