diff --git a/src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardAutoLoginAuthenticationHandler.cs b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardAutoLoginAuthenticationHandler.cs
new file mode 100644
index 0000000..bb0adb9
--- /dev/null
+++ b/src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardAutoLoginAuthenticationHandler.cs
@@ -0,0 +1,89 @@
+using System.Security.Claims;
+using System.Text.Encodings.Web;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using ZB.MOM.WW.Auth.AspNetCore;
+using ZB.MOM.WW.MxGateway.Server.Configuration;
+
+namespace ZB.MOM.WW.MxGateway.Server.Dashboard;
+
+///
+/// Authentication handler used ONLY when MxGateway:Dashboard:DisableLogin is true.
+/// Registered under the dashboard cookie scheme name
+/// (), it authenticates
+/// EVERY request as the configured dev user with both dashboard roles — no credential check,
+/// no cookie, no LDAP bind. The minted principal mirrors the shape the real login
+/// () produces, so policies and the UI cannot tell it
+/// apart. DEV/TEST ONLY; never enable in production.
+///
+public sealed class DashboardAutoLoginAuthenticationHandler
+ : AuthenticationHandler, IAuthenticationSignInHandler
+{
+ /// Username used when AutoLoginUser is null or blank.
+ public const string DefaultUser = "multi-role";
+
+ private readonly string _user;
+
+ /// Initializes the handler with scheme plumbing and the dashboard options.
+ /// The per-scheme authentication options monitor.
+ /// The logger factory the base handler uses.
+ /// The URL encoder the base handler uses.
+ /// Gateway options carrying the dashboard auto-login user.
+ public DashboardAutoLoginAuthenticationHandler(
+ IOptionsMonitor options,
+ ILoggerFactory logger,
+ UrlEncoder encoder,
+ IOptions gatewayOptions)
+ : base(options, logger, encoder)
+ => _user = gatewayOptions.Value.Dashboard.AutoLoginUser ?? DefaultUser;
+
+ /// No-op: auto-login writes no cookie, so a sign-in has nothing to persist.
+ /// Ignored.
+ /// Ignored.
+ /// A completed task.
+ public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties) => Task.CompletedTask;
+
+ /// No-op: there is no auth cookie to clear; the next request re-authenticates.
+ /// Ignored.
+ /// A completed task.
+ public Task SignOutAsync(AuthenticationProperties? properties) => Task.CompletedTask;
+
+ ///
+ protected override Task HandleAuthenticateAsync()
+ {
+ ClaimsPrincipal principal = CreatePrincipal(_user);
+ AuthenticationTicket ticket = new(principal, Scheme.Name);
+
+ return Task.FromResult(AuthenticateResult.Success(ticket));
+ }
+
+ ///
+ /// Builds the multi-role dev principal. Null/blank falls back to
+ /// . Claim shape mirrors .
+ ///
+ /// The configured auto-login username (may be null/blank).
+ /// An authenticated principal holding both dashboard roles.
+ internal static ClaimsPrincipal CreatePrincipal(string? user)
+ {
+ string name = string.IsNullOrWhiteSpace(user) ? DefaultUser : user.Trim();
+
+ Claim[] claims =
+ [
+ new Claim(ClaimTypes.NameIdentifier, name),
+ new Claim(ZbClaimTypes.Username, name),
+ new Claim(ZbClaimTypes.Name, name),
+ new Claim(ZbClaimTypes.DisplayName, name),
+ new Claim(ZbClaimTypes.Role, DashboardRoles.Admin),
+ new Claim(ZbClaimTypes.Role, DashboardRoles.Viewer),
+ ];
+
+ ClaimsIdentity identity = new(
+ claims,
+ DashboardAuthenticationDefaults.AuthenticationScheme,
+ ZbClaimTypes.Name,
+ ZbClaimTypes.Role);
+
+ return new ClaimsPrincipal(identity);
+ }
+}
diff --git a/src/ZB.MOM.WW.MxGateway.Tests/Gateway/Dashboard/DashboardAutoLoginAuthenticationHandlerTests.cs b/src/ZB.MOM.WW.MxGateway.Tests/Gateway/Dashboard/DashboardAutoLoginAuthenticationHandlerTests.cs
new file mode 100644
index 0000000..41b9e78
--- /dev/null
+++ b/src/ZB.MOM.WW.MxGateway.Tests/Gateway/Dashboard/DashboardAutoLoginAuthenticationHandlerTests.cs
@@ -0,0 +1,37 @@
+using System.Security.Claims;
+using ZB.MOM.WW.MxGateway.Server.Dashboard;
+
+namespace ZB.MOM.WW.MxGateway.Tests.Gateway.Dashboard;
+
+public sealed class DashboardAutoLoginAuthenticationHandlerTests
+{
+ [Fact]
+ public void CreatePrincipal_MintsAuthenticatedMultiRoleUser()
+ {
+ ClaimsPrincipal principal = DashboardAutoLoginAuthenticationHandler.CreatePrincipal("multi-role");
+
+ Assert.True(principal.Identity!.IsAuthenticated);
+ Assert.Equal("multi-role", principal.Identity!.Name);
+ Assert.True(principal.IsInRole(DashboardRoles.Admin));
+ Assert.True(principal.IsInRole(DashboardRoles.Viewer));
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData(" ")]
+ public void CreatePrincipal_BlankUser_FallsBackToDefault(string? user)
+ {
+ ClaimsPrincipal principal = DashboardAutoLoginAuthenticationHandler.CreatePrincipal(user);
+
+ Assert.Equal(DashboardAutoLoginAuthenticationHandler.DefaultUser, principal.Identity!.Name);
+ }
+
+ [Fact]
+ public void CreatePrincipal_TrimsUser()
+ {
+ ClaimsPrincipal principal = DashboardAutoLoginAuthenticationHandler.CreatePrincipal(" multi-role ");
+
+ Assert.Equal("multi-role", principal.Identity!.Name);
+ }
+}