diff --git a/Directory.Packages.props b/Directory.Packages.props
index dfb0f023f4..77ac7fafc2 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -2,7 +2,7 @@
   
     true
     
-    0.16.2
+    0.18.0
     
     4.61.0
   
diff --git a/LibsAndSamples.sln b/LibsAndSamples.sln
index 8c0104c004..c49b1d2206 100644
--- a/LibsAndSamples.sln
+++ b/LibsAndSamples.sln
@@ -1,4 +1,4 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 17
 VisualStudioVersion = 17.3.32708.82
 MinimumVisualStudioVersion = 10.0.40219.1
@@ -178,6 +178,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CacheExtension", "tests\dev
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Identity.Client.Extensions.Msal", "src\client\Microsoft.Identity.Client.Extensions.Msal\Microsoft.Identity.Client.Extensions.Msal.csproj", "{87679336-95BE-47E4-B42B-8F6860A0B215}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "tests\devapps\WAM\NetWSLWam\test.csproj", "{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug + MobileApps|Any CPU = Debug + MobileApps|Any CPU
@@ -554,7 +556,6 @@ Global
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug + MobileApps|x86.Build.0 = Debug + MobileApps|Any CPU
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug|ARM.Build.0 = Debug|Any CPU
 		{24D2AF71-A01E-4450-8C3F-B9923A81134B}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -610,7 +611,6 @@ Global
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Debug|x86.Build.0 = Debug|Any CPU
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Release|ARM.ActiveCfg = Release|Any CPU
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Release|ARM.Build.0 = Release|Any CPU
 		{959A47D9-07E7-4BF3-A0F7-6D9CD42A2C46}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -723,7 +723,6 @@ Global
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug + MobileApps|x86.Build.0 = Debug + MobileApps|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|ARM.Build.0 = Debug|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -738,7 +737,6 @@ Global
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Debug|x86.Build.0 = Debug|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Release|ARM.ActiveCfg = Release|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Release|ARM.Build.0 = Release|Any CPU
 		{E7EB3226-D0F5-4A93-87DC-FAAC9A24D684}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -767,7 +765,6 @@ Global
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug + MobileApps|x86.Build.0 = Debug + MobileApps|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|ARM.Build.0 = Debug|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -782,7 +779,6 @@ Global
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Debug|x86.Build.0 = Debug|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Release|ARM.ActiveCfg = Release|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Release|ARM.Build.0 = Release|Any CPU
 		{339E0B2B-4408-4947-B134-E8C5AAB11286}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -811,7 +807,6 @@ Global
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug + MobileApps|x86.Build.0 = Debug + MobileApps|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|ARM.Build.0 = Debug|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -826,7 +821,6 @@ Global
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Debug|x86.Build.0 = Debug|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Release|ARM.ActiveCfg = Release|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Release|ARM.Build.0 = Release|Any CPU
 		{2AF48872-DD47-4DA1-A153-DF4DA13882C2}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -1022,7 +1016,6 @@ Global
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug + MobileApps|x86.Build.0 = Debug + MobileApps|Any CPU
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug|ARM.Build.0 = Debug|Any CPU
 		{998D38B3-344C-4F19-833E-6181B0834AF6}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -1191,7 +1184,6 @@ Global
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|ARM.Build.0 = Debug|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -1206,7 +1198,6 @@ Global
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Debug|x86.Build.0 = Debug|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Release|ARM.ActiveCfg = Release|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Release|ARM.Build.0 = Release|Any CPU
 		{3A2042E9-8B03-4F2D-A2B7-EA4BEC36340C}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -1242,9 +1233,7 @@ Global
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug + MobileApps|x86.Deploy.0 = Debug|x86
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
-
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|ARM.ActiveCfg = Debug|ARM
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|ARM.Build.0 = Debug|ARM
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|ARM.Deploy.0 = Debug|ARM
@@ -1265,9 +1254,7 @@ Global
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Debug|x86.Deploy.0 = Debug|x86
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|Any CPU.Deploy.0 = Release|Any CPU
-
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|ARM.ActiveCfg = Release|ARM
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|ARM.Build.0 = Release|ARM
 		{34E323E8-E706-4DF4-B916-D614FC8CFCEB}.Release|ARM.Deploy.0 = Release|ARM
@@ -1386,7 +1373,6 @@ Global
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|ARM.Build.0 = Debug|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -1401,7 +1387,6 @@ Global
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Debug|x86.Build.0 = Debug|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Release|ARM.ActiveCfg = Release|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Release|ARM.Build.0 = Release|Any CPU
 		{B381269F-44DA-4E46-8F51-1F1DF7D1F61D}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -1430,7 +1415,6 @@ Global
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|ARM.Build.0 = Debug|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -1445,7 +1429,6 @@ Global
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Debug|x86.Build.0 = Debug|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Release|Any CPU.Build.0 = Release|Any CPU
-
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Release|ARM.ActiveCfg = Release|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Release|ARM.Build.0 = Release|Any CPU
 		{4EA542D2-D4C9-403C-B615-0047D0A62790}.Release|ARM64.ActiveCfg = Release|Any CPU
@@ -1474,7 +1457,6 @@ Global
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
-
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug|ARM.ActiveCfg = Debug|Any CPU
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug|ARM.Build.0 = Debug|Any CPU
 		{1B047736-9325-4F59-906B-89A3E12AC8FB}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -1710,6 +1692,48 @@ Global
 		{87679336-95BE-47E4-B42B-8F6860A0B215}.Release|x64.Build.0 = Release|Any CPU
 		{87679336-95BE-47E4-B42B-8F6860A0B215}.Release|x86.ActiveCfg = Release|Any CPU
 		{87679336-95BE-47E4-B42B-8F6860A0B215}.Release|x86.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|Any CPU.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|Any CPU.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|ARM.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|ARM.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|ARM64.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|ARM64.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|iPhone.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|iPhone.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|x64.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|x64.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|x86.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|ARM.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|ARM64.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|x64.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Debug|x86.Build.0 = Debug|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|ARM.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|ARM.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|ARM64.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|ARM64.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|iPhone.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|x64.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|x64.Build.0 = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|x86.ActiveCfg = Release|Any CPU
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -1761,6 +1785,7 @@ Global
 		{74805FE3-2E0D-4EAB-8CFE-A9D46F8D5972} = {34BE693E-3496-45A4-B1D2-D3A0E068EEDB}
 		{92064C48-0136-48CD-AE8D-C6FEDBC7B639} = {74805FE3-2E0D-4EAB-8CFE-A9D46F8D5972}
 		{87679336-95BE-47E4-B42B-8F6860A0B215} = {1A37FD75-94E9-4D6F-953A-0DABBD7B49E9}
+		{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8} = {5FAAD966-36B8-4C19-A5FA-5410DD53063D}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {020399A9-DC27-4B82-9CAA-EF488665AC27}
diff --git a/build/linux-install-deps.sh b/build/linux-install-deps.sh
new file mode 100644
index 0000000000..63b7291503
--- /dev/null
+++ b/build/linux-install-deps.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+apt install sudo
+# This script must be run elevated. Adding a sudo wrapper if needed.
+if [ "$UID" -ne 0 ]; then
+    exec sudo "$0" "$@"
+fi
+
+set -o errexit   # Exit the script if any command returns a non-true return value
+
+if [ -f '/usr/bin/apt' ]; then
+    DEBIAN_FRONTEND=noninteractive
+    # Install quietly, accepting all packages and not overriding user configurations
+    PKGINSTALL_CMD='apt-get install -q -y -o Dpkg::Options::=--force-confold'
+    PACKAGE_MANAGER=apt
+    PKGEXISTS_CMD='dpkg -s'
+elif [ -f '/usr/bin/yum' ]; then
+    PACKAGE_MANAGER=yum
+    PKGINSTALL_CMD='yum -y install'
+    PKGEXISTS_CMD='yum list installed'
+else
+    echo 'Package system currently not supported.'
+    exit 2
+fi
+
+if [ $PACKAGE_MANAGER == 'apt' ]; then
+    apt-get update || true # If apt update fails, see if we can continue anyway
+    $PKGINSTALL_CMD \
+        libx11-dev \
+        dbus-x11 \
+        libsystemd0 \
+        gnome-keyring \
+        libsecret-tools \
+        libsecret-1-dev \
+        xdg-utils \
+        x11-xserver-utils \
+        xorg \
+        libp11-kit-dev \
+        libwebkit2gtk-4.0-dev
+fi
+
+echo "Installing JavaBroker"
+LINUX_VERSION=$(sed -r -n -e 's/^VERSION_ID="?([^"]+)"?/\1/p' /etc/os-release)
+LINUX_VERSION_MAIN=$(echo $LINUX_VERSION | sed 's/\([0-9]*\)\..*/\1/')
+
+BROKER_PACKAGE_NAME='microsoft-identity-broker'
+if [ -f '/usr/bin/apt' ]; then
+    curl https://packages.microsoft.com/config/ubuntu/$LINUX_VERSION/prod.list | sudo sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
+else
+    $PKGINSTALL_CMD yum-utils
+    yum-config-manager --add-repo=https://packages.microsoft.com/config/rhel/$LINUX_VERSION_MAIN/prod.repo
+    rpm --import http://packages.microsoft.com/keys/microsoft.asc
+fi
+echo "Installing latest published JavaBroker package"
+$PKGINSTALL_CMD $BROKER_PACKAGE_NAME
+
+exit 0
\ No newline at end of file
diff --git a/build/template-build-and-prep-automation.yaml b/build/template-build-and-prep-automation.yaml
index d942634bf3..0a8aeba828 100644
--- a/build/template-build-and-prep-automation.yaml
+++ b/build/template-build-and-prep-automation.yaml
@@ -102,6 +102,16 @@ steps:
             }
         }
 
+        #check Linux runtime files
+        $linuxRuntimes = 'runtimes\linux-x64\native\libmsalruntime.so';
+        $LinuxAppsToCheck = 'NetWSLWam\bin\Release\net8.0\';
+        $appFullPath = $searchInFolder+$LinuxAppsToCheck+$linuxRuntimes
+        Write-Host $appFullPath
+        if (-not(Test-Path -Path $appFullPath -PathType Leaf))
+        {
+            $errors += "Failed to find Linux runtime files in : " + $SearchInFolder + $app + "`n";
+        }
+
         #exit if there are errors
         IF (![string]::IsNullOrWhitespace($errors))
         {
diff --git a/build/template-build-and-run-all-tests.yaml b/build/template-build-and-run-all-tests.yaml
index 1f8d2f7184..8ae22e11b0 100644
--- a/build/template-build-and-run-all-tests.yaml
+++ b/build/template-build-and-run-all-tests.yaml
@@ -82,3 +82,15 @@ jobs: #Build and stage projects
       fallbackOnPRTargetBranch: false
       baseDefinitionId: '905' #this is the PR build and it is used as a baseline
       baseBranchRef: 'main'
+
+- job: 'BuildandRunIntegrationTestsOnLinux'
+  pool:
+      vmImage: 'ubuntu-22.04'
+      demands:
+      - msbuild
+  variables:
+      runCodesignValidationInjection: false
+      Codeql.SkipTaskAutoInjection: true
+
+  steps:
+  - template: template-test-on-linux.yaml
\ No newline at end of file
diff --git a/build/template-install-keyvault-secrets.yaml b/build/template-install-keyvault-secrets.yaml
index 0e9b83ddb8..297b4be99b 100644
--- a/build/template-install-keyvault-secrets.yaml
+++ b/build/template-install-keyvault-secrets.yaml
@@ -16,11 +16,18 @@ steps:
    $kvSecretBytes = [System.Convert]::FromBase64String('$(LabAuth)')
    $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
    $certCollection.Import($kvSecretBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
-
-   $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12)
-   $pfxPath = '$(Build.SourcesDirectory)' + "\TestCert.pfx"
+   $CertPass = ''
+   $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $CertPass)
+   $pfxPath = '$(Build.SourcesDirectory)' + "/TestCert.pfx"
    [System.IO.File]::WriteAllBytes($pfxPath, $protectedCertificateBytes)
 
-   Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation Cert:\LocalMachine\My
-
+   if ([System.Environment]::OSVersion.Platform -eq 'Win32NT') {
+      Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation "Cert:\LocalMachine\My"
+   } else {
+      Write-Output "This script is running on a non-Windows platform. Skipping Import-PfxCertificate."
+   }
+   Write-Host "Write $((Get-Item -Path $pfxPath).Length) PFX bytes to: $pfxPath"
+   Write-Host "##vso[task.setvariable variable=certDir;isOutput=true]$pfxPath"
+   Write-Host "##vso[task.setvariable variable=certPass;isSecret=true;isOutput=true]$CertPass"
+  name: generateLabCert
   displayName: 'Install Keyvault Secrets'
diff --git a/build/template-test-on-linux.yaml b/build/template-test-on-linux.yaml
new file mode 100644
index 0000000000..f0eca6131a
--- /dev/null
+++ b/build/template-test-on-linux.yaml
@@ -0,0 +1,154 @@
+# template-test-on-linux.yaml
+# Run all unit tests across the LibsAndSamples.sln project on Linux platform
+
+parameters:
+  BuildConfiguration: 'Release'
+
+steps:
+
+- template: template-install-keyvault-secrets.yaml
+
+- task: Bash@3
+  displayName: Install broker and dependencies
+  inputs:
+    targetType: 'inline'
+    script: |
+      chmod +x ./build/linux-install-deps.sh
+      ./build/linux-install-deps.sh
+
+- task: Bash@3
+  name: SetDbusSession
+  displayName: Set DBUS_SESSION_BUS_ADDRESS
+  inputs:
+    targetType: inline
+    script: |
+      echo "Setting DBUS_SESSION_BUS_ADDRESS"
+      # ensure that /var/lib/dbus/machine-id exists and has the uuid in it
+      sudo dbus-uuidgen --ensure
+      DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${UID}/bus"
+      # enable session lingering for the user
+      sudo loginctl enable-linger ${USER}
+      # enable and start dbus service
+      sudo systemctl enable dbus.service
+      sudo systemctl start dbus.service
+      # make sure per-user instance of systemd is running
+      /usr/bin/dbus-daemon --session --address=systemd: --nofork --print-address --nopidfile --systemd-activation --syslog-only
+      echo "dbus-launch finished"
+
+      echo "##vso[task.setvariable variable=dbusSessionAddress;isOutput=true]$DBUS_SESSION_BUS_ADDRESS"
+      echo "Set dbusSessionAddress successfully"
+      echo "set DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"
+
+- task: Bash@3
+  name: SetTestKeyring
+  displayName: Set test key ring
+  timeoutInMinutes: 2
+  inputs:
+    targetType: inline
+    script: |
+      echo "Setting DBUS_SESSION_BUS_ADDRESS"
+      echo "Set to DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}"
+
+      killall -q -u "$(whoami)" gnome-keyring-daemon
+      echo "gnome-keyring-daemon was terminated"
+
+      rm -f ~/.local/share/keyrings/login.keyring
+      echo "Login keyring deleted"
+
+      _UNLOCK_KEYRING_DATA=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1`
+      echo "_UNLOCK_KEYRING_DATA is set"
+
+      eval $(echo -n "${_UNLOCK_KEYRING_DATA}" \
+        | gnome-keyring-daemon --daemonize --login \
+        | sed -e 's/^/export /')
+      echo "keyring daemon was set"
+
+      unset _UNLOCK_KEYRING_DATA
+      /usr/bin/gnome-keyring-daemon --start --components=secrets
+      echo "keyring daemon started"
+
+      secret-tool search --all version 1.0
+      echo "secret-tool executed"
+
+      echo "##vso[task.setvariable variable=keyRingControl;isOutput=true]$GNOME_KEYRING_CONTROL"
+      echo "GNOME_KEYRING_CONTROL was set."
+  env:
+    DBUS_SESSION_BUS_ADDRESS: $(SetDbusSession.dbusSessionAddress)
+
+- task: Bash@3
+  displayName: Start Xvfb server and launch GUI
+  inputs:
+    targetType: inline
+    script: |
+      if [ -f '/usr/bin/apt' ]; then
+          sudo chmod 777 /etc/systemd/system/
+          sudo rm -f /etc/systemd/system/xvfb.service
+          sudo touch /etc/systemd/system/xvfb.service
+          sudo chmod 777 /etc/systemd/system/xvfb.service
+          echo '[unit]' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo 'Description=X Virtual Frame Buffer Service' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo 'After=network.target' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo '[Service]' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo 'ExecStart=/usr/bin/Xvfb :1 -screen 0 1024x768x24' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo 'Restart=always' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo '[Install]' | sudo tee -a /etc/systemd/system/xvfb.service
+          echo 'WantedBy=multi-user.target' | sudo tee -a /etc/systemd/system/xvfb.service
+
+          sudo systemctl enable /etc/systemd/system/xvfb.service
+          sudo service xvfb start
+
+          wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
+          sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
+          sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
+          rm -f packages.microsoft.gpg
+          sudo apt update
+          sudo apt install code
+          export DISPLAY=:1
+      elif [ -f '/usr/bin/yum' ]; then
+          # install packages for GUI test
+          sudo yum -y install xorg-x11-server-Xvfb mesa-libEGL-devel glx-utils mesa-dri-drivers xorg-x11-server-utils
+          Xvfb -ac ${DISPLAY} 2>/dev/null &
+          sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
+          sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'
+          dnf check-update
+          sudo dnf -y install code
+      fi
+
+      code .
+      dbus-update-activation-environment --systemd DISPLAY XAUTHORITY
+      xhost +SI:localuser:$(whoami)
+      xhost +SI:localuser:microsoft-identity-broker
+  env:
+    DBUS_SESSION_BUS_ADDRESS: $(SetDbusSession.dbusSessionAddress)
+
+- task: UseDotNet@2
+  displayName: 'Use the latest .NET 8'
+  inputs:
+    version: 8.x
+
+- task: CmdLine@2
+  displayName: 'Clear local NuGet cache'
+  inputs:
+    script: 'nuget locals all -clear'
+
+- task: DotNetCoreCLI@2
+  displayName: 'Wotnet workload restore'
+  inputs:
+    command: 'custom'
+    custom: 'workload'
+    arguments: 'restore .\src\client\Microsoft.Identity.Client\Microsoft.Identity.Client.csproj'
+
+- task: DotNetCoreCLI@2
+  displayName: 'Build Integration Test'
+  inputs:
+    command: 'build'
+    projects: |
+      ./tests/Microsoft.Identity.Test.Integration.netcore/Microsoft.Identity.Test.Integration.NetCore.csproj
+    configuration: ${{ parameters.BuildConfiguration }}
+
+- script: |
+    dotnet test **/Microsoft.Identity.Test.Integration.netcore/Microsoft.Identity.Test.Integration.NetCore.csproj -l "console;verbosity=detailed"
+  displayName: 'Run Integration tests .NET'
+  env:
+    CERTIFICATE_LOCATION: $(generateLabCert.certDir)
+    CERTIFICATE_PASSWORD: $(generateLabCert.certPass)
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client.Broker/BrokerExtension.cs b/src/client/Microsoft.Identity.Client.Broker/BrokerExtension.cs
index 256d3427c8..462f231cf6 100644
--- a/src/client/Microsoft.Identity.Client.Broker/BrokerExtension.cs
+++ b/src/client/Microsoft.Identity.Client.Broker/BrokerExtension.cs
@@ -71,15 +71,15 @@ public static PublicClientApplicationBuilder WithSsoPolicy(this PublicClientAppl
 
         private static void AddRuntimeSupport(PublicClientApplicationBuilder builder)
         {
-            if (DesktopOsHelper.IsWin10OrServerEquivalent())
+            if (DesktopOsHelper.IsWin10OrServerEquivalent() || DesktopOsHelper.IsLinux())
             {
                  builder.Config.BrokerCreatorFunc =
                      (uiParent, appConfig, logger) =>
                      {
-                         logger.Info("[Runtime] WAM supported OS.");
+                         logger.Info("[Runtime] Broker supported OS.");
                          return new RuntimeBroker(uiParent, appConfig, logger);
                      };
-            }
+            } 
             else
             {
                 builder.Config.BrokerCreatorFunc =
diff --git a/src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs b/src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs
index ee9292f83b..bf455109f3 100644
--- a/src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs
+++ b/src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs
@@ -6,6 +6,7 @@
 using System.Globalization;
 using System.Linq;
 using System.Diagnostics;
+using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using Microsoft.Identity.Client.ApiConfig.Parameters;
 using Microsoft.Identity.Client.Cache;
@@ -29,6 +30,10 @@ internal class RuntimeBroker : IBroker
         private readonly BrokerOptions _wamOptions;
         private static Exception s_initException;
 
+        // Linux broker's username password flow is via interactive calls
+        [DllImport("libX11.so.6")]
+        private static extern IntPtr XOpenDisplay(string display);
+
         private static Dictionary LogLevelMap = new Dictionary()
         {
             { NativeInterop.LogLevel.Trace, LogLevel.Verbose },
@@ -39,7 +44,10 @@ internal class RuntimeBroker : IBroker
             { NativeInterop.LogLevel.Fatal, LogLevel.Error },
         };
 
-        public bool IsPopSupported => true;
+        /// 
+        /// Pop is supported on Windows only
+        /// 
+        public bool IsPopSupported => DesktopOsHelper.IsWindows();
 
         /// 
         /// Being a C API, MSAL runtime uses a "global init" and "global shutdown" approach. 
@@ -94,7 +102,7 @@ public RuntimeBroker(
             ILoggerAdapter logger)
         {
             _logger = logger ?? throw new ArgumentNullException(nameof(logger));
-
+            
             if (_logger.PiiLoggingEnabled)
             {
                 s_lazyCore.Value.EnablePii(_logger.PiiLoggingEnabled);
@@ -396,15 +404,29 @@ public async Task AcquireTokenByUsernamePasswordAsync(
             {
                 authParams.Properties["MSALRuntime_Username"] = acquireTokenByUsernamePasswordParameters.Username;
                 authParams.Properties["MSALRuntime_Password"] = acquireTokenByUsernamePasswordParameters.Password;
-
-                using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInSilentlyAsync(
+                // For Linux broker, use the interactive flow with username password to get the token
+                if (Environment.GetEnvironmentVariable("TF_BUILD") != null && DesktopOsHelper.IsLinux()) {
+                    using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInInteractivelyAsync(
+                        XOpenDisplay(":1"),
                         authParams,
                         authenticationRequestParameters.CorrelationId.ToString("D"),
+                        acquireTokenByUsernamePasswordParameters.Username,
                         cancellationToken).ConfigureAwait(false))
-                {
-                    var errorMessage = "Could not acquire token with username and password.";
-                    msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
+                    {
+                        var errorMessage = "Could not acquire token with username and password.";
+                        msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
+                    }
+                } else {
+                    using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInSilentlyAsync(
+                        authParams,
+                        authenticationRequestParameters.CorrelationId.ToString("D"),
+                        cancellationToken).ConfigureAwait(false))
+                    {
+                        var errorMessage = "Could not acquire token with username and password.";
+                        msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
+                    }
                 }
+                
             }
 
             return msalTokenResponse;
@@ -586,7 +608,7 @@ public void HandleInstallUrl(string appLink)
 
         public bool IsBrokerInstalledAndInvokable(AuthorityType authorityType)
         {
-            if (!DesktopOsHelper.IsWin10OrServerEquivalent())
+            if (!DesktopOsHelper.IsWin10OrServerEquivalent() && !DesktopOsHelper.IsLinux())
             {
                 _logger?.Warning("[RuntimeBroker] Not a supported operating system. WAM broker is not available. ");
                 return false;
diff --git a/src/client/Microsoft.Identity.Client/ApiConfig/BrokerOptions.cs b/src/client/Microsoft.Identity.Client/ApiConfig/BrokerOptions.cs
index 871cacc8ad..1e28b942a7 100644
--- a/src/client/Microsoft.Identity.Client/ApiConfig/BrokerOptions.cs
+++ b/src/client/Microsoft.Identity.Client/ApiConfig/BrokerOptions.cs
@@ -29,6 +29,10 @@ public enum OperatingSystems
             /// Use broker on Windows OS
             /// 
             Windows = 0b_0000_0001,  // 1
+            /// 
+            /// Use broker on Linux
+            /// 
+            Linux = 0b_0000_0010,  // 2
         }
 
         /// 
@@ -71,8 +75,9 @@ internal static BrokerOptions CreateFromWindowsOptions(WindowsBrokerOptions winO
         public bool MsaPassthrough { get; set; } = false;
 
         /// 
-        /// Currently only supported on Windows
+        /// Currently only supported on Windows and Linux
         /// Allows the Windows broker to list Work and School accounts as part of the 
+        /// Linux broker will discover accounts as part of the 
         ///         
         public bool ListOperatingSystemAccounts { get; set; }
 
@@ -81,6 +86,8 @@ internal bool IsBrokerEnabledOnCurrentOs()
             if (EnabledOn.HasFlag(OperatingSystems.Windows) && DesktopOsHelper.IsWindows())
             {
                 return true;
+            } else if (EnabledOn.HasFlag(OperatingSystems.Linux) && DesktopOsHelper.IsLinux()) {
+                return true;
             }
 
             return false;
diff --git a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/DesktopOsHelper.cs b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/DesktopOsHelper.cs
index a5fc805a46..84b87cfb18 100644
--- a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/DesktopOsHelper.cs
+++ b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/DesktopOsHelper.cs
@@ -2,6 +2,7 @@
 // Licensed under the MIT License.
 
 using System;
+using System.IO;
 using System.Linq;
 using System.Runtime.InteropServices;
 using Microsoft.Identity.Client.Utils;
@@ -19,6 +20,8 @@ internal static class DesktopOsHelper
         private static Lazy s_winVersionLazy = new Lazy(
             GetWindowsVersionStringInternal);
 
+        private static Lazy s_wslEnvLazy = new Lazy(IsWslEnv);
+
         public static bool IsWindows()
         {
 
@@ -55,6 +58,22 @@ public static bool IsMac()
 #endif
         }
 
+        private static bool IsWslEnv()
+        {
+            if (IsLinux()) {
+                try
+                {
+                    var versionInfo = File.ReadAllText("/proc/version");
+                    return versionInfo.Contains("Microsoft") || versionInfo.Contains("WSL");
+                }
+                catch
+                {
+                    return false; // if we can't read the file, we can't determine if it's WSL
+                }
+            }
+            return false;
+        }
+
         /// 
         /// Checks if the OS supports WAM (Web Account Manager)
         /// WAM Supported OS's are Windows 10 and above for Client, Windows 2019 and above for Server
@@ -95,6 +114,11 @@ private static string GetWindowsVersionStringInternal()
 #endif
         }
 
+        public static bool IsRunningOnWsl()
+        {
+            return s_wslEnvLazy.Value;
+        }
+
         public static string GetWindowsVersionString()
         {
             return s_winVersionLazy.Value;
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
index 49930d7c11..bb29330d16 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
index cc453616ba..bb29330d16 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
-Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
+Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
index cc453616ba..5e303488d1 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
index cc453616ba..5e303488d1 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
index cc453616ba..5e303488d1 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
index cc453616ba..5e303488d1 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
@@ -1,2 +1,3 @@
+Microsoft.Identity.Client.BrokerOptions.OperatingSystems.Linux = 2 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.get -> System.Collections.Generic.IEnumerable
 Microsoft.Identity.Client.AssertionRequestOptions.ClientCapabilities.set -> void
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsMtlsPopTests.cs b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsMtlsPopTests.cs
index 55c924df51..0810388ff7 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsMtlsPopTests.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsMtlsPopTests.cs
@@ -6,6 +6,7 @@
 using Microsoft.Identity.Client;
 using Microsoft.Identity.Client.Internal;
 using Microsoft.Identity.Test.Common;
+using Microsoft.Identity.Test.Common.Core.Helpers;
 using Microsoft.Identity.Test.Integration.Infrastructure;
 using Microsoft.Identity.Test.Integration.NetFx.Infrastructure;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -24,6 +25,7 @@ public void TestInitialize()
             TestCommon.ResetInternalStaticCaches();
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task Sni_Gets_Pop_Token_Successfully_TestAsync()
         {
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsTests.NetFwk.cs b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsTests.NetFwk.cs
index e3bee50609..d1c7b042a6 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsTests.NetFwk.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/ClientCredentialsTests.NetFwk.cs
@@ -480,7 +480,8 @@ private static string GetSignedClientAssertionManual(
                 { "sub", issuer }
             };
 
-            RSACng rsa = certificate.GetRSAPrivateKey() as RSACng;
+            // cng is Windows specific, so we use RSA instead
+            RSA rsa = certificate.GetRSAPrivateKey();  // Works cross-platform
 
             Dictionary header;
             if (useSha2AndPss)
@@ -505,7 +506,14 @@ private static string GetSignedClientAssertionManual(
             var headerBytes = JsonSerializer.SerializeToUtf8Bytes(header);
             var claimsBytes = JsonSerializer.SerializeToUtf8Bytes(claims);
             string token = Base64UrlHelpers.Encode(headerBytes) + "." + Base64UrlHelpers.Encode(claimsBytes);
-
+            if (rsa is null)
+            {
+                throw new InvalidOperationException("RSA private key expected");
+            }
+            if (string.IsNullOrEmpty(token))
+            {
+                throw new InvalidOperationException("Token expected");
+            }
             //codeql [SM03799] Backwards Compatibility: Requires accepting PKCS1 for supporting ADFS 
             byte[] signatureBytes = rsa.SignData(
                     Encoding.UTF8.GetBytes(token),
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/MsalCacheStorageIntegrationTests.cs b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/MsalCacheStorageIntegrationTests.cs
index c309dbe284..3f2f7b9b8c 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/MsalCacheStorageIntegrationTests.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/MsalCacheStorageIntegrationTests.cs
@@ -125,15 +125,12 @@ public void CacheStorageFactory_WithFallback_Linux()
                     attribute2: new KeyValuePair("MsalClientVersion", "1.0.0.0"))
                 .Build();
 
-            // Tests run on machines without Libsecret
             Storage store = Storage.Create(storageWithKeyRing, logger: _logger);
             Assert.IsTrue(store.CacheAccessor is LinuxKeyringAccessor);
 
-            // ADO Linux test agents do not have libsecret installed by default
-            // If you run this test on a Linux box with UI / LibSecret, then this test will fail
-            // because the statement below will not throw.
-            AssertException.Throws(
-                () => store.VerifyPersistence());
+            // Installed libsecret on ADO Linux test agents, please see build/linux-install-deps.sh
+            // and setup keyring on the agent, please see build/template-test-on-linux.yml
+            store.VerifyPersistence();
 
             Storage unprotectedStore = Storage.Create(s_storageCreationProperties, _logger);
             Assert.IsTrue(unprotectedStore.CacheAccessor is FileAccessor);
@@ -147,8 +144,7 @@ public void CacheStorageFactory_WithFallback_Linux()
 
             // Mimic another sdk client to check libsecret availability by calling
             // MsalCacheStorage.VerifyPeristence() -> LinuxKeyringAccessor.CreateForPersistenceValidation()
-            AssertException.Throws(
-                () => store.VerifyPersistence());
+            store.VerifyPersistence();
 
             // Verify above call doesn't delete existing cache file
             Assert.IsTrue(File.Exists(s_storageCreationProperties.CacheFilePath));
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/PoPTests.NetFwk.cs b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/PoPTests.NetFwk.cs
index 8df3f05b09..a2e2757708 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/PoPTests.NetFwk.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/PoPTests.NetFwk.cs
@@ -16,6 +16,7 @@
 using Microsoft.Identity.Client.AppConfig;
 using Microsoft.Identity.Client.AuthScheme.PoP;
 using Microsoft.Identity.Client.Extensibility;
+using Microsoft.Identity.Client.Extensions.Msal;
 #if NET_CORE
 using Microsoft.Identity.Client.Broker;
 #endif
@@ -61,6 +62,7 @@ public async Task PoP_MultipleKeys_Async()
             await MultipleKeys_Async().ConfigureAwait(false);
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [RunOn(TargetFrameworks.NetCore)]
         public async Task PoP_BearerAndPoP_CanCoexist_Async()
         {
@@ -217,6 +219,7 @@ private async Task MultipleKeys_Async()
                 result);
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [RunOn(TargetFrameworks.NetCore)]
         public async Task PopTestWithConfigObjectAsync()
         {
@@ -254,6 +257,7 @@ public async Task PopTestWithConfigObjectAsync()
             Assert.AreEqual("RS256", alg, "The algorithm in the token header should be RS256");
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task PopTestWithRSAAsync()
         {
@@ -291,6 +295,7 @@ public async Task PopTestWithRSAAsync()
             Assert.AreEqual("RS256", alg, "The algorithm in the token header should be RS256");
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [RunOn(TargetFrameworks.NetCore)]
         public async Task ROPC_PopTestWithRSAAsync()
         {
@@ -323,6 +328,7 @@ public async Task ROPC_PopTestWithRSAAsync()
 
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task PopTest_ExternalWilsonSigning_Async()
         {
@@ -388,7 +394,8 @@ public async Task PopTest_ExternalWilsonSigning_Async()
                 TokenSource.Cache,
                 result2.AuthenticationResultMetadata.TokenSource);
         }
-
+        
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task PopTestWithECDAsync()
         {
@@ -427,6 +434,7 @@ public async Task PopTestWithECDAsync()
                 result);
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task NewPOP_WithKeyIdOnly_Async()
         {
@@ -520,6 +528,7 @@ public async Task NewPOP_WithKeyIdOnly_Async()
                 result2.AuthenticationResultMetadata.TokenSource);
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task InMemoryCryptoProvider_AlgIsPS256()
         {
@@ -662,6 +671,7 @@ public async Task InMemoryCryptoProvider_WithGraph()
             Assert.IsTrue(responseWithPopToken.IsSuccessStatusCode, "The response should be successful with the PoP token");
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [TestMethod]
         public async Task PoPToken_ShouldHaveCorrectAlgorithm_PS256_Async()
         {
@@ -700,6 +710,7 @@ public async Task PoPToken_ShouldHaveCorrectAlgorithm_PS256_Async()
         }
 
 #if NET_CORE
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [IgnoreOnOneBranch]
         public async Task WamUsernamePasswordRequestWithPOPAsync()
         {
@@ -740,31 +751,29 @@ public async Task WamUsernamePasswordRequestWithPOPAsync()
         public void CheckPopRuntimeBrokerSupportTest()
         {
             //Broker enabled
-            var pcaBuilder = PublicClientApplicationBuilder
-                                            .Create(TestConstants.ClientId);
-
-            pcaBuilder = pcaBuilder.WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows));
-
-            IPublicClientApplication app = pcaBuilder.Build();
-
-            Assert.IsTrue(app.IsProofOfPossessionSupportedByClient());
+            if (SharedUtilities.IsWindowsPlatform()) {
+                CheckPopSupport(new BrokerOptions(BrokerOptions.OperatingSystems.Windows), true);
+            }
 
             //Broker disabled
-            pcaBuilder = PublicClientApplicationBuilder
-                                .Create(TestConstants.ClientId);
+            CheckPopSupport(new BrokerOptions(BrokerOptions.OperatingSystems.None), false);
 
-            pcaBuilder.WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.None));
-
-            app = pcaBuilder.Build();
+            // POP is not supported on Linux
+            if (SharedUtilities.IsLinuxPlatform()) {
+                CheckPopSupport(new BrokerOptions(BrokerOptions.OperatingSystems.Linux), false);
+            }
+        }
+        
+        private static void CheckPopSupport(BrokerOptions brokerOptions, bool isPopSupported)
+        {
+            var pcaBuilder = PublicClientApplicationBuilder
+                .Create(TestConstants.ClientId);
 
-            Assert.IsFalse(app.IsProofOfPossessionSupportedByClient());
+            pcaBuilder = pcaBuilder.WithBroker(brokerOptions);
 
-            //Broker not configured
-            app = PublicClientApplicationBuilder
-                                .Create(TestConstants.ClientId)
-                                .Build();
+            IPublicClientApplication app = pcaBuilder.Build();
 
-            Assert.IsFalse(app.IsProofOfPossessionSupportedByClient());
+            Assert.AreEqual(isPopSupported, app.IsProofOfPossessionSupportedByClient());
         }
 #endif
 
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/RuntimeBrokerTests.cs b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/RuntimeBrokerTests.cs
index 9a828527fd..455a047d4f 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/RuntimeBrokerTests.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/RuntimeBrokerTests.cs
@@ -18,6 +18,7 @@
 using Microsoft.Identity.Client.ApiConfig;
 using Microsoft.Identity.Client.Broker;
 using Microsoft.Identity.Client.Core;
+using Microsoft.Identity.Client.Extensions.Msal;
 using Microsoft.Identity.Client.OAuth2;
 using Microsoft.Identity.Client.SSHCertificates;
 using Microsoft.Identity.Client.UI;
@@ -26,6 +27,7 @@
 using Microsoft.Identity.Test.Common.Core.Helpers;
 using Microsoft.Identity.Test.Common.Core.Mocks;
 using Microsoft.Identity.Test.Integration.Infrastructure;
+using Microsoft.Identity.Test.Integration.Utils;
 using Microsoft.Identity.Test.LabInfrastructure;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using NSubstitute;
@@ -35,14 +37,13 @@ namespace Microsoft.Identity.Test.Integration.Broker
     [TestClass]
     public class RuntimeBrokerTests
     {
-        [DllImport("user32.dll")]
-        static extern IntPtr GetForegroundWindow();
-
         //This client id is for Azure CLI which is one of the only 2 clients that have PreAuth to use ssh cert feature
         string _SSH_ClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
         //SSH User impersonation scope required for this test
         private string[] _SSH_scopes = new[] { "https://pas.windows.net/CheckMyAccess/Linux/user_impersonation" };
 
+        private BrokerOptions _brokerOptions = TestUtils.GetPlatformBroker();
+
         private string CreateJwk()
         {
             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
@@ -70,7 +71,7 @@ public async Task WamSilentAuthUserInteractionRequiredAsync()
                .WithAuthority("https://login.microsoftonline.com/organizations");
 
             IPublicClientApplication pca = pcaBuilder
-                .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+                .WithBroker(_brokerOptions)
                 .Build();
 
             // Act
@@ -90,6 +91,7 @@ public async Task WamSilentAuthUserInteractionRequiredAsync()
             }
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux
         [IgnoreOnOneBranch]
         [TestMethod]
         public async Task ExtractNonceWithAuthParserAndValidateShrAsync()
@@ -104,7 +106,7 @@ public async Task ExtractNonceWithAuthParserAndValidateShrAsync()
             IPublicClientApplication pca = PublicClientApplicationBuilder
                .Create(labResponse.App.AppId)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             Assert.IsTrue(pca.IsProofOfPossessionSupportedByClient(), "Either the broker is not configured or it does not support POP.");
@@ -135,7 +137,7 @@ public async Task ExtractNonceWithAuthParserAndValidateShrAsync()
                 result);
         }
     
-
+        [DoNotRunOnLinux] // Linux broker return different error code
         [IgnoreOnOneBranch]
         [TestMethod]
         public async Task WamInvalidROPC_ThrowsException_TestAsync()
@@ -148,7 +150,7 @@ public async Task WamInvalidROPC_ThrowsException_TestAsync()
                .Create(labResponse.App.AppId)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
                .WithLogging(wastestLogger, enablePiiLogging: true) // it's important that the PII is turned on, otherwise context is 'pii'
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             MsalServiceException ex = await AssertException.TaskThrowsAsync(() =>
@@ -164,6 +166,7 @@ public async Task WamInvalidROPC_ThrowsException_TestAsync()
             Assert.AreEqual("ApiContractViolation", ex.AdditionalExceptionData[MsalException.BrokerErrorStatus]);
             Assert.AreEqual("3399811229", ex.AdditionalExceptionData[MsalException.BrokerErrorCode]);
             Assert.IsNotNull(ex.AdditionalExceptionData[MsalException.BrokerTelemetry]);
+            
         }
 
         [IgnoreOnOneBranch]
@@ -180,7 +183,7 @@ public async Task WamSilentAuthLoginHintNoAccontInCacheAsync()
                .WithAuthority("https://login.microsoftonline.com/organizations");
 
             IPublicClientApplication pca = pcaBuilder
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             // Act
@@ -203,7 +206,7 @@ public async Task WamUsernamePasswordRequestAsync()
             var labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false);
             string[] scopes = { "User.Read" };            
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -211,17 +214,20 @@ public async Task WamUsernamePasswordRequestAsync()
                .Create(labResponse.App.AppId)
                .WithParentActivityOrWindow(windowHandleProvider)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithLogging((x, y, z) => Debug.WriteLine($"{x} {y}"), LogLevel.Verbose, true)
+               .WithBroker(_brokerOptions)
                .Build();
 
+            // Get Accounts
+            var accounts = await pca.GetAccountsAsync().ConfigureAwait(false);
+
             // Acquire token using username password
             var result = await pca.AcquireTokenByUsernamePassword(scopes, labResponse.User.Upn, labResponse.User.GetOrFetchPassword()).ExecuteAsync().ConfigureAwait(false);
-
             MsalAssert.AssertAuthResult(result, TokenSource.Broker, labResponse.Lab.TenantId, scopes);
             Assert.IsNotNull(result.AuthenticationResultMetadata.Telemetry);
 
             // Get Accounts
-            var accounts = await pca.GetAccountsAsync().ConfigureAwait(false);
+            accounts = await pca.GetAccountsAsync().ConfigureAwait(false);
             Assert.IsNotNull(accounts);
 
             var account = accounts.FirstOrDefault();
@@ -246,11 +252,12 @@ await AssertException.TaskThrowsAsync(
                 .ConfigureAwait(false);
         }
 
+        [DoNotRunOnLinux] // SSH Certs are not supported on Linux
         [IgnoreOnOneBranch]
         [TestMethod]
         public async Task WamWithSSHCertificateAuthenticationSchemeAsync()
         {
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
             Func windowHandleProvider = () => intPtr;
             var labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false);
 
@@ -259,7 +266,7 @@ public async Task WamWithSSHCertificateAuthenticationSchemeAsync()
             .WithTestLogging()
             .WithAuthority(labResponse.Lab.Authority, "organizations")
             .WithParentActivityOrWindow(windowHandleProvider)
-            .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+            .WithBroker(_brokerOptions)
             .Build();
 
             string jwk = CreateJwk();
@@ -292,14 +299,15 @@ public async Task WamUsernamePasswordWithForceRefreshAsync()
             var labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false);
             string[] scopes = { "User.Read" };
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
             Func windowHandleProvider = () => intPtr;
 
             IPublicClientApplication pca = PublicClientApplicationBuilder
                .Create(labResponse.App.AppId)
                .WithParentActivityOrWindow(windowHandleProvider)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithLogging((x, y, z) => Debug.WriteLine($"{x} {y}"), LogLevel.Verbose, true)
+               .WithBroker(_brokerOptions)
                .Build();
 
             // Acquire token using username password
@@ -342,7 +350,7 @@ public async Task WamUsernamePasswordRequestAsync_WithPiiAsync()
             var labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false);
             string[] scopes = { "User.Read" };
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -353,7 +361,7 @@ public async Task WamUsernamePasswordRequestAsync_WithPiiAsync()
                .WithParentActivityOrWindow(windowHandleProvider)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
                .WithLogging(testLogger, enablePiiLogging: true)
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             // Acquire token using username password
@@ -387,6 +395,7 @@ public async Task WamUsernamePasswordRequestAsync_WithPiiAsync()
             result = await pca.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);
         }
 
+        [DoNotRunOnLinux] // List Windows Work and School accounts is not supported on Linux
         [IgnoreOnOneBranch]
         [TestMethod]
         public async Task WamListWindowsWorkAndSchoolAccountsAsync()
@@ -394,7 +403,7 @@ public async Task WamListWindowsWorkAndSchoolAccountsAsync()
             var labResponse = await LabUserHelper.GetDefaultUserAsync().ConfigureAwait(false);
             string[] scopes = { "User.Read" };
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -430,7 +439,7 @@ public async Task WamListWindowsWorkAndSchoolAccountsAsync()
         [TestMethod]
         public async Task WamAddDefaultScopesWhenNoScopesArePassedAsync(string scopes)
         {
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -438,18 +447,25 @@ public async Task WamAddDefaultScopesWhenNoScopesArePassedAsync(string scopes)
                .Create("43dfbb29-3683-4673-a66f-baba91798bd2")
                .WithAuthority("https://login.microsoftonline.com/organizations")
                .WithParentActivityOrWindow(windowHandleProvider)
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
-
             // Act
-            var ex = await AssertException.TaskThrowsAsync(
+            if (SharedUtilities.IsLinuxPlatform()) {
+                var exLinux = await AssertException.TaskThrowsAsync(
                  () => pca.AcquireTokenSilent(new string[] { scopes }, PublicClientApplication.OperatingSystemAccount)
                         .ExecuteAsync())
                         .ConfigureAwait(false);
-
-            Assert.IsTrue(!string.IsNullOrEmpty(ex.ErrorCode));
+                StringAssert.Contains(exLinux.AdditionalExceptionData[MsalException.BrokerErrorContext], "requestedScopes is NULL or EMPTY");
+            } else {
+                var ex = await AssertException.TaskThrowsAsync(
+                 () => pca.AcquireTokenSilent(new string[] { scopes }, PublicClientApplication.OperatingSystemAccount)
+                        .ExecuteAsync())
+                        .ConfigureAwait(false);
+                Assert.IsTrue(!string.IsNullOrEmpty(ex.ErrorCode));
+            }
         }
 
+        [DoNotRunOnLinux] // POP is not supported on Linux     
         [IgnoreOnOneBranch]
         [TestMethod]
         public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnValidResourceAsync()
@@ -461,7 +477,7 @@ public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnValidResourceAsync(
 
             string[] scopes = { "https://msidlab4.sharepoint.com/user.read" };
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -469,7 +485,7 @@ public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnValidResourceAsync(
                .Create(labResponse.App.AppId)
                .WithParentActivityOrWindow(windowHandleProvider)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             // Acquire token using username password with POP on a valid resource
@@ -484,6 +500,7 @@ public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnValidResourceAsync(
             Assert.AreEqual(popUser, result.Account.Username);
         }
 
+        [DoNotRunOnLinux] // POP are not supported on Linux  
         [IgnoreOnOneBranch]
         [TestMethod]
         [ExpectedException(typeof(MsalUiRequiredException))]
@@ -496,7 +513,7 @@ public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnInValidResourceAsyn
 
             string[] scopes = { "user.read" };
 
-            IntPtr intPtr = GetForegroundWindow();
+            IntPtr intPtr = TestUtils.GetWindowHandle();
 
             Func windowHandleProvider = () => intPtr;
 
@@ -504,7 +521,7 @@ public async Task WamUsernamePasswordPopTokenEnforcedWithCaOnInValidResourceAsyn
                .Create(labResponse.App.AppId)
                .WithParentActivityOrWindow(windowHandleProvider)
                .WithAuthority(labResponse.Lab.Authority, "organizations")
-               .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
+               .WithBroker(_brokerOptions)
                .Build();
 
             // Acquire token using username password with POP on a resource not in the CA policy
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/DeviceCodeFlowIntegrationTest.cs b/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/DeviceCodeFlowIntegrationTest.cs
index cd341b3a9e..5bb6aaa179 100644
--- a/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/DeviceCodeFlowIntegrationTest.cs
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/DeviceCodeFlowIntegrationTest.cs
@@ -9,6 +9,7 @@
 using Microsoft.Identity.Test.Common;
 using Microsoft.Identity.Test.Common.Core.Helpers;
 using Microsoft.Identity.Test.Integration.Infrastructure;
+using Microsoft.Identity.Test.Integration.Utils;
 using Microsoft.Identity.Test.LabInfrastructure;
 using Microsoft.Identity.Test.Unit;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -126,7 +127,7 @@ private async Task AcquireTokenWithDeviceCodeFlowAsync(LabResponse labResponse,
         private async Task AcquireTokenSilentAfterDeviceCodeFlowWithBrokerAsync(LabResponse labResponse, string userType)
         {
             Trace.WriteLine($"Calling AcquireTokenSilentAfterDeviceCodeFlowWithBrokerAsync with {0}", userType);
-            BrokerOptions options = new BrokerOptions(BrokerOptions.OperatingSystems.Windows);
+            BrokerOptions options = TestUtils.GetPlatformBroker();
             var builder = PublicClientApplicationBuilder.Create(labResponse.App.AppId).WithTestLogging().WithBroker(options);
 
             switch (labResponse.User.AzureEnvironment)
diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/Utils/TestUtils.cs b/tests/Microsoft.Identity.Test.Integration.netcore/Utils/TestUtils.cs
new file mode 100644
index 0000000000..949b5b16a4
--- /dev/null
+++ b/tests/Microsoft.Identity.Test.Integration.netcore/Utils/TestUtils.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Runtime.InteropServices;
+using Microsoft.Identity.Client;
+
+namespace Microsoft.Identity.Test.Integration.Utils
+{
+    public static class TestUtils
+    {
+        /// 
+        /// Get the handle of the foreground window for Windows
+        /// 
+        [DllImport("user32.dll")]
+        static extern IntPtr GetForegroundWindow();
+
+        /// 
+        /// Get the handle of the console window for Linux
+        /// 
+        [DllImport("libX11.so.6")]
+        private static extern IntPtr XOpenDisplay(string display);
+
+        [DllImport("libX11.so.6")]
+        private static extern IntPtr XRootWindow(IntPtr display, int screen);
+
+        [DllImport("libX11.so.6")]
+        private static extern IntPtr XDefaultRootWindow(IntPtr display);
+
+        /// 
+        /// Get window handle on xplat
+        /// 
+        public static IntPtr GetWindowHandle()
+        {
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                return GetForegroundWindow();
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+            {
+                try {
+                    IntPtr display = XOpenDisplay(":1");
+                    if (display == IntPtr.Zero)
+                    {
+                        Console.WriteLine("No X display available. Running in headless mode.");
+                    }
+                    else
+                    {
+                        Console.WriteLine("X display is available.");
+                    }
+                    return display;
+                } catch (System.Exception ex)
+                {
+                    Console.ForegroundColor = ConsoleColor.Red;
+                    Console.WriteLine(ex.ToString());
+                    Console.ResetColor();
+                }
+                return IntPtr.Zero;
+            }
+            else
+            {
+                throw new PlatformNotSupportedException("This platform is not supported.");
+            }
+        }
+
+        public static BrokerOptions GetPlatformBroker() {
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                return new BrokerOptions(BrokerOptions.OperatingSystems.Windows);
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+            {
+                return new BrokerOptions(BrokerOptions.OperatingSystems.Linux){ListOperatingSystemAccounts = true,};
+            }
+            else
+            {
+                throw new PlatformNotSupportedException("This platform is not supported.");
+            }
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/tests/Microsoft.Identity.Test.LabInfrastructure/CertificateHelper.cs b/tests/Microsoft.Identity.Test.LabInfrastructure/CertificateHelper.cs
index 1c4519e621..1a2b3e2e43 100644
--- a/tests/Microsoft.Identity.Test.LabInfrastructure/CertificateHelper.cs
+++ b/tests/Microsoft.Identity.Test.LabInfrastructure/CertificateHelper.cs
@@ -3,6 +3,7 @@
 
 using System;
 using System.Security.Cryptography.X509Certificates;
+using Microsoft.Identity.Client.Extensions.Msal;
 
 namespace Microsoft.Identity.Test.LabInfrastructure
 {
@@ -37,9 +38,16 @@ public static X509Certificate2 FindCertificateByName(string subjectName)
         ///  with , or null if no matching certificate was found
         public static X509Certificate2 FindCertificateByName(string certName, StoreLocation location, StoreName name)
         {
+            // Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores
+            if (SharedUtilities.IsLinuxPlatform())
+            {
+                var certPasswrod = Environment.GetEnvironmentVariable("CERTIFICATE_PASSWORD");
+                var certLocation = Environment.GetEnvironmentVariable("CERTIFICATE_LOCATION");
+                var cert = new X509Certificate2(certLocation, certPasswrod, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
+                return cert;
+            }
             // Don't validate certs, since the test root isn't installed.
             const bool validateCerts = false;
-
             using (var store = new X509Store(name, location))
             {
                 store.Open(OpenFlags.ReadOnly);
diff --git a/tests/Microsoft.Identity.Test.LabInfrastructure/Microsoft.Identity.Test.LabInfrastructure.csproj b/tests/Microsoft.Identity.Test.LabInfrastructure/Microsoft.Identity.Test.LabInfrastructure.csproj
index 7c8ed47cba..cb491f52d7 100644
--- a/tests/Microsoft.Identity.Test.LabInfrastructure/Microsoft.Identity.Test.LabInfrastructure.csproj
+++ b/tests/Microsoft.Identity.Test.LabInfrastructure/Microsoft.Identity.Test.LabInfrastructure.csproj
@@ -17,6 +17,7 @@
       Microsoft.Identity.Client
     
     
+    
   
 
   
diff --git a/tests/Microsoft.Identity.Test.Unit/Microsoft.Identity.Test.Unit.csproj b/tests/Microsoft.Identity.Test.Unit/Microsoft.Identity.Test.Unit.csproj
index 275d5e892e..eb6a842e0f 100644
--- a/tests/Microsoft.Identity.Test.Unit/Microsoft.Identity.Test.Unit.csproj
+++ b/tests/Microsoft.Identity.Test.Unit/Microsoft.Identity.Test.Unit.csproj
@@ -10,7 +10,6 @@
     Debug;Release;Debug + MobileApps
 
     AnyCPU;x64
-  
 
 
   
diff --git a/tests/devapps/WAM/NetWSLWam/Class1.cs b/tests/devapps/WAM/NetWSLWam/Class1.cs
new file mode 100644
index 0000000000..826bddf419
--- /dev/null
+++ b/tests/devapps/WAM/NetWSLWam/Class1.cs
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Identity.Client;
+using Microsoft.Identity.Client.Broker;
+
+namespace WAMClassLibrary
+{
+    public class Authentication
+    {
+        /// 
+        /// Get the handle of the console window for Linux
+        /// 
+        [DllImport("libX11")]
+        private static extern IntPtr XOpenDisplay(string display);
+
+        [DllImport("libX11")]
+        private static extern IntPtr XRootWindow(IntPtr display, int screen);
+
+        [DllImport("libX11")]
+        private static extern IntPtr XDefaultRootWindow(IntPtr display);
+
+
+        public static async Task InvokeBrokerAsync()
+        {
+            IntPtr _parentHandle = XRootWindow(XOpenDisplay(null), 0);;
+            Func consoleWindowHandleProvider = () => _parentHandle;
+
+            // 1. Configuration - read below about redirect URI
+            var pca = PublicClientApplicationBuilder.Create("4b0db8c2-9f26-4417-8bde-3f0e3656f8e0"/*Lab Public Multi-Tenant*/)
+                          .WithAuthority("https://login.microsoftonline.com/common")
+                          .WithDefaultRedirectUri()
+                          .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Linux){
+                            ListOperatingSystemAccounts = true,
+                            MsaPassthrough = true,
+                            Title = "MSAL WSL Test App"
+                          })
+                          .WithParentActivityOrWindow(consoleWindowHandleProvider)
+                          .WithLogging((x, y, z) => Console.WriteLine($"{x} {y}"), LogLevel.Verbose, true)
+                          .Build();
+
+            // Add a token cache, see https://learn.microsoft.com/entra/msal/dotnet/how-to/token-cache-serialization?tabs=desktop
+
+            // 2. GetAccounts
+            var accounts = await pca.GetAccountsAsync().ConfigureAwait(false);
+            var accountToLogin = accounts.FirstOrDefault();
+
+            try
+            {
+                var authResult = await pca.AcquireTokenSilent(new[] { "user.read" }, accountToLogin)
+                                      .ExecuteAsync().ConfigureAwait(false);
+            }
+            catch (MsalUiRequiredException ex)
+            {
+                Console.WriteLine(ex.Message);
+                Console.WriteLine(ex.ErrorCode);
+            }
+
+            try
+            {
+                var authResult = await pca.AcquireTokenInteractive(new[] { "user.read" }).WithLoginHint("idlab@msidlab4.onmicrosoft.com")
+                                      .ExecuteAsync().ConfigureAwait(false);
+
+                Console.WriteLine(authResult.Account);
+
+                Console.WriteLine("Acquired Token Successfully!!!");
+
+            }
+            catch (MsalClientException ex)
+            {
+                int errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
+                Console.WriteLine("MsalClientException (ErrCode " + errorCode + "): " + ex.Message);
+            }
+            catch (MsalException ex)
+            {
+                Console.WriteLine($"MsalException Error signing-out user: {ex.Message}");
+            }
+            catch (Exception ex)
+            {
+                int errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
+                Console.WriteLine("Error Acquiring Token (ErrCode " + errorCode + "): " + ex);
+            }
+            Console.Read();
+        }
+
+        public static void Main(string[] args)
+        {
+            InvokeBrokerAsync().Wait();
+        }
+    }
+}
diff --git a/tests/devapps/WAM/NetWSLWam/Properties/launchSettings.json b/tests/devapps/WAM/NetWSLWam/Properties/launchSettings.json
new file mode 100644
index 0000000000..0411ab6b8c
--- /dev/null
+++ b/tests/devapps/WAM/NetWSLWam/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+  "profiles": {
+    "test": {
+      "commandName": "Project"
+    },
+    "WSL": {
+      "commandName": "WSL2",
+      "distributionName": ""
+    }
+  }
+}
\ No newline at end of file
diff --git a/tests/devapps/WAM/NetWSLWam/test.csproj b/tests/devapps/WAM/NetWSLWam/test.csproj
new file mode 100644
index 0000000000..ec3de2464c
--- /dev/null
+++ b/tests/devapps/WAM/NetWSLWam/test.csproj
@@ -0,0 +1,19 @@
+
+
+  
+    net8.0
+    Exe
+    latest
+    false
+  
+  
+    
+      {6839f934-45f0-4026-8af3-c3aefb7d48a9}
+      Microsoft.Identity.Client.Broker
+    
+    
+      {60117a9b-4bb8-472e-bfff-52cbf67ca95a}
+      Microsoft.Identity.Client
+    
+  
+
\ No newline at end of file