diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
index 40acd9c0..a803f6c2 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
@@ -1,5 +1,3 @@
-// Copyright (c) The LEGO Group. All rights reserved.
-
 namespace LEGO.AsyncAPI.Bindings.Sns;
 
 using System;
@@ -9,20 +7,11 @@ namespace LEGO.AsyncAPI.Bindings.Sns;
 using System.Text.Json.Nodes;
 using LEGO.AsyncAPI.Models.Interfaces;
 using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
 
-public class Principal : IAsyncApiElement
+public abstract class Principal : IAsyncApiElement
 {
-    public Principal(KeyValuePair<string, StringOrStringList> value)
-    {
-        this.Value = new PrincipalObject(value);
-    }
-
-    public Principal()
-    {
-        this.Value = new PrincipalStar();
-    }
-
-    public IPrincipalValue Value { get; private set; }
+    public abstract void Serialize(IAsyncApiWriter writer);
 
     public static Principal Parse(ParseNode node)
     {
@@ -36,7 +25,7 @@ public static Principal Parse(ParseNode node)
                                                 $"Principal value without a property name can only be a string value of '*'.");
                 }
 
-                return new Principal();
+                return new PrincipalStar();
 
             case MapNode mapNode:
             {
@@ -51,7 +40,7 @@ public static Principal Parse(ParseNode node)
                     propertyNode.Name,
                     StringOrStringList.Parse(propertyNode.Value));
 
-                return new Principal(principalValue);
+                return new PrincipalObject(principalValue);
             }
 
             default:
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/IPrincipalValue.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
similarity index 50%
rename from src/LEGO.AsyncAPI.Bindings/Sns/IPrincipalValue.cs
rename to src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
index ab097a5a..a25c198f 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/IPrincipalValue.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
@@ -1,17 +1,10 @@
-// Copyright (c) The LEGO Group. All rights reserved.
-
 namespace LEGO.AsyncAPI.Bindings.Sns;
 
 using System;
 using System.Collections.Generic;
 using LEGO.AsyncAPI.Writers;
 
-public interface IPrincipalValue
-{
-    void Serialize(IAsyncApiWriter writer);
-}
-
-public struct PrincipalObject : IPrincipalValue
+public class PrincipalObject : Principal
 {
     private KeyValuePair<string, StringOrStringList> PrincipalValue;
 
@@ -20,7 +13,7 @@ public PrincipalObject(KeyValuePair<string, StringOrStringList> principalValue)
         this.PrincipalValue = principalValue;
     }
 
-    public void Serialize(IAsyncApiWriter writer)
+    public override void Serialize(IAsyncApiWriter writer)
     {
         if (writer is null)
         {
@@ -31,24 +24,4 @@ public void Serialize(IAsyncApiWriter writer)
         writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
         writer.WriteEndObject();
     }
-}
-
-public struct PrincipalStar : IPrincipalValue
-{
-    private string PrincipalValue;
-
-    public PrincipalStar()
-    {
-        this.PrincipalValue = "*";
-    }
-
-    public void Serialize(IAsyncApiWriter writer)
-    {
-        if (writer is null)
-        {
-            throw new ArgumentNullException(nameof(writer));
-        }
-
-        writer.WriteValue(this.PrincipalValue);
-    }
 }
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
new file mode 100644
index 00000000..533e9fb7
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
@@ -0,0 +1,24 @@
+namespace LEGO.AsyncAPI.Bindings.Sns;
+
+using System;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalStar : Principal
+{
+    private string PrincipalValue;
+
+    public PrincipalStar()
+    {
+        this.PrincipalValue = "*";
+    }
+
+    public override void Serialize(IAsyncApiWriter writer)
+    {
+        if (writer is null)
+        {
+            throw new ArgumentNullException(nameof(writer));
+        }
+
+        writer.WriteValue(this.PrincipalValue);
+    }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
index de16d1d4..170fe371 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
@@ -46,7 +46,7 @@ public void Serialize(IAsyncApiWriter writer)
 
             writer.WriteStartObject();
             writer.WriteRequiredProperty("effect", this.Effect.GetDisplayName());
-            writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Value.Serialize(w));
+            writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
             writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
             writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
             writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
index acffe8d3..2821f952 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
@@ -9,20 +9,11 @@ namespace LEGO.AsyncAPI.Bindings.Sqs;
 using System.Text.Json.Nodes;
 using LEGO.AsyncAPI.Models.Interfaces;
 using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
 
-public class Principal : IAsyncApiElement
+public abstract class Principal : IAsyncApiElement
 {
-    public Principal(KeyValuePair<string, StringOrStringList> value)
-    {
-        this.Value = new PrincipalObject(value);
-    }
-
-    public Principal()
-    {
-        this.Value = new PrincipalStar();
-    }
-
-    public IPrincipalValue Value { get; private set; }
+    public abstract void Serialize(IAsyncApiWriter writer);
 
     public static Principal Parse(ParseNode node)
     {
@@ -36,7 +27,7 @@ public static Principal Parse(ParseNode node)
                                                 $"Principal value without a property name can only be a string value of '*'.");
                 }
 
-                return new Principal();
+                return new PrincipalStar();
 
             case MapNode mapNode:
             {
@@ -51,7 +42,7 @@ public static Principal Parse(ParseNode node)
                     propertyNode.Name,
                     StringOrStringList.Parse(propertyNode.Value));
 
-                return new Principal(principalValue);
+                return new PrincipalObject(principalValue);
             }
 
             default:
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/IPrincipalValue.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
similarity index 51%
rename from src/LEGO.AsyncAPI.Bindings/Sqs/IPrincipalValue.cs
rename to src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
index 958aec9a..2652060d 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/IPrincipalValue.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
@@ -1,17 +1,10 @@
-// Copyright (c) The LEGO Group. All rights reserved.
-
 namespace LEGO.AsyncAPI.Bindings.Sqs;
 
 using System;
 using System.Collections.Generic;
 using LEGO.AsyncAPI.Writers;
 
-public interface IPrincipalValue
-{
-    void Serialize(IAsyncApiWriter writer);
-}
-
-public struct PrincipalObject : IPrincipalValue
+public class PrincipalObject : Principal
 {
     private KeyValuePair<string, StringOrStringList> PrincipalValue;
 
@@ -20,7 +13,7 @@ public PrincipalObject(KeyValuePair<string, StringOrStringList> principalValue)
         this.PrincipalValue = principalValue;
     }
 
-    public void Serialize(IAsyncApiWriter writer)
+    public override void Serialize(IAsyncApiWriter writer)
     {
         if (writer is null)
         {
@@ -31,24 +24,4 @@ public void Serialize(IAsyncApiWriter writer)
         writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
         writer.WriteEndObject();
     }
-}
-
-struct PrincipalStar : IPrincipalValue
-{
-    private string PrincipalValue;
-
-    public PrincipalStar()
-    {
-        this.PrincipalValue = "*";
-    }
-
-    public void Serialize(IAsyncApiWriter writer)
-    {
-        if (writer is null)
-        {
-            throw new ArgumentNullException(nameof(writer));
-        }
-
-        writer.WriteValue(this.PrincipalValue);
-    }
 }
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
new file mode 100644
index 00000000..9e54bc5a
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
@@ -0,0 +1,24 @@
+namespace LEGO.AsyncAPI.Bindings.Sqs;
+
+using System;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalStar : Principal
+{
+    private string PrincipalValue;
+
+    public PrincipalStar()
+    {
+        this.PrincipalValue = "*";
+    }
+
+    public override void Serialize(IAsyncApiWriter writer)
+    {
+        if (writer is null)
+        {
+            throw new ArgumentNullException(nameof(writer));
+        }
+
+        writer.WriteValue(this.PrincipalValue);
+    }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
index 2dfff3b9..4abc05a6 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
@@ -47,7 +47,7 @@ public void Serialize(IAsyncApiWriter writer)
 
             writer.WriteStartObject();
             writer.WriteRequiredProperty("effect", this.Effect.GetDisplayName());
-            writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Value.Serialize(w));
+            writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
             writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
             writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
             writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
index f3deb55c..fbb3622e 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
@@ -86,7 +86,7 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
                         new Statement()
                         {
                             Effect = Effect.Deny,
-                            Principal = new Principal(),
+                            Principal = new PrincipalStar(),
                             Action = new StringOrStringList(new AsyncApiAny(new List<string>()
                             {
                                 "sns:Publish",
@@ -105,7 +105,7 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
                         new Statement()
                         {
                             Effect = Effect.Allow,
-                            Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                            Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                 "AWS", new StringOrStringList(new AsyncApiAny(new List<string>
                                     { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
                             Action = new StringOrStringList(new AsyncApiAny("sns:Create")),
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
index 65978a80..3a0337a3 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
@@ -136,7 +136,7 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
                             new Statement()
                             {
                                 Effect = Effect.Deny,
-                                Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                     "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
                                 Action = new StringOrStringList(new AsyncApiAny(new List<string>
                                 {
@@ -166,7 +166,7 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
                             new Statement()
                             {
                                 Effect = Effect.Allow,
-                                Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                     "AWS", new StringOrStringList(new AsyncApiAny(new List<string>
                                         { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
                                 Action = new StringOrStringList(new AsyncApiAny("sqs:CreateQueue")),
@@ -223,7 +223,7 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
                             new Statement()
                             {
                                 Effect = Effect.Allow,
-                                Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                     "Service", new StringOrStringList(new AsyncApiAny("s3.amazonaws.com")))),
                                 Action = new StringOrStringList(new AsyncApiAny(new List<string>
                                 {
@@ -377,7 +377,7 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
                                 new Statement()
                                 {
                                     Effect = Effect.Deny,
-                                    Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                    Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                         "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
                                     Action = new StringOrStringList(new AsyncApiAny(new List<string>()
                                     {
@@ -398,7 +398,7 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
                                 new Statement()
                                 {
                                     Effect = Effect.Allow,
-                                    Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                    Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                         "AWS", new StringOrStringList(new AsyncApiAny(new List<string>
                                             { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
                                     Action = new StringOrStringList(new AsyncApiAny("sqs:CreateQueue")),
@@ -446,7 +446,7 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
                                 new Statement()
                                 {
                                     Effect = Effect.Allow,
-                                    Principal = new Principal(new KeyValuePair<string, StringOrStringList>(
+                                    Principal = new PrincipalObject(new KeyValuePair<string, StringOrStringList>(
                                         "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
                                     Action = new StringOrStringList(new AsyncApiAny(new List<string>
                                     {