diff --git a/src/BuildingBlocks/Security/Authorization/PolicyEvaluator.cs b/src/BuildingBlocks/Security/Authorization/PolicyEvaluator.cs
new file mode 100644
index 0000000..2e5e792
--- /dev/null
+++ b/src/BuildingBlocks/Security/Authorization/PolicyEvaluator.cs
@@ -0,0 +1,43 @@
+namespace OpenHealthOS.Security.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+
+///
+/// Evaluates authorization requests using an authorization policy set.
+///
+public sealed class PolicyEvaluator : IAuthorizationEvaluator
+{
+ private readonly IAuthorizationPolicySet _policySet;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The authorization policy set used to evaluate requests.
+ ///
+ public PolicyEvaluator(IAuthorizationPolicySet policySet)
+ {
+ ArgumentNullException.ThrowIfNull(policySet);
+
+ _policySet = policySet;
+ }
+
+ ///
+ /// Evaluates whether the authorization context satisfies the policy set.
+ ///
+ ///
+ /// The authorization context to evaluate.
+ ///
+ ///
+ /// when all policies are
+ /// satisfied; otherwise .
+ ///
+ public AuthorizationDecision Evaluate(AuthorizationContextDto context)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+
+ return _policySet.IsSatisfied(context)
+ ? AuthorizationDecision.Allow
+ : AuthorizationDecision.Deny;
+ }
+}
diff --git a/tests/UnitTests/Authorization/PolicyEvaluatorTests.cs b/tests/UnitTests/Authorization/PolicyEvaluatorTests.cs
new file mode 100644
index 0000000..e45f07f
--- /dev/null
+++ b/tests/UnitTests/Authorization/PolicyEvaluatorTests.cs
@@ -0,0 +1,124 @@
+namespace OpenHealthOS.UnitTests.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+using OpenHealthOS.Contracts.Identity;
+using OpenHealthOS.Security.Authorization;
+using Xunit;
+
+public sealed class PolicyEvaluatorTests
+{
+ [Fact]
+ public void Evaluate_ShouldAllow_WhenPolicySetIsSatisfied()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ ]);
+
+ var evaluator = new PolicyEvaluator(policySet);
+
+ var context = CreateContext("patient.read");
+
+ var result = evaluator.Evaluate(context);
+
+ Assert.Equal(
+ AuthorizationDecision.Allow,
+ result);
+ }
+
+ [Fact]
+ public void Evaluate_ShouldDeny_WhenPolicySetIsNotSatisfied()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.write")),
+ ]);
+
+ var evaluator = new PolicyEvaluator(policySet);
+
+ var context = CreateContext("patient.read");
+
+ var result = evaluator.Evaluate(context);
+
+ Assert.Equal(
+ AuthorizationDecision.Deny,
+ result);
+ }
+
+ [Fact]
+ public void Evaluate_ShouldAllow_WhenAllPoliciesAreSatisfied()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ new PermissionPolicy(new Permission("patient.read")),
+ ]);
+
+ var evaluator = new PolicyEvaluator(policySet);
+
+ var context = CreateContext("patient.read");
+
+ var result = evaluator.Evaluate(context);
+
+ Assert.Equal(
+ AuthorizationDecision.Allow,
+ result);
+ }
+
+ [Fact]
+ public void Evaluate_ShouldDeny_WhenAnyPolicyIsNotSatisfied()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ new PermissionPolicy(new Permission("patient.write")),
+ ]);
+
+ var evaluator = new PolicyEvaluator(policySet);
+
+ var context = CreateContext("patient.read");
+
+ var result = evaluator.Evaluate(context);
+
+ Assert.Equal(
+ AuthorizationDecision.Deny,
+ result);
+ }
+
+ [Fact]
+ public void Constructor_ShouldThrow_WhenPolicySetIsNull()
+ {
+ Assert.Throws(
+ () => new PolicyEvaluator(null!));
+ }
+
+ [Fact]
+ public void Evaluate_ShouldThrow_WhenContextIsNull()
+ {
+ var policySet = new AuthorizationPolicySet(
+ [
+ new PermissionPolicy(new Permission("patient.read")),
+ ]);
+
+ var evaluator = new PolicyEvaluator(policySet);
+
+ Assert.Throws(
+ () => evaluator.Evaluate(null!));
+ }
+
+ private static AuthorizationContextDto CreateContext(
+ string permission)
+ {
+ return new AuthorizationContextDto
+ {
+ Identity = new IdentityContextDto
+ {
+ SubjectId = "test-user",
+ PrincipalType = PrincipalType.User,
+ Scopes = [permission],
+ },
+ Permission = new Permission(permission),
+ ResourceType = "Patient",
+ };
+ }
+}