diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go
index 3bb704e..1903bd4 100644
--- a/pkg/datastore/datastore.go
+++ b/pkg/datastore/datastore.go
@@ -24,6 +24,7 @@ const (
 )
 
 type Datastore interface {
+	AuditEvents() AuditEvents
 	Mapfixes() Mapfixes
 	Operations() Operations
 	Submissions() Submissions
@@ -31,6 +32,14 @@ type Datastore interface {
 	ScriptPolicy() ScriptPolicy
 }
 
+type AuditEvents interface {
+	Get(ctx context.Context, id int64) (model.AuditEvent, error)
+	Create(ctx context.Context, smap model.AuditEvent) (model.AuditEvent, error)
+	Update(ctx context.Context, id int64, values OptionalMap) error
+	Delete(ctx context.Context, id int64) error
+	List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.AuditEvent, error)
+}
+
 type Mapfixes interface {
 	Get(ctx context.Context, id int64) (model.Mapfix, error)
 	GetList(ctx context.Context, id []int64) ([]model.Mapfix, error)
diff --git a/pkg/datastore/gormstore/audit_events.go b/pkg/datastore/gormstore/audit_events.go
new file mode 100644
index 0000000..efaab4d
--- /dev/null
+++ b/pkg/datastore/gormstore/audit_events.go
@@ -0,0 +1,64 @@
+package gormstore
+
+import (
+	"context"
+	"errors"
+
+	"git.itzana.me/strafesnet/maps-service/pkg/datastore"
+	"git.itzana.me/strafesnet/maps-service/pkg/model"
+	"gorm.io/gorm"
+)
+
+type AuditEvents struct {
+	db *gorm.DB
+}
+
+func (env *AuditEvents) Get(ctx context.Context, id int64) (model.AuditEvent, error) {
+	var mdl model.AuditEvent
+	if err := env.db.First(&mdl, id).Error; err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return mdl, datastore.ErrNotExist
+		}
+		return mdl, err
+	}
+	return mdl, nil
+}
+
+func (env *AuditEvents) Create(ctx context.Context, smap model.AuditEvent) (model.AuditEvent, error) {
+	if err := env.db.Create(&smap).Error; err != nil {
+		return smap, err
+	}
+
+	return smap, nil
+}
+
+func (env *AuditEvents) Update(ctx context.Context, id int64, values datastore.OptionalMap) error {
+	if err := env.db.Model(&model.AuditEvent{}).Where("id = ?", id).Updates(values.Map()).Error; err != nil {
+		if err == gorm.ErrRecordNotFound {
+			return datastore.ErrNotExist
+		}
+		return err
+	}
+
+	return nil
+}
+
+func (env *AuditEvents) Delete(ctx context.Context, id int64) error {
+	if err := env.db.Delete(&model.AuditEvent{}, id).Error; err != nil {
+		if err == gorm.ErrRecordNotFound {
+			return datastore.ErrNotExist
+		}
+		return err
+	}
+
+	return nil
+}
+
+func (env *AuditEvents) List(ctx context.Context, filters datastore.OptionalMap, page model.Page) ([]model.AuditEvent, error) {
+	var events []model.AuditEvent
+	if err := env.db.Where(filters.Map()).Offset(int((page.Number - 1) * page.Size)).Limit(int(page.Size)).Find(&events).Error; err != nil {
+		return nil, err
+	}
+
+	return events, nil
+}
diff --git a/pkg/datastore/gormstore/db.go b/pkg/datastore/gormstore/db.go
index e4d0ed3..127cfe0 100644
--- a/pkg/datastore/gormstore/db.go
+++ b/pkg/datastore/gormstore/db.go
@@ -31,6 +31,7 @@ func New(ctx *cli.Context) (datastore.Datastore, error) {
 
 	if ctx.Bool("migrate") {
 		if err := db.AutoMigrate(
+			&model.AuditEvent{},
 			&model.Mapfix{},
 			&model.Operation{},
 			&model.Submission{},
diff --git a/pkg/datastore/gormstore/gormstore.go b/pkg/datastore/gormstore/gormstore.go
index 7d88b12..da8fe14 100644
--- a/pkg/datastore/gormstore/gormstore.go
+++ b/pkg/datastore/gormstore/gormstore.go
@@ -9,6 +9,10 @@ type Gormstore struct {
 	db *gorm.DB
 }
 
+func (g Gormstore) AuditEvents() datastore.AuditEvents {
+	return &AuditEvents{db: g.db}
+}
+
 func (g Gormstore) Mapfixes() datastore.Mapfixes {
 	return &Mapfixes{db: g.db}
 }