diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 7d87fc83a8..3b5c141d70 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -9,6 +9,7 @@ import (
 	"os"
 	"strings"
 
+	"github.com/containers/common/pkg/secrets"
 	"github.com/containers/image/v5/types"
 	"github.com/containers/podman/v3/libpod"
 	"github.com/containers/podman/v3/libpod/define"
@@ -135,6 +136,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
 		report        entities.PlayKubeReport
 	)
 
+	// Create the secret manager before hand
+	secretsManager, err := secrets.NewManager(ic.Libpod.GetSecretsStorageDir())
+	if err != nil {
+		return nil, err
+	}
+
 	// check for name collision between pod and container
 	if podName == "" {
 		return nil, errors.Errorf("pod does not have a name")
@@ -261,16 +268,17 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
 		}
 
 		specgenOpts := kube.CtrSpecGenOptions{
-			Container:     container,
-			Image:         newImage,
-			Volumes:       volumes,
-			PodID:         pod.ID(),
-			PodName:       podName,
-			PodInfraID:    podInfraID,
-			ConfigMaps:    configMaps,
-			SeccompPaths:  seccompPaths,
-			RestartPolicy: ctrRestartPolicy,
-			NetNSIsHost:   p.NetNS.IsHost(),
+			Container:      container,
+			Image:          newImage,
+			Volumes:        volumes,
+			PodID:          pod.ID(),
+			PodName:        podName,
+			PodInfraID:     podInfraID,
+			ConfigMaps:     configMaps,
+			SeccompPaths:   seccompPaths,
+			RestartPolicy:  ctrRestartPolicy,
+			NetNSIsHost:    p.NetNS.IsHost(),
+			SecretsManager: secretsManager,
 		}
 		specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
 		if err != nil {
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index f31f5e711e..31ed3fd7c2 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -2,11 +2,13 @@ package kube
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"net"
 	"strings"
 
 	"github.com/containers/common/pkg/parse"
+	"github.com/containers/common/pkg/secrets"
 	"github.com/containers/podman/v3/libpod/image"
 	ann "github.com/containers/podman/v3/pkg/annotations"
 	"github.com/containers/podman/v3/pkg/specgen"
@@ -94,6 +96,8 @@ type CtrSpecGenOptions struct {
 	RestartPolicy string
 	// NetNSIsHost tells the container to use the host netns
 	NetNSIsHost bool
+	// SecretManager to access the secrets
+	SecretsManager *secrets.SecretsManager
 }
 
 func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
@@ -331,7 +335,21 @@ func quantityToInt64(quantity *resource.Quantity) (int64, error) {
 	return 0, errors.Errorf("Quantity cannot be represented as int64: %v", quantity)
 }
 
-// envVarsFrom returns all key-value pairs as env vars from a configMap that matches the envFrom setting of a container
+// read a k8s secret in JSON format from the secret manager
+func k8sSecretFromSecretManager(name string, secretsManager *secrets.SecretsManager) (map[string][]byte, error) {
+	_, jsonSecret, err := secretsManager.LookupSecretData(name)
+	if err != nil {
+		return nil, err
+	}
+
+	var secrets map[string][]byte
+	if err := json.Unmarshal(jsonSecret, &secrets); err != nil {
+		return nil, errors.Errorf("Secret %v is not valid JSON: %v", name, err)
+	}
+	return secrets, nil
+}
+
+// envVarsFrom returns all key-value pairs as env vars from a configMap or secret that matches the envFrom setting of a container
 func envVarsFrom(envFrom v1.EnvFromSource, opts *CtrSpecGenOptions) (map[string]string, error) {
 	envs := map[string]string{}
 
@@ -352,11 +370,23 @@ func envVarsFrom(envFrom v1.EnvFromSource, opts *CtrSpecGenOptions) (map[string]
 		}
 	}
 
+	if envFrom.SecretRef != nil {
+		secRef := envFrom.SecretRef
+		secret, err := k8sSecretFromSecretManager(secRef.Name, opts.SecretsManager)
+		if err == nil {
+			for k, v := range secret {
+				envs[k] = string(v)
+			}
+		} else if secRef.Optional == nil || !*secRef.Optional {
+			return nil, err
+		}
+	}
+
 	return envs, nil
 }
 
 // envVarValue returns the environment variable value configured within the container's env setting.
-// It gets the value from a configMap if specified, otherwise returns env.Value
+// It gets the value from a configMap or secret if specified, otherwise returns env.Value
 func envVarValue(env v1.EnvVar, opts *CtrSpecGenOptions) (string, error) {
 	if env.ValueFrom != nil {
 		if env.ValueFrom.ConfigMapKeyRef != nil {
@@ -377,6 +407,21 @@ func envVarValue(env v1.EnvVar, opts *CtrSpecGenOptions) (string, error) {
 			}
 			return "", nil
 		}
+
+		if env.ValueFrom.SecretKeyRef != nil {
+			secKeyRef := env.ValueFrom.SecretKeyRef
+			secret, err := k8sSecretFromSecretManager(secKeyRef.Name, opts.SecretsManager)
+			if err == nil {
+				if val, ok := secret[secKeyRef.Key]; ok {
+					return string(val), nil
+				}
+				err = errors.Errorf("Secret %v has not %v key", secKeyRef.Name, secKeyRef.Key)
+			}
+			if secKeyRef.Optional == nil || !*secKeyRef.Optional {
+				return "", errors.Errorf("Cannot set env %v: %v", env.Name, err)
+			}
+			return "", nil
+		}
 	}
 
 	return env.Value, nil
diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go
index c38b3e40ba..f714826f0c 100644
--- a/pkg/specgen/generate/kube/play_test.go
+++ b/pkg/specgen/generate/kube/play_test.go
@@ -1,14 +1,43 @@
 package kube
 
 import (
+	"encoding/json"
+	"io/ioutil"
+	"os"
 	"testing"
 
+	"github.com/containers/common/pkg/secrets"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+func createSecrets(t *testing.T, d string) *secrets.SecretsManager {
+	secretsManager, err := secrets.NewManager(d)
+	assert.NoError(t, err)
+
+	driver := "file"
+	driverOpts := map[string]string{
+		"path": d,
+	}
+
+	for _, s := range k8sSecrets {
+		data, err := json.Marshal(s.Data)
+		assert.NoError(t, err)
+
+		_, err = secretsManager.Store(s.ObjectMeta.Name, data, driver, driverOpts)
+		assert.NoError(t, err)
+	}
+
+	return secretsManager
+}
+
 func TestEnvVarsFrom(t *testing.T) {
+	d, err := ioutil.TempDir("", "secrets")
+	assert.NoError(t, err)
+	defer os.RemoveAll(d)
+	secretsManager := createSecrets(t, d)
+
 	tests := []struct {
 		name     string
 		envFrom  v1.EnvFromSource
@@ -95,6 +124,54 @@ func TestEnvVarsFrom(t *testing.T) {
 			true,
 			map[string]string{},
 		},
+		{
+			"SecretExists",
+			v1.EnvFromSource{
+				SecretRef: &v1.SecretEnvSource{
+					LocalObjectReference: v1.LocalObjectReference{
+						Name: "foo",
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			true,
+			map[string]string{
+				"myvar": "foo",
+			},
+		},
+		{
+			"SecretDoesNotExist",
+			v1.EnvFromSource{
+				SecretRef: &v1.SecretEnvSource{
+					LocalObjectReference: v1.LocalObjectReference{
+						Name: "doesnotexist",
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			false,
+			nil,
+		},
+		{
+			"OptionalSecretDoesNotExist",
+			v1.EnvFromSource{
+				SecretRef: &v1.SecretEnvSource{
+					LocalObjectReference: v1.LocalObjectReference{
+						Name: "doesnotexist",
+					},
+					Optional: &optional,
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			true,
+			map[string]string{},
+		},
 	}
 
 	for _, test := range tests {
@@ -108,6 +185,11 @@ func TestEnvVarsFrom(t *testing.T) {
 }
 
 func TestEnvVarValue(t *testing.T) {
+	d, err := ioutil.TempDir("", "secrets")
+	assert.NoError(t, err)
+	defer os.RemoveAll(d)
+	secretsManager := createSecrets(t, d)
+
 	tests := []struct {
 		name     string
 		envVar   v1.EnvVar
@@ -251,6 +333,103 @@ func TestEnvVarValue(t *testing.T) {
 			true,
 			"",
 		},
+		{
+			"SecretExists",
+			v1.EnvVar{
+				Name: "FOO",
+				ValueFrom: &v1.EnvVarSource{
+					SecretKeyRef: &v1.SecretKeySelector{
+						LocalObjectReference: v1.LocalObjectReference{
+							Name: "foo",
+						},
+						Key: "myvar",
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			true,
+			"foo",
+		},
+		{
+			"ContainerKeyDoesNotExistInSecret",
+			v1.EnvVar{
+				Name: "FOO",
+				ValueFrom: &v1.EnvVarSource{
+					SecretKeyRef: &v1.SecretKeySelector{
+						LocalObjectReference: v1.LocalObjectReference{
+							Name: "foo",
+						},
+						Key: "doesnotexist",
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			false,
+			"",
+		},
+		{
+			"OptionalContainerKeyDoesNotExistInSecret",
+			v1.EnvVar{
+				Name: "FOO",
+				ValueFrom: &v1.EnvVarSource{
+					SecretKeyRef: &v1.SecretKeySelector{
+						LocalObjectReference: v1.LocalObjectReference{
+							Name: "foo",
+						},
+						Key:      "doesnotexist",
+						Optional: &optional,
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			true,
+			"",
+		},
+		{
+			"SecretDoesNotExist",
+			v1.EnvVar{
+				Name: "FOO",
+				ValueFrom: &v1.EnvVarSource{
+					SecretKeyRef: &v1.SecretKeySelector{
+						LocalObjectReference: v1.LocalObjectReference{
+							Name: "doesnotexist",
+						},
+						Key: "myvar",
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			false,
+			"",
+		},
+		{
+			"OptionalSecretDoesNotExist",
+			v1.EnvVar{
+				Name: "FOO",
+				ValueFrom: &v1.EnvVarSource{
+					SecretKeyRef: &v1.SecretKeySelector{
+						LocalObjectReference: v1.LocalObjectReference{
+							Name: "doesnotexist",
+						},
+						Key:      "myvar",
+						Optional: &optional,
+					},
+				},
+			},
+			CtrSpecGenOptions{
+				SecretsManager: secretsManager,
+			},
+			true,
+			"",
+		},
 	}
 
 	for _, test := range tests {
@@ -289,3 +468,28 @@ var configMapList = []v1.ConfigMap{
 }
 
 var optional = true
+
+var k8sSecrets = []v1.Secret{
+	{
+		TypeMeta: v12.TypeMeta{
+			Kind: "Secret",
+		},
+		ObjectMeta: v12.ObjectMeta{
+			Name: "bar",
+		},
+		Data: map[string][]byte{
+			"myvar": []byte("bar"),
+		},
+	},
+	{
+		TypeMeta: v12.TypeMeta{
+			Kind: "Secret",
+		},
+		ObjectMeta: v12.ObjectMeta{
+			Name: "foo",
+		},
+		Data: map[string][]byte{
+			"myvar": []byte("foo"),
+		},
+	},
+}
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 943887e32c..b22f63f34e 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -142,7 +142,15 @@ spec:
           name: {{ .RefName }}
           key: {{ .RefKey }}
           optional: {{ .Optional }}
-    {{ else }}
+    {{ end }}
+    {{ if (eq .ValueFrom "secret") }}
+      valueFrom:
+        secretKeyRef:
+          name: {{ .RefName }}
+          key: {{ .RefKey }}
+          optional: {{ .Optional }}
+    {{ end }}
+    {{ if (eq .ValueFrom "") }}
       value: {{ .Value }}
     {{ end }}
     {{ end }}
@@ -154,6 +162,11 @@ spec:
         name: {{ .Name }}
         optional: {{ .Optional }}
     {{ end }}
+    {{ if (eq .From "secret") }}
+    - secretRef:
+        name: {{ .Name }}
+        optional: {{ .Optional }}
+    {{ end }}
     {{ end }}
     {{ end }}
     image: {{ .Image }}
@@ -342,6 +355,8 @@ var (
 	seccompPwdEPERM       = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
 	// CPU Period in ms
 	defaultCPUPeriod = 100
+	// Default secret in JSON. Note that the values ("foo" and "bar") are base64 encoded.
+	defaultSecret = []byte(`{"FOO":"Zm9v","BAR":"YmFy"}`)
 )
 
 func writeYaml(content string, fileName string) error {
@@ -409,6 +424,16 @@ func generateMultiDocKubeYaml(kubeObjects []string, pathname string) error {
 	return writeYaml(multiKube, pathname)
 }
 
+func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) {
+	secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+	err := ioutil.WriteFile(secretFilePath, value, 0755)
+	Expect(err).To(BeNil())
+
+	secret := podmanTest.Podman([]string{"secret", "create", name, secretFilePath})
+	secret.WaitWithDefaultTimeout()
+	Expect(secret.ExitCode()).To(Equal(0))
+}
+
 // ConfigMap describes the options a kube yaml can be configured at configmap level
 type ConfigMap struct {
 	Name string
@@ -1186,6 +1211,111 @@ var _ = Describe("Podman play kube", func() {
 		Expect(kube.ExitCode()).To(Equal(0))
 	})
 
+	It("podman play kube test env value from secret", func() {
+		createSecret(podmanTest, "foo", defaultSecret)
+		pod := getPod(withCtr(getCtr(withEnv("FOO", "", "secret", "foo", "FOO", false))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Equal(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect.ExitCode()).To(Equal(0))
+		Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=foo`))
+	})
+
+	It("podman play kube test required env value from missing secret", func() {
+		pod := getPod(withCtr(getCtr(withEnv("FOO", "", "secret", "foo", "FOO", false))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Not(Equal(0)))
+	})
+
+	It("podman play kube test required env value from secret with missing key", func() {
+		createSecret(podmanTest, "foo", defaultSecret)
+		pod := getPod(withCtr(getCtr(withEnv("FOO", "", "secret", "foo", "MISSING", false))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Not(Equal(0)))
+	})
+
+	It("podman play kube test optional env value from missing secret", func() {
+		pod := getPod(withCtr(getCtr(withEnv("FOO", "", "secret", "foo", "FOO", true))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Equal(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect.ExitCode()).To(Equal(0))
+		Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+	})
+
+	It("podman play kube test optional env value from secret with missing key", func() {
+		createSecret(podmanTest, "foo", defaultSecret)
+		pod := getPod(withCtr(getCtr(withEnv("FOO", "", "secret", "foo", "MISSING", true))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Equal(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ range .Config.Env }}[{{ . }}]{{end}}'"})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect.ExitCode()).To(Equal(0))
+		Expect(inspect.OutputToString()).To(ContainSubstring(`[FOO=]`))
+	})
+
+	It("podman play kube test get all key-value pairs from secret as envs", func() {
+		createSecret(podmanTest, "foo", defaultSecret)
+		pod := getPod(withCtr(getCtr(withEnvFrom("foo", "secret", false))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Equal(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Env }}'"})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect.ExitCode()).To(Equal(0))
+		Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=foo`))
+		Expect(inspect.OutputToString()).To(ContainSubstring(`BAR=bar`))
+	})
+
+	It("podman play kube test get all key-value pairs from required secret as envs", func() {
+		pod := getPod(withCtr(getCtr(withEnvFrom("missing_secret", "secret", false))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Not(Equal(0)))
+	})
+
+	It("podman play kube test get all key-value pairs from optional secret as envs", func() {
+		pod := getPod(withCtr(getCtr(withEnvFrom("missing_secret", "secret", true))))
+		err = generateKubeYaml("pod", pod, kubeYaml)
+		Expect(err).To(BeNil())
+
+		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube.ExitCode()).To(Equal(0))
+	})
+
 	It("podman play kube test hostname", func() {
 		pod := getPod()
 		err := generateKubeYaml("pod", pod, kubeYaml)