diff --git a/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs b/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs
index 172f968baa30..8e4bc29b7656 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Collections.Concurrent;
+using System.ComponentModel;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Net;
@@ -38,12 +39,14 @@ private sealed record AuthInfo(string Realm, string? Service, string? Scope);
 
     private readonly string _registryName;
     private readonly ILogger _logger;
+    private readonly RegistryMode _registryMode;
     private static ConcurrentDictionary<string, AuthenticationHeaderValue?> _authenticationHeaders = new();
 
-    public AuthHandshakeMessageHandler(string registryName, HttpMessageHandler innerHandler, ILogger logger) : base(innerHandler)
+    public AuthHandshakeMessageHandler(string registryName, HttpMessageHandler innerHandler, ILogger logger, RegistryMode mode) : base(innerHandler)
     {
         _registryName = registryName;
         _logger = logger;
+        _registryMode = mode;
     }
 
     /// <summary>
@@ -156,14 +159,10 @@ public DateTimeOffset ResolvedExpiration
     /// </summary>
     private async Task<(AuthenticationHeaderValue, DateTimeOffset)?> GetAuthenticationAsync(string registry, string scheme, AuthInfo? bearerAuthInfo, CancellationToken cancellationToken)
     {
-        // Allow overrides for auth via environment variables
-        string? credU = Environment.GetEnvironmentVariable(ContainerHelpers.HostObjectUser) ?? Environment.GetEnvironmentVariable(ContainerHelpers.HostObjectUserLegacy);
-        string? credP = Environment.GetEnvironmentVariable(ContainerHelpers.HostObjectPass) ?? Environment.GetEnvironmentVariable(ContainerHelpers.HostObjectPassLegacy);
-
-        // fetch creds for the host
+        
         DockerCredentials? privateRepoCreds;
-
-        if (!string.IsNullOrEmpty(credU) && !string.IsNullOrEmpty(credP))
+        // Allow overrides for auth via environment variables
+        if (GetDockerCredentialsFromEnvironment(_registryMode) is (string credU, string credP))
         {
             privateRepoCreds = new DockerCredentials(credU, credP);
         }
@@ -196,6 +195,63 @@ public DateTimeOffset ResolvedExpiration
         }
     }
 
+    internal static (string credU, string credP)? TryGetCredentialsFromEnvVars(string unameVar, string passwordVar)
+    {
+        var credU = Environment.GetEnvironmentVariable(unameVar);
+        var credP = Environment.GetEnvironmentVariable(passwordVar);
+        if (!string.IsNullOrEmpty(credU) && !string.IsNullOrEmpty(credP))
+        {
+            return (credU, credP);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /// <summary>
+    /// Gets docker credentials from the environment variables based on registry mode.
+    /// </summary>
+    internal static (string credU, string credP)? GetDockerCredentialsFromEnvironment(RegistryMode mode)
+    {
+        if (mode == RegistryMode.Push)
+        {
+            if (TryGetCredentialsFromEnvVars(ContainerHelpers.PushHostObjectUser, ContainerHelpers.PushHostObjectPass) is (string, string) pushCreds)
+            {
+                return pushCreds;
+            }
+
+            if (TryGetCredentialsFromEnvVars(ContainerHelpers.HostObjectUser, ContainerHelpers.HostObjectPass) is (string, string) genericCreds)
+            {
+                return genericCreds;
+            }
+
+            return TryGetCredentialsFromEnvVars(ContainerHelpers.HostObjectUserLegacy, ContainerHelpers.HostObjectPassLegacy);
+        }
+        else if (mode == RegistryMode.Pull)
+        {
+            return TryGetCredentialsFromEnvVars(ContainerHelpers.PullHostObjectUser, ContainerHelpers.PullHostObjectPass);
+        }
+        else if (mode == RegistryMode.PullFromOutput)
+        {
+            if (TryGetCredentialsFromEnvVars(ContainerHelpers.PullHostObjectUser, ContainerHelpers.PullHostObjectPass) is (string, string) pullCreds)
+            {
+                return pullCreds;
+            }
+
+            if (TryGetCredentialsFromEnvVars(ContainerHelpers.HostObjectUser, ContainerHelpers.HostObjectPass) is (string, string) genericCreds)
+            {
+                return genericCreds;
+            }
+
+            return TryGetCredentialsFromEnvVars(ContainerHelpers.HostObjectUserLegacy, ContainerHelpers.HostObjectPassLegacy);
+        }
+        else
+        {
+            throw new InvalidEnumArgumentException(nameof(mode), (int)mode, typeof(RegistryMode));
+        }
+    }
+
     /// <summary>
     /// Implements the Docker OAuth2 Authentication flow as documented at <see href="https://docs.docker.com/registry/spec/auth/oauth/"/>.
     /// </summary
diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
index c63227808ca1..48867a93de6b 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
@@ -45,7 +45,8 @@ internal static async Task<int> ContainerizeAsync(
         logger.LogTrace("Trace logging: enabled.");
 
         bool isLocalPull = string.IsNullOrEmpty(baseRegistry);
-        Registry? sourceRegistry = isLocalPull ? null : new Registry(baseRegistry, logger);
+        RegistryMode sourceRegistryMode = baseRegistry.Equals(outputRegistry, StringComparison.InvariantCultureIgnoreCase) ? RegistryMode.PullFromOutput : RegistryMode.Pull;
+        Registry? sourceRegistry = isLocalPull ? null : new Registry(baseRegistry, logger, sourceRegistryMode);
         SourceImageReference sourceImageReference = new(sourceRegistry, baseImageName, baseImageTag);
 
         DestinationImageReference destinationImageReference = DestinationImageReference.CreateFromSettings(
diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
index 137755cdeb3d..3a1ff7b8d004 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
@@ -22,6 +22,12 @@ public static class ContainerHelpers
     internal const string HostObjectPass = "DOTNET_CONTAINER_REGISTRY_PWORD";
     internal const string HostObjectPassLegacy = "SDK_CONTAINER_REGISTRY_PWORD";
 
+    internal const string PushHostObjectUser = "DOTNET_CONTAINER_PUSH_REGISTRY_UNAME";
+    internal const string PushHostObjectPass = "DOTNET_CONTAINER_PUSH_REGISTRY_PWORD";
+
+    internal const string PullHostObjectUser = "DOTNET_CONTAINER_PULL_REGISTRY_UNAME";
+    internal const string PullHostObjectPass = "DOTNET_CONTAINER_PULL_REGISTRY_PWORD";
+
     internal const string DockerRegistryAlias = "docker.io";
     
     /// <summary>
diff --git a/src/Containers/Microsoft.NET.Build.Containers/DestinationImageReference.cs b/src/Containers/Microsoft.NET.Build.Containers/DestinationImageReference.cs
index dc9c99a9fb97..a6c92d93dd80 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/DestinationImageReference.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/DestinationImageReference.cs
@@ -75,7 +75,10 @@ public static DestinationImageReference CreateFromSettings(
         }
         else if (!string.IsNullOrEmpty(outputRegistry))
         {
-            destinationImageReference = new DestinationImageReference(new Registry(outputRegistry, loggerFactory.CreateLogger<Registry>()), repository, imageTags);
+            destinationImageReference = new DestinationImageReference(
+                new Registry(outputRegistry, loggerFactory.CreateLogger<Registry>(), RegistryMode.Push),
+                repository,
+                imageTags);
         }
         else
         {
diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultRegistryAPI.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultRegistryAPI.cs
index 71b937233fe4..dff5a8921cc2 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultRegistryAPI.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultRegistryAPI.cs
@@ -22,11 +22,11 @@ internal class DefaultRegistryAPI : IRegistryAPI
     // Making this a round 30 for convenience.
     private static TimeSpan LongRequestTimeout = TimeSpan.FromMinutes(30);
 
-    internal DefaultRegistryAPI(string registryName, Uri baseUri, bool isInsecureRegistry, ILogger logger)
+    internal DefaultRegistryAPI(string registryName, Uri baseUri, bool isInsecureRegistry, ILogger logger, RegistryMode mode)
     {
         _baseUri = baseUri;
         _logger = logger;
-        _client = CreateClient(registryName, baseUri, isInsecureRegistry, logger);
+        _client = CreateClient(registryName, baseUri, logger, isInsecureRegistry, mode);
         Manifest = new DefaultManifestOperations(_baseUri, registryName, _client, _logger);
         Blob = new DefaultBlobOperations(_baseUri, registryName, _client, _logger);
     }
@@ -35,11 +35,11 @@ internal DefaultRegistryAPI(string registryName, Uri baseUri, bool isInsecureReg
 
     public IManifestOperations Manifest { get; }
 
-    private static HttpClient CreateClient(string registryName, Uri baseUri, bool isInsecureRegistry, ILogger logger)
+    private static HttpClient CreateClient(string registryName, Uri baseUri, ILogger logger, bool isInsecureRegistry, RegistryMode mode)
     {
         HttpMessageHandler innerHandler = CreateHttpHandler(baseUri, isInsecureRegistry, logger);
 
-        HttpMessageHandler clientHandler = new AuthHandshakeMessageHandler(registryName, innerHandler, logger);
+        HttpMessageHandler clientHandler = new AuthHandshakeMessageHandler(registryName, innerHandler, logger, mode);
 
         if (baseUri.IsAmazonECRRegistry())
         {
diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
index 387a21008f11..253ea2a2dc3a 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
@@ -53,6 +53,13 @@ public RidGraphManifestPicker(string runtimeIdentifierGraphPath)
 
 }
 
+internal enum RegistryMode
+{
+    Push,
+    Pull,
+    PullFromOutput
+}
+
 internal sealed class Registry
 {
     private const string DockerHubRegistry1 = "registry-1.docker.io";
@@ -70,11 +77,24 @@ internal sealed class Registry
     /// </summary>
     public string RegistryName { get; }
 
-    internal Registry(string registryName, ILogger logger, IRegistryAPI? registryAPI = null, RegistrySettings? settings = null) :
+    internal Registry(string registryName, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null) :
         this(new Uri($"https://{registryName}"), logger, registryAPI, settings)
     { }
 
-    internal Registry(Uri baseUri, ILogger logger, IRegistryAPI? registryAPI = null, RegistrySettings? settings = null)
+    internal Registry(string registryName, ILogger logger, RegistryMode mode, RegistrySettings? settings = null) : 
+        this(new Uri($"https://{registryName}"), logger, new RegistryApiFactory(mode), settings)
+    { }
+
+
+    internal Registry(Uri baseUri, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null) :
+        this(baseUri, logger, new RegistryApiFactory(registryAPI), settings)
+    { }
+
+    internal Registry(Uri baseUri, ILogger logger, RegistryMode mode, RegistrySettings? settings = null) :
+        this(baseUri, logger, new RegistryApiFactory(mode), settings)
+    { }
+
+    private Registry(Uri baseUri, ILogger logger, RegistryApiFactory factory, RegistrySettings? settings = null)
     {
         RegistryName = DeriveRegistryName(baseUri);
 
@@ -87,7 +107,7 @@ internal Registry(Uri baseUri, ILogger logger, IRegistryAPI? registryAPI = null,
 
         _logger = logger;
         _settings = settings ?? new RegistrySettings(RegistryName);
-        _registryAPI = registryAPI ?? new DefaultRegistryAPI(RegistryName, BaseUri, _settings.IsInsecure, logger);
+        _registryAPI = factory.Create(RegistryName, BaseUri, logger, _settings.IsInsecure);
     }
 
     private static string DeriveRegistryName(Uri baseUri)
@@ -95,7 +115,7 @@ private static string DeriveRegistryName(Uri baseUri)
         var port = baseUri.Port == -1 ? string.Empty : $":{baseUri.Port}";
         if (baseUri.OriginalString.EndsWith(port, ignoreCase: true, culture: null))
         {
-            // the port was part of the original assignment, so it's ok to consider it part of the 'name
+            // the port was part of the original assignment, so it's ok to consider it part of the 'name'
             return baseUri.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped);
         }
         else
@@ -507,4 +527,25 @@ private async Task PushAsync(BuiltImage builtImage, SourceImageReference source,
             _logger.LogInformation(Strings.Registry_ManifestUploaded, RegistryName);
         }
     }
+
+    private readonly ref struct RegistryApiFactory
+    {
+        private readonly IRegistryAPI? _registryApi;
+        private readonly RegistryMode? _mode;
+
+        public RegistryApiFactory(IRegistryAPI registryApi)
+        {
+            _registryApi = registryApi;
+        }
+
+        public RegistryApiFactory(RegistryMode mode)
+        {
+            _mode = mode;
+        }
+
+        public IRegistryAPI Create(string registryName, Uri baseUri, ILogger logger, bool isInsecureRegistry)
+        {
+            return _registryApi ?? new DefaultRegistryAPI(registryName, baseUri, isInsecureRegistry, logger, _mode!.Value);
+        }
+    }
 }
diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs
index 0bdd2eed555f..834bae6529f4 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs
@@ -60,7 +60,8 @@ internal async Task<bool> ExecuteAsync(CancellationToken cancellationToken)
             return !Log.HasLoggedErrors;
         }
 
-        Registry? sourceRegistry = IsLocalPull ? null : new Registry(BaseRegistry, logger);
+        RegistryMode sourceRegistryMode = BaseRegistry.Equals(OutputRegistry, StringComparison.InvariantCultureIgnoreCase) ? RegistryMode.PullFromOutput : RegistryMode.Pull;
+        Registry? sourceRegistry = IsLocalPull ? null : new Registry(BaseRegistry, logger, sourceRegistryMode);
         SourceImageReference sourceImageReference = new(sourceRegistry, BaseImageName, BaseImageTag);
 
         DestinationImageReference destinationImageReference = DestinationImageReference.CreateFromSettings(
diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs
index e9fe7898dff5..cf25db4b0309 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/CreateNewImageTests.cs
@@ -225,7 +225,7 @@ public async System.Threading.Tasks.Task CreateNewImage_RootlessBaseImage()
         var logger = loggerFactory.CreateLogger(nameof(CreateNewImage_RootlessBaseImage));
 
         // Build a rootless base runtime image.
-        Registry registry = new Registry(DockerRegistryManager.LocalRegistry, logger);
+        Registry registry = new(DockerRegistryManager.LocalRegistry, logger, RegistryMode.Push);
 
         ImageBuilder imageBuilder = await registry.GetImageManifestAsync(
             DockerRegistryManager.RuntimeBaseImage,
diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs
index 22447bc5df00..253c44653a85 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryManager.cs
@@ -43,8 +43,8 @@ public static async Task StartAndPopulateDockerRegistry(ITestOutputHelper testOu
         int spawnRegistryDelay = 1000; //ms
         StringBuilder failureReasons = new();
 
-        var pullRegistry = new Registry(BaseImageSource, logger);
-        var pushRegistry = new Registry(LocalRegistry, logger);
+        var pullRegistry = new Registry(BaseImageSource, logger, RegistryMode.Pull);
+        var pushRegistry = new Registry(LocalRegistry, logger, RegistryMode.Push);
 
         for (int spawnRegistryAttempt = 1; spawnRegistryAttempt <= spawnRegistryMaxRetry; spawnRegistryAttempt++)
         {
diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs
index 3529e5edec41..ba8840dc01c4 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/DockerRegistryTests.cs
@@ -22,7 +22,7 @@ public async Task GetFromRegistry()
     {
         var loggerFactory = new TestLoggerFactory(_testOutput);
         var logger = loggerFactory.CreateLogger(nameof(GetFromRegistry));
-        Registry registry = new Registry(DockerRegistryManager.LocalRegistry, logger);
+        Registry registry = new(DockerRegistryManager.LocalRegistry, logger, RegistryMode.Push);
         var ridgraphfile = ToolsetUtils.GetRuntimeGraphFilePath();
 
         // Don't need rid graph for local registry image pulls - since we're only pushing single image manifests (not manifest lists)
@@ -74,9 +74,9 @@ public async Task WriteToPrivateBasicRegistry()
             // login to that registry
             ContainerCli.LoginCommand(_testOutput, "--username", "testuser", "--password", "testpassword", registryName).Execute().Should().Pass();
             // push an image to that registry using username/password
-            Registry localAuthed = new(new Uri($"https://{registryName}"), logger, settings: new(registryName) { ParallelUploadEnabled = false, ForceChunkedUpload = true });
+            Registry localAuthed = new(new Uri($"https://{registryName}"), logger, RegistryMode.Push, settings: new() { ParallelUploadEnabled = false, ForceChunkedUpload = true });
             var ridgraphfile = ToolsetUtils.GetRuntimeGraphFilePath();
-            Registry mcr = new Registry(DockerRegistryManager.BaseImageSource, logger);
+            Registry mcr = new(DockerRegistryManager.BaseImageSource, logger, RegistryMode.Pull);
 
             var sourceImage = new SourceImageReference(mcr, DockerRegistryManager.RuntimeBaseImage, DockerRegistryManager.Net6ImageTag);
             var destinationImage = new DestinationImageReference(localAuthed, DockerRegistryManager.RuntimeBaseImage, new[] { DockerRegistryManager.Net6ImageTag });
diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
index 9dc7db0b6586..d78b88cc211b 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
@@ -46,7 +46,7 @@ public async Task ApiEndToEndWithRegistryPushAndPull()
 
         // Build the image
 
-        Registry registry = new Registry(DockerRegistryManager.LocalRegistry, logger);
+        Registry registry = new(DockerRegistryManager.LocalRegistry, logger, RegistryMode.Push);
 
         ImageBuilder imageBuilder = await registry.GetImageManifestAsync(
             DockerRegistryManager.RuntimeBaseImage,
@@ -93,7 +93,7 @@ public async Task ApiEndToEndWithLocalLoad()
 
         // Build the image
 
-        Registry registry = new Registry(DockerRegistryManager.LocalRegistry, logger);
+        Registry registry = new(DockerRegistryManager.LocalRegistry, logger, RegistryMode.Push);
 
         ImageBuilder imageBuilder = await registry.GetImageManifestAsync(
             DockerRegistryManager.RuntimeBaseImage,
@@ -134,7 +134,7 @@ public async Task ApiEndToEndWithArchiveWritingAndLoad()
 
         // Build the image
 
-        Registry registry = new Registry(DockerRegistryManager.LocalRegistry, logger);
+        Registry registry = new(DockerRegistryManager.LocalRegistry, logger, RegistryMode.Push);
 
         ImageBuilder imageBuilder = await registry.GetImageManifestAsync(
             DockerRegistryManager.RuntimeBaseImage,
@@ -555,7 +555,7 @@ public async Task CanPackageForAllSupportedContainerRIDs(string dockerPlatform,
         string publishDirectory = BuildLocalApp(tfm: ToolsetInfo.CurrentTargetFramework, rid: rid);
 
         // Build the image
-        Registry registry = new(DockerRegistryManager.BaseImageSource, logger);
+        Registry registry = new(DockerRegistryManager.BaseImageSource, logger, RegistryMode.Push);
         var isWin = rid.StartsWith("win");
         ImageBuilder? imageBuilder = await registry.GetImageManifestAsync(
             DockerRegistryManager.RuntimeBaseImage,
diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/RegistryTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/RegistryTests.cs
index 0f58b21e98ec..814892354356 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/RegistryTests.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/RegistryTests.cs
@@ -39,7 +39,7 @@ public async Task CanReadManifestFromRegistry(string fullyQualifiedContainerName
         containerTag ??= "latest";
 
         ILogger logger = _loggerFactory.CreateLogger(nameof(CanReadManifestFromRegistry));
-        Registry registry = new Registry(containerRegistry, logger);
+        Registry registry = new(containerRegistry, logger, RegistryMode.Pull);
 
         var ridgraphfile = ToolsetUtils.GetRuntimeGraphFilePath();
 
diff --git a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs
new file mode 100644
index 000000000000..9e17b99e56bc
--- /dev/null
+++ b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/AuthHandshakeMessageHandlerTests.cs
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.NET.Build.Containers.UnitTests
+{
+    public class AuthHandshakeMessageHandlerTests
+    {
+        [Theory]
+        [InlineData("SDK_CONTAINER_REGISTRY_UNAME", "SDK_CONTAINER_REGISTRY_PWORD", (int)RegistryMode.Push)]
+        [InlineData("DOTNET_CONTAINER_PUSH_REGISTRY_UNAME", "DOTNET_CONTAINER_PUSH_REGISTRY_PWORD", (int)RegistryMode.Push)]
+        [InlineData("DOTNET_CONTAINER_PULL_REGISTRY_UNAME", "DOTNET_CONTAINER_PULL_REGISTRY_PWORD", (int)RegistryMode.Pull)]
+        [InlineData("DOTNET_CONTAINER_PULL_REGISTRY_UNAME", "DOTNET_CONTAINER_PULL_REGISTRY_PWORD", (int)RegistryMode.PullFromOutput)]
+        [InlineData("SDK_CONTAINER_REGISTRY_UNAME", "SDK_CONTAINER_REGISTRY_PWORD", (int)RegistryMode.PullFromOutput)]
+        public void GetDockerCredentialsFromEnvironment_ReturnsCorrectValues(string unameVarName, string pwordVarName, int mode)
+        {
+            string? originalUnameValue = Environment.GetEnvironmentVariable(unameVarName);
+            string? originalPwordValue = Environment.GetEnvironmentVariable(pwordVarName);
+
+            Environment.SetEnvironmentVariable(unameVarName, "uname");
+            Environment.SetEnvironmentVariable(pwordVarName, "pword");
+
+            if (AuthHandshakeMessageHandler.GetDockerCredentialsFromEnvironment((RegistryMode)mode) is (string credU, string credP))
+            {
+                Assert.Equal("uname", credU);
+                Assert.Equal("pword", credP);
+            }
+            else 
+            {
+                Assert.Fail("Should have parsed credentials from environment");
+            }
+
+
+            // restore env variable values
+            Environment.SetEnvironmentVariable(unameVarName, originalUnameValue);
+            Environment.SetEnvironmentVariable(pwordVarName, originalPwordValue);
+        }
+    }
+}
diff --git a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
index d01aab77d77b..51fad494918f 100644
--- a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
+++ b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
@@ -35,7 +35,7 @@ public void Dispose()
     public void CheckIfGoogleArtifactRegistry(string registryName, bool isECR)
     {
         ILogger logger = _loggerFactory.CreateLogger(nameof(CheckIfGoogleArtifactRegistry));
-        Registry registry = new Registry(registryName, logger);
+        Registry registry = new(registryName, logger, RegistryMode.Push);
         Assert.Equal(isECR, registry.IsGoogleArtifactRegistry);
     }
 
@@ -43,7 +43,7 @@ public void CheckIfGoogleArtifactRegistry(string registryName, bool isECR)
     public void DockerIoAlias()
     {
         ILogger logger = _loggerFactory.CreateLogger(nameof(DockerIoAlias));
-        Registry registry = new Registry("docker.io", logger);
+        Registry registry = new("docker.io", logger, RegistryMode.Push);
         Assert.True(registry.IsDockerHub);
         Assert.Equal("docker.io", registry.RegistryName);
         Assert.Equal("registry-1.docker.io", registry.BaseUri.Host);
@@ -456,7 +456,7 @@ public async Task InsecureRegistry(bool isInsecureRegistry, bool serverIsHttps,
         {
             IsInsecure = isInsecureRegistry
         };
-        Registry registry = new(registryUri, logger, settings: settings);
+        Registry registry = new(registryUri, logger, RegistryMode.Pull, settings: settings);
 
         // Make a request.
         Task getManifest = registry.GetImageManifestAsync(repositoryName: "dotnet/runtime", reference: "latest", runtimeIdentifier: "linux-x64", manifestPicker: null!, cancellationToken: default!);