Repository: kubernetes/minikube
Pull request #16761 (2023-06-23 00:11:50)

Add ability to start & stop ssh-agent process
This PR adds an `sshagent` package that allows starting and stoping an ssh-agent process. Once a process is started it's auth socket and agent pid are added to the cluster config. When running `docker-env`, if the auth socket and agent pid are populated in the cluster config they'll be included in the command output. On cluster delete the process is killed.

When creating this output I added `sshagent.Start()` to the beginning of `cmd/minikube/cmd/docker-env.go`

`sshagent.Start()` will be implemented in https://github.com/kubernetes/minikube/pull/15452

```
$ pgrep ssh-agent
1219

$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://127.0.0.1:59146"
export DOCKER_CERT_PATH="/Users/powellsteven/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"
export SSH_AUTH_SOCK="/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227"
export SSH_AGENT_PID="29228"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)

$ pgrep ssh-agent
1219
29228

$ minikube delete
🔥  Deleting "minikube" in docker ...
🔥  Deleting container "minikube" ...
🔥  Removing /Users/powellsteven/.minikube/machines/minikube ...
💀  Removed all traces of the "minikube" cluster.

$ pgrep ssh-agent
1219
```

**Before:**
```
$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://127.0.0.1:51030"
export DOCKER_CERT_PATH="/Users/powellsteven/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
```

**After w/ agent stopped:**
```
$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://127.0.0.1:51030"
export DOCKER_CERT_PATH="/Users/powellsteven/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
```

**After w/ agent started:**
```
$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://127.0.0.1:51030"
export DOCKER_CERT_PATH="/Users/powellsteven/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"
export SSH_AUTH_SOCK="/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-rrVWjcEBi4pO/agent.37343"
export SSH_AGENT_PID="37344"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
```


Patch:
diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go
index 74ecf22bf..eae8e28c0 100644
--- a/cmd/minikube/cmd/delete.go
+++ b/cmd/minikube/cmd/delete.go
@@ -51,6 +51,7 @@ import (
 	"k8s.io/minikube/pkg/minikube/out"
 	"k8s.io/minikube/pkg/minikube/out/register"
 	"k8s.io/minikube/pkg/minikube/reason"
+	"k8s.io/minikube/pkg/minikube/sshagent"
 	"k8s.io/minikube/pkg/minikube/style"
 )
 
@@ -93,6 +94,9 @@ var hostAndDirsDeleter = func(api libmachine.API, cc *config.ClusterConfig, prof
 	if err := killMountProcess(); err != nil {
 		out.FailureT("Failed to kill mount process: {{.error}}", out.V{"error": err})
 	}
+	if err := sshagent.Stop(profileName); err != nil {
+		out.FailureT("Failed to stop ssh-agent process: {{.error}}", out.V{"error": err})
+	}
 
 	deleteHosts(api, cc)
 
diff --git a/cmd/minikube/cmd/docker-env.go b/cmd/minikube/cmd/docker-env.go
index 6e6ab192d..450fc9952 100644
--- a/cmd/minikube/cmd/docker-env.go
+++ b/cmd/minikube/cmd/docker-env.go
@@ -71,6 +71,12 @@ var dockerEnvTCPTmpl = fmt.Sprintf(
 		"{{ if .NoProxyVar }}"+
 		"{{ .Prefix }}{{ .NoProxyVar }}{{ .Delimiter }}{{ .NoProxyValue }}{{ .Suffix }}"+
 		"{{ end }}"+
+		"{{ if .SSHAuthSock }}"+
+		"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAuthSock }}{{ .Suffix }}"+
+		"{{ end }}"+
+		"{{ if .SSHAgentPID }}"+
+		"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAgentPID }}{{ .Suffix }}"+
+		"{{ end }}"+
 		"{{ .UsageHint }}",
 	constants.DockerTLSVerifyEnv,
 	constants.DockerHostEnv,
@@ -78,13 +84,23 @@ var dockerEnvTCPTmpl = fmt.Sprintf(
 	constants.ExistingDockerTLSVerifyEnv,
 	constants.ExistingDockerHostEnv,
 	constants.ExistingDockerCertPathEnv,
-	constants.MinikubeActiveDockerdEnv)
+	constants.MinikubeActiveDockerdEnv,
+	constants.SSHAuthSock,
+	constants.SSHAgentPID)
 var dockerEnvSSHTmpl = fmt.Sprintf(
 	"{{ .Prefix }}%s{{ .Delimiter }}{{ .DockerHost }}{{ .Suffix }}"+
 		"{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubeDockerdProfile }}{{ .Suffix }}"+
+		"{{ if .SSHAuthSock }}"+
+		"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAuthSock }}{{ .Suffix }}"+
+		"{{ end }}"+
+		"{{ if .SSHAgentPID }}"+
+		"{{ .Prefix }}%s{{ .Delimiter }}{{ .SSHAgentPID }}{{ .Suffix }}"+
+		"{{ end }}"+
 		"{{ .UsageHint }}",
 	constants.DockerHostEnv,
-	constants.MinikubeActiveDockerdEnv)
+	constants.MinikubeActiveDockerdEnv,
+	constants.SSHAuthSock,
+	constants.SSHAgentPID)
 
 // DockerShellConfig represents the shell config for Docker
 type DockerShellConfig struct {
@@ -99,6 +115,9 @@ type DockerShellConfig struct {
 	ExistingDockerCertPath  string
 	ExistingDockerHost      string
 	ExistingDockerTLSVerify string
+
+	SSHAuthSock string
+	SSHAgentPID string
 }
 
 var (
@@ -142,6 +161,9 @@ func dockerShellCfgSet(ec DockerEnvConfig, envMap map[string]string) *DockerShel
 
 	s.MinikubeDockerdProfile = envMap[constants.MinikubeActiveDockerdEnv]
 
+	s.SSHAuthSock = envMap[constants.SSHAuthSock]
+	s.SSHAgentPID = envMap[constants.SSHAgentPID]
+
 	if ec.noProxy {
 		noProxyVar, noProxyValue := defaultNoProxyGetter.GetNoProxyVar()
 
@@ -316,18 +338,20 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
 
 		hostIP := co.CP.IP.String()
 		ec := DockerEnvConfig{
-			EnvConfig: sh,
-			profile:   cname,
-			driver:    driverName,
-			ssh:       sshHost,
-			hostIP:    hostIP,
-			port:      port,
-			certsDir:  localpath.MakeMiniPath("certs"),
-			noProxy:   noProxy,
-			username:  d.GetSSHUsername(),
-			hostname:  hostname,
-			sshport:   sshport,
-			keypath:   d.GetSSHKeyPath(),
+			EnvConfig:   sh,
+			profile:     cname,
+			driver:      driverName,
+			ssh:         sshHost,
+			hostIP:      hostIP,
+			port:        port,
+			certsDir:    localpath.MakeMiniPath("certs"),
+			noProxy:     noProxy,
+			username:    d.GetSSHUsername(),
+			hostname:    hostname,
+			sshport:     sshport,
+			keypath:     d.GetSSHKeyPath(),
+			sshAuthSock: co.Config.SSHAuthSock,
+			sshAgentPID: co.Config.SSHAgentPID,
 		}
 
 		dockerPath, err := exec.LookPath("docker")
@@ -371,17 +395,19 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
 // DockerEnvConfig encapsulates all external inputs into shell generation for Docker
 type DockerEnvConfig struct {
 	shell.EnvConfig
-	profile  string
-	driver   string
-	ssh      bool
-	hostIP   string
-	port     int
-	certsDir string
-	noProxy  bool
-	username string
-	hostname string
-	sshport  int
-	keypath  string
+	profile     string
+	driver      string
+	ssh         bool
+	hostIP      string
+	port        int
+	certsDir    string
+	noProxy     bool
+	username    string
+	hostname    string
+	sshport     int
+	keypath     string
+	sshAuthSock string
+	sshAgentPID int
 }
 
 // dockerSetScript writes out a shell-compatible 'docker-env' script
@@ -497,11 +523,18 @@ func sshURL(username string, hostname string, port int) string {
 
 // dockerEnvVars gets the necessary docker env variables to allow the use of minikube's docker daemon
 func dockerEnvVars(ec DockerEnvConfig) map[string]string {
+	agentPID := strconv.Itoa(ec.sshAgentPID)
+	// set agentPID to nil value if not set
+	if agentPID == "0" {
+		agentPID = ""
+	}
 	envTCP := map[string]string{
 		constants.DockerTLSVerifyEnv:       "1",
 		constants.DockerHostEnv:            dockerURL(ec.hostIP, ec.port),
 		constants.DockerCertPathEnv:        ec.certsDir,
 		constants.MinikubeActiveDockerdEnv: ec.profile,
+		constants.SSHAuthSock:              ec.sshAuthSock,
+		constants.SSHAgentPID:              agentPID,
 	}
 	envSSH := map[string]string{
 		constants.DockerHostEnv:            sshURL(ec.username, ec.hostname, ec.sshport),
@@ -532,6 +565,8 @@ func dockerEnvNames(ec DockerEnvConfig) []string {
 		constants.DockerHostEnv,
 		constants.DockerCertPathEnv,
 		constants.MinikubeActiveDockerdEnv,
+		constants.SSHAuthSock,
+		constants.SSHAgentPID,
 	}
 
 	if ec.noProxy {
@@ -550,6 +585,8 @@ func dockerEnvVarsList(ec DockerEnvConfig) []string {
 		fmt.Sprintf("%s=%s", constants.DockerHostEnv, dockerURL(ec.hostIP, ec.port)),
 		fmt.Sprintf("%s=%s", constants.DockerCertPathEnv, ec.certsDir),
 		fmt.Sprintf("%s=%s", constants.MinikubeActiveDockerdEnv, ec.profile),
+		fmt.Sprintf("%s=%s", constants.SSHAuthSock, ec.sshAuthSock),
+		fmt.Sprintf("%s=%d", constants.SSHAgentPID, ec.sshAgentPID),
 	}
 }
 
diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go
index 32481b3b4..93bda0e2b 100644
--- a/pkg/minikube/config/types.go
+++ b/pkg/minikube/config/types.go
@@ -105,6 +105,8 @@ type ClusterConfig struct {
 	SocketVMnetClientPath   string
 	SocketVMnetPath         string
 	StaticIP                string
+	SSHAuthSock             string
+	SSHAgentPID             int
 }
 
 // KubernetesConfig contains the parameters used to configure the VM Kubernetes.
diff --git a/pkg/minikube/constants/constants.go b/pkg/minikube/constants/constants.go
index 5ad6aa611..127e7f0da 100644
--- a/pkg/minikube/constants/constants.go
+++ b/pkg/minikube/constants/constants.go
@@ -92,6 +92,10 @@ const (
 	// MinikubeActiveDockerdEnv holds the docker daemon which user's shell is pointing at
 	// value would be profile or empty if pointing to the user's host daemon.
 	MinikubeActiveDockerdEnv = "MINIKUBE_ACTIVE_DOCKERD"
+	// SSHAuthSock is used for docker-env
+	SSHAuthSock = "SSH_AUTH_SOCK"
+	// SSHAgentPID is used for docker-env
+	SSHAgentPID = "SSH_AGENT_PID"
 	// PodmanVarlinkBridgeEnv is used for podman settings
 	PodmanVarlinkBridgeEnv = "PODMAN_VARLINK_BRIDGE"
 	// PodmanContainerHostEnv is used for podman settings
diff --git a/pkg/minikube/sshagent/sshagent.go b/pkg/minikube/sshagent/sshagent.go
new file mode 100644
index 000000000..dc066907c
--- /dev/null
+++ b/pkg/minikube/sshagent/sshagent.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2023 The Kubernetes Authors All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sshagent
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/mitchellh/go-ps"
+	"k8s.io/klog/v2"
+	"k8s.io/minikube/pkg/minikube/config"
+)
+
+type sshAgent struct {
+	authSock string
+	agentPID int
+}
+
+// Start an ssh-agent process
+func Start(profile string) error {
+	if runtime.GOOS == "windows" {
+		return fmt.Errorf("starting an SSH agent on Windows is not yet supported")
+	}
+	cc, err := config.Load(profile)
+	if err != nil {
+		return fmt.Errorf("failed loading config: %v", err)
+	}
+	running, err := isRunning(cc)
+	if err != nil {
+		return fmt.Errorf("failed checking if SSH agent is running: %v", err)
+	}
+	if running {
+		klog.Info("SSH agent is already running, aborting start")
+		return nil
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+	out, err := exec.CommandContext(ctx, "ssh-agent").CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("failed starting ssh-agent: %s: %v", string(out), err)
+	}
+	parsed, err := parseOutput(string(out))
+	if err != nil {
+		return fmt.Errorf("failed to parse ssh-agent output: %v", err)
+	}
+	cc.SSHAuthSock = parsed.authSock
+	cc.SSHAgentPID = parsed.agentPID
+	if err := config.Write(profile, cc); err != nil {
+		return fmt.Errorf("failed writing config: %v", err)
+	}
+	return nil
+}
+
+func parseOutput(out string) (*sshAgent, error) {
+	sockSubmatches := regexp.MustCompile(`SSH_AUTH_SOCK=(.*?);`).FindStringSubmatch(out)
+	if len(sockSubmatches) < 2 {
+		return nil, fmt.Errorf("SSH_AUTH_SOCK not found in output: %s", out)
+	}
+	pidSubmatches := regexp.MustCompile(`SSH_AGENT_PID=(.*?);`).FindStringSubmatch(out)
+	if len(pidSubmatches) < 2 {
+		return nil, fmt.Errorf("SSH_AGENT_PID not found in output: %s", out)
+	}
+	pid, err := strconv.Atoi(pidSubmatches[1])
+	if err != nil {
+		return nil, fmt.Errorf("failed to convert pid to int: %v", err)
+	}
+	return &sshAgent{sockSubmatches[1], pid}, nil
+}
+
+func isRunning(cc *config.ClusterConfig) (bool, error) {
+	if cc.SSHAgentPID == 0 {
+		return false, nil
+	}
+	entry, err := ps.FindProcess(cc.SSHAgentPID)
+	if err != nil {
+		return false, fmt.Errorf("failed finding process: %v", err)
+	}
+	if entry == nil {
+		return false, nil
+	}
+	return strings.Contains(entry.Executable(), "ssh-agent"), nil
+}
+
+// Stop an ssh-agent process
+func Stop(profile string) error {
+	cc, err := config.Load(profile)
+	if err != nil {
+		return fmt.Errorf("failed loading config: %v", err)
+	}
+	running, err := isRunning(cc)
+	if err != nil {
+		return fmt.Errorf("failed checking if SSH agent is running: %v", err)
+	}
+	if running {
+		if err := killProcess(cc.SSHAgentPID); err != nil {
+			return fmt.Errorf("failed killing SSH agent process: %v", err)
+		}
+	}
+	cc.SSHAuthSock = ""
+	cc.SSHAgentPID = 0
+	if err := config.Write(profile, cc); err != nil {
+		return fmt.Errorf("failed writing config: %v", err)
+	}
+	return nil
+}
+
+func killProcess(pid int) error {
+	proc, err := os.FindProcess(pid)
+	if err != nil {
+		return fmt.Errorf("failed finding process: %v", err)
+	}
+	if err := proc.Kill(); err != nil {
+		return fmt.Errorf("failed killing process: %v", err)
+	}
+	return nil
+}


Test patch:
diff --git a/cmd/minikube/cmd/docker-env_test.go b/cmd/minikube/cmd/docker-env_test.go
index 705437ae3..c980da4eb 100644
--- a/cmd/minikube/cmd/docker-env_test.go
+++ b/cmd/minikube/cmd/docker-env_test.go
@@ -63,6 +63,8 @@ export MINIKUBE_ACTIVE_DOCKERD="dockerdriver"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 `,
 			nil,
 		},
@@ -81,6 +83,8 @@ export MINIKUBE_ACTIVE_DOCKERD="dockerdriver"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 `,
 			nil,
 		},
@@ -101,6 +105,8 @@ export MINIKUBE_ACTIVE_DOCKERD="bash"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 `,
 			nil,
 		},
@@ -121,6 +127,8 @@ export MINIKUBE_ACTIVE_DOCKERD="ipv6"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 `,
 			nil,
 		},
@@ -141,6 +149,8 @@ set -gx MINIKUBE_ACTIVE_DOCKERD "fish";
 set -e DOCKER_HOST;
 set -e DOCKER_CERT_PATH;
 set -e MINIKUBE_ACTIVE_DOCKERD;
+set -e SSH_AUTH_SOCK;
+set -e SSH_AGENT_PID;
 `,
 			nil,
 		},
@@ -161,6 +171,8 @@ $Env:MINIKUBE_ACTIVE_DOCKERD = "powershell"
 Remove-Item Env:\\DOCKER_HOST
 Remove-Item Env:\\DOCKER_CERT_PATH
 Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD
+Remove-Item Env:\\SSH_AUTH_SOCK
+Remove-Item Env:\\SSH_AGENT_PID
 `,
 			nil,
 		},
@@ -181,6 +193,8 @@ REM @FOR /f "tokens=*" %i IN ('minikube -p cmd docker-env --shell cmd') DO @%i
 SET DOCKER_HOST=
 SET DOCKER_CERT_PATH=
 SET MINIKUBE_ACTIVE_DOCKERD=
+SET SSH_AUTH_SOCK=
+SET SSH_AGENT_PID=
 `,
 			nil,
 		},
@@ -200,6 +214,8 @@ SET MINIKUBE_ACTIVE_DOCKERD=
 (setenv "DOCKER_HOST" nil)
 (setenv "DOCKER_CERT_PATH" nil)
 (setenv "MINIKUBE_ACTIVE_DOCKERD" nil)
+(setenv "SSH_AUTH_SOCK" nil)
+(setenv "SSH_AGENT_PID" nil)
 `,
 			nil,
 		},
@@ -222,6 +238,8 @@ export NO_PROXY="127.0.0.1"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 unset NO_PROXY;
 `,
 			nil,
@@ -245,6 +263,8 @@ export no_proxy="127.0.0.1"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 unset no_proxy;
 `,
 			nil,
@@ -267,6 +287,8 @@ $Env:no_proxy = "192.168.0.1"
 Remove-Item Env:\\DOCKER_HOST
 Remove-Item Env:\\DOCKER_CERT_PATH
 Remove-Item Env:\\MINIKUBE_ACTIVE_DOCKERD
+Remove-Item Env:\\SSH_AUTH_SOCK
+Remove-Item Env:\\SSH_AGENT_PID
 Remove-Item Env:\\no_proxy
 `,
 			nil,
@@ -290,6 +312,8 @@ export NO_PROXY="192.168.0.1,10.0.0.4,127.0.0.1"
 unset DOCKER_HOST;
 unset DOCKER_CERT_PATH;
 unset MINIKUBE_ACTIVE_DOCKERD;
+unset SSH_AUTH_SOCK;
+unset SSH_AGENT_PID;
 unset NO_PROXY;
 `,
 			nil,
@@ -308,23 +332,29 @@ MINIKUBE_ACTIVE_DOCKERD=noneshell
 DOCKER_HOST
 DOCKER_CERT_PATH
 MINIKUBE_ACTIVE_DOCKERD
+SSH_AUTH_SOCK
+SSH_AGENT_PID
 `,
 			nil,
 		},
 		{
 			"none",
 			"text",
-			DockerEnvConfig{profile: "nonetext", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
+			DockerEnvConfig{profile: "nonetext", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
 			nil,
 			`DOCKER_TLS_VERIFY=1
 DOCKER_HOST=tcp://127.0.0.1:32842
 DOCKER_CERT_PATH=/certs
 MINIKUBE_ACTIVE_DOCKERD=nonetext
+SSH_AUTH_SOCK=/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227
+SSH_AGENT_PID=29228
 `,
 			`DOCKER_TLS_VERIFY
 DOCKER_HOST
 DOCKER_CERT_PATH
 MINIKUBE_ACTIVE_DOCKERD
+SSH_AUTH_SOCK
+SSH_AGENT_PID
 `,
 			[]cmp.Option{
 				cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
@@ -338,19 +368,23 @@ MINIKUBE_ACTIVE_DOCKERD
 		{
 			"none",
 			"json",
-			DockerEnvConfig{profile: "nonejson", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
+			DockerEnvConfig{profile: "nonejson", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
 			nil,
 			`{
 				"DOCKER_TLS_VERIFY": "1",
 				"DOCKER_HOST": "tcp://127.0.0.1:32842",
 				"DOCKER_CERT_PATH": "/certs",
-				"MINIKUBE_ACTIVE_DOCKERD": "nonejson"
+				"MINIKUBE_ACTIVE_DOCKERD": "nonejson",
+				"SSH_AUTH_SOCK": "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227",
+				"SSH_AGENT_PID": "29228"
 			}`,
 			`[
 				"DOCKER_TLS_VERIFY",
 				"DOCKER_HOST",
 				"DOCKER_CERT_PATH",
-				"MINIKUBE_ACTIVE_DOCKERD"
+				"MINIKUBE_ACTIVE_DOCKERD",
+				"SSH_AUTH_SOCK",
+				"SSH_AGENT_PID"
 			]`,
 			[]cmp.Option{
 				cmp.FilterValues(func(x, y string) bool {
@@ -367,17 +401,21 @@ MINIKUBE_ACTIVE_DOCKERD
 		{
 			"none",
 			"yaml",
-			DockerEnvConfig{profile: "noneyaml", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs"},
+			DockerEnvConfig{profile: "noneyaml", driver: "docker", hostIP: "127.0.0.1", port: 32842, certsDir: "/certs", sshAuthSock: "/var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227", sshAgentPID: 29228},
 			nil,
 			`DOCKER_TLS_VERIFY: "1"
 DOCKER_HOST: tcp://127.0.0.1:32842
 DOCKER_CERT_PATH: /certs
 MINIKUBE_ACTIVE_DOCKERD: noneyaml
+SSH_AUTH_SOCK: /var/folders/9l/6wpxv6wd1b901m1146r579wc00rqw3/T//ssh-KCQt1sNqrCPI/agent.29227
+SSH_AGENT_PID: "29228"
 `,
 			`- DOCKER_TLS_VERIFY
 - DOCKER_HOST
 - DOCKER_CERT_PATH
 - MINIKUBE_ACTIVE_DOCKERD
+- SSH_AUTH_SOCK
+- SSH_AGENT_PID
 `,
 			[]cmp.Option{
 				cmpopts.AcyclicTransformer("ParseYAML", func(in string) (out interface{}) {