diff --git a/PluralKit.Core/Database/Migrations/9.sql b/PluralKit.Core/Database/Migrations/9.sql
index 47c7429c..60444326 100644
--- a/PluralKit.Core/Database/Migrations/9.sql
+++ b/PluralKit.Core/Database/Migrations/9.sql
@@ -1,11 +1,20 @@
 -- SCHEMA VERSION 9: 2020-xx-xx --
+-- Adds support for member groups.
 
 create table groups (
     id int primary key generated always as identity,
     hid char(5) unique not null,
     system int not null references systems(id) on delete cascade,
+    
     name text not null,
     description text,
+    icon text,
+    
+    -- Description columns follow the same pattern as usual: 1 = public, 2 = private
+    description_privacy integer check (description_privacy in (1, 2)) not null default 1,
+    icon_privacy integer check (icon_privacy in (1, 2)) not null default 1,
+    visibility integer check (visibility in (1, 2)) not null default 1,
+
     created timestamp with time zone not null default (current_timestamp at time zone 'utc')
 );
 
diff --git a/PluralKit.Core/Models/PKGroup.cs b/PluralKit.Core/Models/PKGroup.cs
index 276157dc..e553b902 100644
--- a/PluralKit.Core/Models/PKGroup.cs
+++ b/PluralKit.Core/Models/PKGroup.cs
@@ -11,6 +11,11 @@ namespace PluralKit.Core
 
         public string Name { get; } = null!;
         public string? Description { get; }
+        public string? Icon { get; }
+
+        public PrivacyLevel DescriptionPrivacy { get; }
+        public PrivacyLevel IconPrivacy { get; }
+        public PrivacyLevel Visibility { get; }
         
         public Instant Created { get; }
     }
diff --git a/PluralKit.Core/Models/Patch/GroupPatch.cs b/PluralKit.Core/Models/Patch/GroupPatch.cs
index 5c4143fd..02281d8c 100644
--- a/PluralKit.Core/Models/Patch/GroupPatch.cs
+++ b/PluralKit.Core/Models/Patch/GroupPatch.cs
@@ -5,9 +5,18 @@ namespace PluralKit.Core
     {
         public Partial<string> Name { get; set; }
         public Partial<string?> Description { get; set; }
+        public Partial<string?> Icon { get; set; }
+        
+        public Partial<PrivacyLevel> DescriptionPrivacy { get; set; }
+        public Partial<PrivacyLevel> IconPrivacy { get; set; }
+        public Partial<PrivacyLevel> Visibility { get; set; }
 
         public override UpdateQueryBuilder Apply(UpdateQueryBuilder b) => b
             .With("name", Name)
-            .With("description", Description);
+            .With("description", Description)
+            .With("icon", Icon)
+            .With("description_privacy", DescriptionPrivacy)
+            .With("icon_privacy", IconPrivacy)
+            .With("visibility", Visibility);
     }
 }
\ No newline at end of file