diff --git a/src/BuildingBlocks/Security/Authorization/AuthorizationPolicySet.cs b/src/BuildingBlocks/Security/Authorization/AuthorizationPolicySet.cs
new file mode 100644
index 0000000..6cc5dd3
--- /dev/null
+++ b/src/BuildingBlocks/Security/Authorization/AuthorizationPolicySet.cs
@@ -0,0 +1,50 @@
+namespace OpenHealthOS.Security.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+
+///
+/// Evaluates a collection of authorization policies using AND semantics.
+///
+public sealed class AuthorizationPolicySet : IAuthorizationPolicySet
+{
+ private readonly IReadOnlyCollection _policies;
+
+ ///
+ /// Initializes a new instance of the
+ /// class.
+ ///
+ ///
+ /// The policies that must all be satisfied.
+ ///
+ public AuthorizationPolicySet(
+ IEnumerable policies)
+ {
+ ArgumentNullException.ThrowIfNull(policies);
+
+ _policies = policies.ToArray();
+
+ if (_policies.Any(policy => policy is null))
+ {
+ throw new ArgumentException(
+ "Policy collection cannot contain null policies.",
+ nameof(policies));
+ }
+ }
+
+ ///
+ /// Determines whether all policies are satisfied.
+ ///
+ ///
+ /// The authorization context to evaluate.
+ ///
+ ///
+ /// when every policy is satisfied;
+ /// otherwise .
+ ///
+ public bool IsSatisfied(AuthorizationContextDto context)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+
+ return _policies.All(policy => policy.IsSatisfied(context));
+ }
+}
diff --git a/src/BuildingBlocks/Security/Authorization/IAuthorizationPolicySet.cs b/src/BuildingBlocks/Security/Authorization/IAuthorizationPolicySet.cs
new file mode 100644
index 0000000..bdcb65e
--- /dev/null
+++ b/src/BuildingBlocks/Security/Authorization/IAuthorizationPolicySet.cs
@@ -0,0 +1,22 @@
+namespace OpenHealthOS.Security.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+
+///
+/// Represents a composition of authorization policies.
+///
+public interface IAuthorizationPolicySet
+{
+ ///
+ /// Determines whether the authorization context satisfies all policies
+ /// in the set.
+ ///
+ ///
+ /// The authorization context to evaluate.
+ ///
+ ///
+ /// when all policies are satisfied;
+ /// otherwise .
+ ///
+ bool IsSatisfied(AuthorizationContextDto context);
+}
diff --git a/tests/UnitTests/Authorization/AuthorizationPolicySetTests.cs b/tests/UnitTests/Authorization/AuthorizationPolicySetTests.cs
new file mode 100644
index 0000000..86f7460
--- /dev/null
+++ b/tests/UnitTests/Authorization/AuthorizationPolicySetTests.cs
@@ -0,0 +1,88 @@
+namespace OpenHealthOS.UnitTests.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+using OpenHealthOS.Contracts.Identity;
+using OpenHealthOS.Security.Authorization;
+using Xunit;
+
+public sealed class AuthorizationPolicySetTests
+{
+ [Fact]
+ public void IsSatisfied_ShouldAllow_WhenAllPoliciesAreSatisfied()
+ {
+ var context = CreateContext("patient.read");
+
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ new PermissionPolicy(new Permission("PATIENT.READ")),
+ ]);
+
+ var result = policySet.IsSatisfied(context);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void IsSatisfied_ShouldDeny_WhenAnyPolicyIsNotSatisfied()
+ {
+ var context = CreateContext("patient.read");
+
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ new PermissionPolicy(new Permission("patient.write")),
+ ]);
+
+ var result = policySet.IsSatisfied(context);
+
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void IsSatisfied_ShouldAllow_WhenPolicySetIsEmpty()
+ {
+ var context = CreateContext("patient.read");
+
+ var policySet = new AuthorizationPolicySet(
+ Array.Empty());
+
+ var result = policySet.IsSatisfied(context);
+
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void IsSatisfied_ShouldThrow_WhenContextIsNull()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ ]);
+
+ Assert.Throws(
+ () => policySet.IsSatisfied(null!));
+ }
+
+ [Fact]
+ public void Constructor_ShouldThrow_WhenPoliciesIsNull()
+ {
+ Assert.Throws(
+ () => new AuthorizationPolicySet(null!));
+ }
+
+ private static AuthorizationContextDto CreateContext(
+ string permission)
+ {
+ return new AuthorizationContextDto
+ {
+ Identity = new IdentityContextDto
+ {
+ SubjectId = "test-user",
+ PrincipalType = PrincipalType.User,
+ },
+ Permission = new Permission(permission),
+ ResourceType = "Patient",
+ };
+ }
+}