diff --git a/src/BuildingBlocks/Security/Authorization/AuthorizationService.cs b/src/BuildingBlocks/Security/Authorization/AuthorizationService.cs
new file mode 100644
index 0000000..d641e7a
--- /dev/null
+++ b/src/BuildingBlocks/Security/Authorization/AuthorizationService.cs
@@ -0,0 +1,43 @@
+namespace OpenHealthOS.Security.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+
+///
+/// Provides application-facing authorization by delegating evaluation
+/// to an authorization evaluator.
+///
+public sealed class AuthorizationService : IAuthorizationService
+{
+ private readonly IAuthorizationEvaluator _evaluator;
+
+ ///
+ /// Initializes a new instance of the
+ /// class.
+ ///
+ ///
+ /// The authorization evaluator used to evaluate requests.
+ ///
+ public AuthorizationService(IAuthorizationEvaluator evaluator)
+ {
+ ArgumentNullException.ThrowIfNull(evaluator);
+
+ _evaluator = evaluator;
+ }
+
+ ///
+ /// Evaluates whether the specified authorization context is allowed.
+ ///
+ ///
+ /// The authorization context to evaluate.
+ ///
+ ///
+ /// The authorization decision returned by the evaluator.
+ ///
+ public AuthorizationDecision Authorize(
+ AuthorizationContextDto context)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+
+ return _evaluator.Evaluate(context);
+ }
+}
diff --git a/src/BuildingBlocks/Security/Authorization/IAuthorizationService.cs b/src/BuildingBlocks/Security/Authorization/IAuthorizationService.cs
new file mode 100644
index 0000000..b856878
--- /dev/null
+++ b/src/BuildingBlocks/Security/Authorization/IAuthorizationService.cs
@@ -0,0 +1,20 @@
+namespace OpenHealthOS.Security.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+
+///
+/// Provides the application-facing authorization service.
+///
+public interface IAuthorizationService
+{
+ ///
+ /// Evaluates whether the specified authorization context is allowed.
+ ///
+ ///
+ /// The authorization context to evaluate.
+ ///
+ ///
+ /// The authorization decision.
+ ///
+ AuthorizationDecision Authorize(AuthorizationContextDto context);
+}
diff --git a/tests/UnitTests/Authorization/AuthorizationServiceTests.cs b/tests/UnitTests/Authorization/AuthorizationServiceTests.cs
new file mode 100644
index 0000000..10a3820
--- /dev/null
+++ b/tests/UnitTests/Authorization/AuthorizationServiceTests.cs
@@ -0,0 +1,110 @@
+namespace OpenHealthOS.UnitTests.Authorization;
+
+using OpenHealthOS.Contracts.Authorization;
+using OpenHealthOS.Contracts.Identity;
+using OpenHealthOS.Security.Authorization;
+using Xunit;
+
+public sealed class AuthorizationServiceTests
+{
+ [Fact]
+ public void Authorize_ShouldReturnAllow_WhenEvaluatorAllows()
+ {
+ var evaluator = new StubAuthorizationEvaluator(
+ AuthorizationDecision.Allow);
+
+ var service = new AuthorizationService(evaluator);
+
+ var result = service.Authorize(CreateContext());
+
+ Assert.Equal(
+ AuthorizationDecision.Allow,
+ result);
+ }
+
+ [Fact]
+ public void Authorize_ShouldReturnDeny_WhenEvaluatorDenies()
+ {
+ var evaluator = new StubAuthorizationEvaluator(
+ AuthorizationDecision.Deny);
+
+ var service = new AuthorizationService(evaluator);
+
+ var result = service.Authorize(CreateContext());
+
+ Assert.Equal(
+ AuthorizationDecision.Deny,
+ result);
+ }
+
+ [Fact]
+ public void Constructor_ShouldThrow_WhenEvaluatorIsNull()
+ {
+ Assert.Throws(
+ () => new AuthorizationService(null!));
+ }
+
+ [Fact]
+ public void Authorize_ShouldThrow_WhenContextIsNull()
+ {
+ var evaluator = new StubAuthorizationEvaluator(
+ AuthorizationDecision.Allow);
+
+ var service = new AuthorizationService(evaluator);
+
+ Assert.Throws(
+ () => service.Authorize(null!));
+ }
+
+ [Fact]
+ public void Authorize_ShouldDelegateToEvaluator()
+ {
+ var evaluator = new StubAuthorizationEvaluator(
+ AuthorizationDecision.Allow);
+
+ var service = new AuthorizationService(evaluator);
+
+ var context = CreateContext();
+
+ service.Authorize(context);
+
+ Assert.Same(context, evaluator.LastContext);
+ }
+
+ private static AuthorizationContextDto CreateContext()
+ {
+ return new AuthorizationContextDto
+ {
+ Identity = new IdentityContextDto
+ {
+ SubjectId = "test-user",
+ PrincipalType = PrincipalType.User,
+ Scopes = ["patient.read"],
+ },
+ Permission = new Permission("patient.read"),
+ ResourceType = "Patient",
+ };
+ }
+
+ private sealed class StubAuthorizationEvaluator
+ : IAuthorizationEvaluator
+ {
+ private readonly AuthorizationDecision _decision;
+
+ public StubAuthorizationEvaluator(
+ AuthorizationDecision decision)
+ {
+ _decision = decision;
+ }
+
+ public AuthorizationContextDto? LastContext { get; private set; }
+
+ public AuthorizationDecision Evaluate(
+ AuthorizationContextDto context)
+ {
+ LastContext = context;
+
+ return _decision;
+ }
+ }
+}