diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/InteractiveShellTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/InteractiveShellTests.cs
index 957abdb..5d9381e 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/InteractiveShellTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/InteractiveShellTests.cs
@@ -13,6 +13,7 @@ namespace ZB.MOM.WW.Secrets.Tests.Cli.Interactive;
/// KEK-upgrade prompt, and the error-containment panel. The shell is the only UI-owning class, so these
/// tests assert on rendered and on what a fake flow observed.
///
+[Collection("Process environment")]
public sealed class InteractiveShellTests : IDisposable
{
private readonly string _dir =
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/LiteralMasterKeyProviderTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/LiteralMasterKeyProviderTests.cs
index e718344..b1400bd 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/LiteralMasterKeyProviderTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/LiteralMasterKeyProviderTests.cs
@@ -11,6 +11,7 @@ namespace ZB.MOM.WW.Secrets.Tests.Cli.Interactive;
/// derived identically to the configured providers so a key
/// entered by hand can decrypt (and re-wrap) rows another provider kind sealed.
///
+[Collection("Process environment")]
public sealed class LiteralMasterKeyProviderTests
{
private static string NewKeyBase64()
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/ReferenceAuditorTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/ReferenceAuditorTests.cs
index a3d2eac..1878f79 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/ReferenceAuditorTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/ReferenceAuditorTests.cs
@@ -13,6 +13,7 @@ namespace ZB.MOM.WW.Secrets.Tests.Cli.Interactive;
/// (present/decryptable → Ok, absent → Missing, tombstoned → Tombstoned, wrong-KEK → Undecryptable),
/// and the degraded-session presence-only downgrade (present → PresentUnverified).
///
+[Collection("Process environment")]
public sealed class ReferenceAuditorTests : IDisposable
{
private readonly string _dir =
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/SecretsSessionFactoryTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/SecretsSessionFactoryTests.cs
index 6359cc6..3ddf696 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/SecretsSessionFactoryTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/Cli/Interactive/SecretsSessionFactoryTests.cs
@@ -13,6 +13,7 @@ namespace ZB.MOM.WW.Secrets.Tests.Cli.Interactive;
/// (KEK unresolvable → degraded session that still lists metadata), the operator-override upgrade, and
/// the SQL-Server-with-unresolved-secret-ref fall-back to the local store.
///
+[Collection("Process environment")]
public sealed class SecretsSessionFactoryTests : IDisposable
{
private readonly string _dir =
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/DependencyInjection/AddZbSecretsTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/DependencyInjection/AddZbSecretsTests.cs
index bea5dff..058cd3b 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/DependencyInjection/AddZbSecretsTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/DependencyInjection/AddZbSecretsTests.cs
@@ -12,6 +12,7 @@ namespace ZB.MOM.WW.Secrets.Tests.DependencyInjection;
/// core: every seam resolves, a real secret round-trips through the composed graph, and a missing
/// master key fails closed.
///
+[Collection("Process environment")]
public sealed class AddZbSecretsTests
{
private static string NewTempDbPath() =>
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/MasterKey/MasterKeyProviderTests.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/MasterKey/MasterKeyProviderTests.cs
index 4450466..a0b40b8 100644
--- a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/MasterKey/MasterKeyProviderTests.cs
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/MasterKey/MasterKeyProviderTests.cs
@@ -4,6 +4,7 @@ using ZB.MOM.WW.Secrets.MasterKey;
namespace ZB.MOM.WW.Secrets.Tests.MasterKey;
+[Collection("Process environment")]
public class MasterKeyProviderTests
{
// ---- Environment ----------------------------------------------------------------------
diff --git a/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/ProcessEnvironmentCollection.cs b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/ProcessEnvironmentCollection.cs
new file mode 100644
index 0000000..e6e31c3
--- /dev/null
+++ b/ZB.MOM.WW.Secrets/tests/ZB.MOM.WW.Secrets.Tests/ProcessEnvironmentCollection.cs
@@ -0,0 +1,10 @@
+namespace ZB.MOM.WW.Secrets.Tests;
+
+///
+/// Serializes every test class that mutates process environment variables. setenv/getenv operate
+/// on the single process-wide environ, which is not safe under concurrent mutation on glibc —
+/// unique variable names do not remove the race, only serialization does. Classes that never
+/// touch the environment stay fully parallel.
+///
+[CollectionDefinition("Process environment", DisableParallelization = true)]
+public sealed class ProcessEnvironmentCollection;