diff --git a/src/ZB.MOM.WW.MxGateway.Server/Configuration/GatewayOptions.cs b/src/ZB.MOM.WW.MxGateway.Server/Configuration/GatewayOptions.cs
index f5caf1f..f3d41e5 100644
--- a/src/ZB.MOM.WW.MxGateway.Server/Configuration/GatewayOptions.cs
+++ b/src/ZB.MOM.WW.MxGateway.Server/Configuration/GatewayOptions.cs
@@ -43,4 +43,7 @@ public sealed class GatewayOptions
/// behaviour (alarms disabled).
///
public AlarmsOptions Alarms { get; init; } = new();
+
+ /// Gets self-signed TLS certificate auto-generation options.
+ public TlsOptions Tls { get; init; } = new();
}
diff --git a/src/ZB.MOM.WW.MxGateway.Server/Configuration/TlsOptions.cs b/src/ZB.MOM.WW.MxGateway.Server/Configuration/TlsOptions.cs
new file mode 100644
index 0000000..9be84a3
--- /dev/null
+++ b/src/ZB.MOM.WW.MxGateway.Server/Configuration/TlsOptions.cs
@@ -0,0 +1,22 @@
+namespace ZB.MOM.WW.MxGateway.Server.Configuration;
+
+///
+/// Options controlling the gateway's self-signed certificate auto-generation.
+/// Only consulted when a Kestrel HTTPS endpoint is configured without its own
+/// certificate; plaintext deployments never trigger generation.
+///
+public sealed class TlsOptions
+{
+ /// Path to the persisted self-signed PFX. Reused across restarts.
+ public string SelfSignedCertPath { get; init; } =
+ @"C:\ProgramData\MxGateway\certs\gateway-selfsigned.pfx";
+
+ /// Lifetime in years of a freshly generated certificate.
+ public int ValidityYears { get; init; } = 10;
+
+ /// Extra DNS SANs to embed (e.g. a load-balancer name).
+ public IReadOnlyList AdditionalDnsNames { get; init; } = [];
+
+ /// Regenerate the persisted certificate when it has expired.
+ public bool RegenerateIfExpired { get; init; } = true;
+}
diff --git a/src/ZB.MOM.WW.MxGateway.Tests/Configuration/TlsOptionsBindingTests.cs b/src/ZB.MOM.WW.MxGateway.Tests/Configuration/TlsOptionsBindingTests.cs
new file mode 100644
index 0000000..796a4ca
--- /dev/null
+++ b/src/ZB.MOM.WW.MxGateway.Tests/Configuration/TlsOptionsBindingTests.cs
@@ -0,0 +1,39 @@
+using Microsoft.Extensions.Configuration;
+using ZB.MOM.WW.MxGateway.Server.Configuration;
+using Xunit;
+
+namespace ZB.MOM.WW.MxGateway.Tests.Configuration;
+
+public sealed class TlsOptionsBindingTests
+{
+ [Fact]
+ public void Defaults_AreApplied_WhenSectionAbsent()
+ {
+ TlsOptions options = new();
+ Assert.Equal(10, options.ValidityYears);
+ Assert.True(options.RegenerateIfExpired);
+ Assert.Empty(options.AdditionalDnsNames);
+ Assert.False(string.IsNullOrWhiteSpace(options.SelfSignedCertPath));
+ }
+
+ [Fact]
+ public void Binds_FromMxGatewayTlsSection()
+ {
+ IConfiguration config = new ConfigurationBuilder()
+ .AddInMemoryCollection(new Dictionary
+ {
+ ["MxGateway:Tls:ValidityYears"] = "5",
+ ["MxGateway:Tls:SelfSignedCertPath"] = @"C:\tmp\gw.pfx",
+ ["MxGateway:Tls:RegenerateIfExpired"] = "false",
+ ["MxGateway:Tls:AdditionalDnsNames:0"] = "gw.internal",
+ })
+ .Build();
+
+ GatewayOptions options = config.GetSection(GatewayOptions.SectionName).Get()!;
+
+ Assert.Equal(5, options.Tls.ValidityYears);
+ Assert.Equal(@"C:\tmp\gw.pfx", options.Tls.SelfSignedCertPath);
+ Assert.False(options.Tls.RegenerateIfExpired);
+ Assert.Equal("gw.internal", Assert.Single(options.Tls.AdditionalDnsNames));
+ }
+}