diff --git a/pkg/service/audit_events.go b/pkg/service/audit_events.go
new file mode 100644
index 0000000..38522f6
--- /dev/null
+++ b/pkg/service/audit_events.go
@@ -0,0 +1,200 @@
+package service
+
+import (
+	"context"
+	"encoding/json"
+
+	"git.itzana.me/strafesnet/maps-service/pkg/api"
+	"git.itzana.me/strafesnet/maps-service/pkg/datastore"
+	"git.itzana.me/strafesnet/maps-service/pkg/model"
+)
+
+// CreateMapfixAuditComment implements createMapfixAuditComment operation.
+//
+// Post a comment to the audit log
+//
+// POST /mapfixes/{MapfixID}/comment
+func (svc *Service) CreateMapfixAuditComment(ctx context.Context, req api.CreateMapfixAuditCommentReq, params api.CreateMapfixAuditCommentParams) (error) {
+	userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
+	if !ok {
+		return ErrUserInfo
+	}
+
+	has_role, err := userInfo.HasRoleMapfixReview()
+	if err != nil {
+		return err
+	}
+	if !has_role {
+		return ErrPermissionDeniedNeedRoleMapReview
+	}
+
+	userId, err := userInfo.GetUserID()
+	if err != nil {
+		return err
+	}
+
+	data := []byte{}
+	_, err = req.Read(data)
+	if err != nil {
+		return err
+	}
+	Comment := string(data)
+
+	event_data := model.AuditEventDataComment{
+		Comment: Comment,
+	}
+
+	EventData, err := json.Marshal(event_data)
+	if err != nil {
+		return err
+	}
+
+	_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
+		ID:           0,
+		User:         userId,
+		ResourceType: model.ResourceMapfix,
+		ResourceID:   params.MapfixID,
+		EventType:    model.AuditEventTypeComment,
+		EventData:    EventData,
+	})
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// ListMapfixAuditEvents invokes listMapfixAuditEvents operation.
+//
+// Retrieve a list of audit events.
+//
+// GET /mapfixes/{MapfixID}/audit-events
+func (svc *Service) ListMapfixAuditEvents(ctx context.Context, params api.ListMapfixAuditEventsParams) ([]api.AuditEvent, error) {
+	filter := datastore.Optional()
+
+	filter.Add("resource_type", model.ResourceMapfix)
+	filter.Add("resource_id", params.MapfixID)
+
+	items, err := svc.DB.AuditEvents().List(ctx, filter, model.Page{
+		Number: params.Page,
+		Size:   params.Limit,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var resp []api.AuditEvent
+	for _, item := range items {
+		EventData := api.AuditEventEventData{}
+		err = EventData.UnmarshalJSON(item.EventData)
+		if err != nil {
+			return nil, err
+		}
+		resp = append(resp, api.AuditEvent{
+			ID:           item.ID,
+			Date:         item.CreatedAt.Unix(),
+			User:         int64(item.User),
+			ResourceType: int32(item.ResourceType),
+			ResourceID:   item.ResourceID,
+			EventType:    int32(item.EventType),
+			EventData:    EventData,
+		})
+	}
+
+	return resp, nil
+}
+
+// CreateSubmissionAuditComment implements createSubmissionAuditComment operation.
+//
+// Post a comment to the audit log
+//
+// POST /submissions/{SubmissionID}/comment
+func (svc *Service) CreateSubmissionAuditComment(ctx context.Context, req api.CreateSubmissionAuditCommentReq, params api.CreateSubmissionAuditCommentParams) (error) {
+	userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
+	if !ok {
+		return ErrUserInfo
+	}
+
+	has_role, err := userInfo.HasRoleSubmissionReview()
+	if err != nil {
+		return err
+	}
+	if !has_role {
+		return ErrPermissionDeniedNeedRoleMapReview
+	}
+
+	userId, err := userInfo.GetUserID()
+	if err != nil {
+		return err
+	}
+
+	data := []byte{}
+	_, err = req.Read(data)
+	if err != nil {
+		return err
+	}
+	Comment := string(data)
+
+	event_data := model.AuditEventDataComment{
+		Comment: Comment,
+	}
+
+	EventData, err := json.Marshal(event_data)
+	if err != nil {
+		return err
+	}
+
+	_, err = svc.DB.AuditEvents().Create(ctx, model.AuditEvent{
+		ID:           0,
+		User:         userId,
+		ResourceType: model.ResourceSubmission,
+		ResourceID:   params.SubmissionID,
+		EventType:    model.AuditEventTypeComment,
+		EventData:    EventData,
+	})
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// ListSubmissionAuditEvents invokes listSubmissionAuditEvents operation.
+//
+// Retrieve a list of audit events.
+//
+// GET /submissions/{SubmissionID}/audit-events
+func (svc *Service) ListSubmissionAuditEvents(ctx context.Context, params api.ListSubmissionAuditEventsParams) ([]api.AuditEvent, error) {
+	filter := datastore.Optional()
+
+	filter.Add("resource_type", model.ResourceSubmission)
+	filter.Add("resource_id", params.SubmissionID)
+
+	items, err := svc.DB.AuditEvents().List(ctx, filter, model.Page{
+		Number: params.Page,
+		Size:   params.Limit,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var resp []api.AuditEvent
+	for _, item := range items {
+		EventData := api.AuditEventEventData{}
+		err = EventData.UnmarshalJSON(item.EventData)
+		if err != nil {
+			return nil, err
+		}
+		resp = append(resp, api.AuditEvent{
+			ID:           item.ID,
+			Date:         item.CreatedAt.Unix(),
+			User:         int64(item.User),
+			ResourceType: int32(item.ResourceType),
+			ResourceID:   item.ResourceID,
+			EventType:    int32(item.EventType),
+			EventData:    EventData,
+		})
+	}
+
+	return resp, nil
+}