// Package securitylog provides security event logging for audit purposes. // This captures security-relevant events for monitoring and forensics. package securitylog import ( "time" "go.uber.org/zap" ) // EventType defines the type of security event type EventType string const ( // Authentication events EventLoginAttempt EventType = "LOGIN_ATTEMPT" EventLoginSuccess EventType = "LOGIN_SUCCESS" EventLoginFailure EventType = "LOGIN_FAILURE" EventLogout EventType = "LOGOUT" EventSessionRestored EventType = "SESSION_RESTORED" EventSessionExpired EventType = "SESSION_EXPIRED" EventSessionRevoked EventType = "SESSION_REVOKED" EventTokenRefresh EventType = "TOKEN_REFRESH" EventTokenRefreshFail EventType = "TOKEN_REFRESH_FAILURE" // Registration events EventRegistration EventType = "REGISTRATION" EventEmailVerification EventType = "EMAIL_VERIFICATION" EventOTTRequest EventType = "OTT_REQUEST" EventOTTVerify EventType = "OTT_VERIFY" EventPasswordChallenge EventType = "PASSWORD_CHALLENGE" // Rate limiting events EventRateLimitExceeded EventType = "RATE_LIMIT_EXCEEDED" // Data access events EventCollectionCreate EventType = "COLLECTION_CREATE" EventCollectionUpdate EventType = "COLLECTION_UPDATE" EventCollectionDelete EventType = "COLLECTION_DELETE" EventCollectionAccess EventType = "COLLECTION_ACCESS" EventFileUpload EventType = "FILE_UPLOAD" EventFileDownload EventType = "FILE_DOWNLOAD" EventFileDelete EventType = "FILE_DELETE" EventFileAccess EventType = "FILE_ACCESS" EventFileOpen EventType = "FILE_OPEN" // Export events EventExportStart EventType = "EXPORT_START" EventExportComplete EventType = "EXPORT_COMPLETE" EventExportFailure EventType = "EXPORT_FAILURE" // Configuration events EventConfigChange EventType = "CONFIG_CHANGE" EventConfigIntegrityFail EventType = "CONFIG_INTEGRITY_FAILURE" EventCloudProviderChange EventType = "CLOUD_PROVIDER_CHANGE" // Security events EventSecurityValidationFail EventType = "SECURITY_VALIDATION_FAILURE" EventURLValidationFail EventType = "URL_VALIDATION_FAILURE" EventInputValidationFail EventType = "INPUT_VALIDATION_FAILURE" EventPathTraversalAttempt EventType = "PATH_TRAVERSAL_ATTEMPT" // Key management events EventMasterKeyDerived EventType = "MASTER_KEY_DERIVED" EventMasterKeyCleared EventType = "MASTER_KEY_CLEARED" EventPasswordCleared EventType = "PASSWORD_CLEARED" // Application lifecycle events EventAppStart EventType = "APP_START" EventAppShutdown EventType = "APP_SHUTDOWN" ) // EventOutcome indicates the result of an event type EventOutcome string const ( OutcomeSuccess EventOutcome = "SUCCESS" OutcomeFailure EventOutcome = "FAILURE" OutcomeBlocked EventOutcome = "BLOCKED" ) // SecurityEvent represents a security-relevant event type SecurityEvent struct { Timestamp time.Time `json:"timestamp"` EventType EventType `json:"event_type"` Outcome EventOutcome `json:"outcome"` UserEmail string `json:"user_email,omitempty"` // Masked email ResourceID string `json:"resource_id,omitempty"` ResourceType string `json:"resource_type,omitempty"` Details map[string]string `json:"details,omitempty"` ErrorMsg string `json:"error,omitempty"` } // Service provides security event logging type Service struct { logger *zap.Logger } // New creates a new security logging service func New(logger *zap.Logger) *Service { return &Service{ logger: logger.Named("security"), } } // ProvideService is the Wire provider for the security log service func ProvideService(logger *zap.Logger) *Service { return New(logger) } // LogEvent logs a security event func (s *Service) LogEvent(event *SecurityEvent) { event.Timestamp = time.Now().UTC() fields := []zap.Field{ zap.String("event_type", string(event.EventType)), zap.String("outcome", string(event.Outcome)), zap.Time("timestamp", event.Timestamp), } if event.UserEmail != "" { fields = append(fields, zap.String("user_email", event.UserEmail)) } if event.ResourceID != "" { fields = append(fields, zap.String("resource_id", event.ResourceID)) } if event.ResourceType != "" { fields = append(fields, zap.String("resource_type", event.ResourceType)) } if event.ErrorMsg != "" { fields = append(fields, zap.String("error", event.ErrorMsg)) } for k, v := range event.Details { fields = append(fields, zap.String("detail_"+k, v)) } switch event.Outcome { case OutcomeSuccess: s.logger.Info("Security event", fields...) case OutcomeFailure: s.logger.Warn("Security event", fields...) case OutcomeBlocked: s.logger.Warn("Security event (blocked)", fields...) default: s.logger.Info("Security event", fields...) } } // Helper methods for common events // LogLoginAttempt logs a login attempt func (s *Service) LogLoginAttempt(maskedEmail string) { s.LogEvent(&SecurityEvent{ EventType: EventLoginAttempt, Outcome: OutcomeSuccess, UserEmail: maskedEmail, }) } // LogLoginSuccess logs a successful login func (s *Service) LogLoginSuccess(maskedEmail string) { s.LogEvent(&SecurityEvent{ EventType: EventLoginSuccess, Outcome: OutcomeSuccess, UserEmail: maskedEmail, }) } // LogLoginFailure logs a failed login func (s *Service) LogLoginFailure(maskedEmail string, reason string) { s.LogEvent(&SecurityEvent{ EventType: EventLoginFailure, Outcome: OutcomeFailure, UserEmail: maskedEmail, ErrorMsg: reason, }) } // LogLogout logs a logout event func (s *Service) LogLogout(maskedEmail string) { s.LogEvent(&SecurityEvent{ EventType: EventLogout, Outcome: OutcomeSuccess, UserEmail: maskedEmail, }) } // LogRateLimitExceeded logs a rate limit exceeded event func (s *Service) LogRateLimitExceeded(maskedEmail string, operation string) { s.LogEvent(&SecurityEvent{ EventType: EventRateLimitExceeded, Outcome: OutcomeBlocked, UserEmail: maskedEmail, Details: map[string]string{ "operation": operation, }, }) } // LogFileAccess logs a file access event func (s *Service) LogFileAccess(maskedEmail string, fileID string, operation string, outcome EventOutcome) { s.LogEvent(&SecurityEvent{ EventType: EventFileAccess, Outcome: outcome, UserEmail: maskedEmail, ResourceID: fileID, ResourceType: "file", Details: map[string]string{ "operation": operation, }, }) } // LogCollectionAccess logs a collection access event func (s *Service) LogCollectionAccess(maskedEmail string, collectionID string, operation string, outcome EventOutcome) { s.LogEvent(&SecurityEvent{ EventType: EventCollectionAccess, Outcome: outcome, UserEmail: maskedEmail, ResourceID: collectionID, ResourceType: "collection", Details: map[string]string{ "operation": operation, }, }) } // LogSecurityValidationFailure logs a security validation failure func (s *Service) LogSecurityValidationFailure(eventType EventType, details map[string]string, errorMsg string) { s.LogEvent(&SecurityEvent{ EventType: eventType, Outcome: OutcomeBlocked, Details: details, ErrorMsg: errorMsg, }) } // LogExport logs an export operation func (s *Service) LogExport(maskedEmail string, eventType EventType, outcome EventOutcome, details map[string]string) { s.LogEvent(&SecurityEvent{ EventType: eventType, Outcome: outcome, UserEmail: maskedEmail, Details: details, }) } // LogConfigChange logs a configuration change func (s *Service) LogConfigChange(setting string, maskedEmail string) { s.LogEvent(&SecurityEvent{ EventType: EventConfigChange, Outcome: OutcomeSuccess, UserEmail: maskedEmail, Details: map[string]string{ "setting": setting, }, }) } // LogAppLifecycle logs application start/shutdown func (s *Service) LogAppLifecycle(eventType EventType) { s.LogEvent(&SecurityEvent{ EventType: eventType, Outcome: OutcomeSuccess, }) } // LogKeyManagement logs key management operations func (s *Service) LogKeyManagement(eventType EventType, maskedEmail string, outcome EventOutcome) { s.LogEvent(&SecurityEvent{ EventType: eventType, Outcome: outcome, UserEmail: maskedEmail, }) }