Kubernetes Native Secrets
Flyte allows you to leverage native Kubernetes Secrets as a source for task secrets. This is particularly useful when you already have secrets managed within your Kubernetes cluster and want to expose them to your Flyte tasks without using external secret managers like AWS Secrets Manager or HashiCorp Vault.
When a task requests a secret, the Flyte Pod Webhook uses the K8sSecretInjector (defined in flyteplugins/go/tasks/pluginmachinery/secret/k8s_secrets.go) to mutate the task's Pod specification. This mutation either injects environment variables that reference the Kubernetes Secret or mounts the secret as a file.
Secret Injection Strategies
Flyte supports two primary strategies for injecting Kubernetes Secrets into a task Pod: environment variables and file mounts.
Environment Variables
When you request a secret with a mount requirement of ENV_VAR, Flyte adds a SecretKeyRef to the Pod's container environment.
User-facing Secret Request:
# Example in Flytekit (Python)
from flytekit import Secret
secret = Secret(group="my-group", key="my-key", mount_requirement=Secret.MountRequirement.ENV_VAR)
Internal Implementation:
The K8sSecretInjector calls CreateEnvVarForSecret (in flyteplugins/go/tasks/pluginmachinery/secret/utils.go) to generate the environment variable definition:
func CreateEnvVarForSecret(secret *core.Secret, envVarPrefix string) corev1.EnvVar {
optional := true
return corev1.EnvVar{
Name: strings.ToUpper(envVarPrefix + secret.Group + EnvVarGroupKeySeparator + secret.Key),
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secret.Group,
},
Key: secret.Key,
Optional: &optional,
},
},
}
}
By default, the environment variable name is prefixed with _UNION_, followed by the group and key in uppercase, separated by an underscore (e.g., _UNION_MY-GROUP_MY-KEY).
File Mounts
When you request a secret with a mount requirement of FILE (or ANY), Flyte creates a Kubernetes Volume and VolumeMount to expose the secret as a file within the container.
User-facing Secret Request:
# Example in Flytekit (Python)
secret = Secret(group="my-group", key="my-key", mount_requirement=Secret.MountRequirement.FILE)
Internal Implementation:
The injector creates a volume for the secret group and mounts it to a specific path. The default mount path prefix is /etc/flyte/secrets.
// From flyteplugins/go/tasks/pluginmachinery/secret/utils.go
func CreateVolumeMountForSecret(volumeName string, secret *core.Secret) corev1.VolumeMount {
return corev1.VolumeMount{
Name: volumeName,
ReadOnly: true,
MountPath: filepath.Join(filepath.Join(K8sSecretPathPrefix...), strings.ToLower(secret.Group)),
}
}
The resulting file path inside the container will be /etc/flyte/secrets/<group>/<key>.
Naming and Hashing Conventions
Kubernetes Secret names must be valid DNS subdomains, which means they cannot contain certain characters like underscores. Flyte handles this mapping automatically:
- Explicit Group: If you provide a
group, Flyte uses it as the name of the Kubernetes Secret object. - Missing Group: If the
groupis not set, Flyte generates a name by hashing thekeyusing MD5. This logic is implemented inEncodeK8sSecretName(inflyteplugins/go/tasks/pluginmachinery/secret/k8s_utils.go):
func EncodeK8sSecretName(secretName string) string {
hash := md5.Sum([]byte(secretName)) // #nosec
hashHex := fmt.Sprintf("%x", hash)
return hashHex
}
Configuration
To enable and configure Kubernetes native secrets, you modify the webhook section of the Flyte configuration. The Config struct in flyteplugins/go/tasks/pluginmachinery/secret/config/config.go defines the available settings.
webhook:
secretManagerType: k8s
secretEnvVarPrefix: "_UNION_"
Metadata Environment Variables
When secrets are injected, Flyte also adds metadata environment variables to the Pod to help the Flyte SDK locate them:
FLYTE_SECRETS_DEFAULT_DIR: The base directory for file mounts (default:/etc/flyte/secrets).FLYTE_SECRETS_FILE_PREFIX: The prefix used for secret files (default: empty string for K8s secrets).FLYTE_SECRETS_ENV_PREFIX: The prefix used for environment variables (default:_UNION_).
These constants are defined in flyteplugins/go/tasks/pluginmachinery/secret/secrets_pod_mutator.go:
const (
SecretPathDefaultDirEnvVar = "FLYTE_SECRETS_DEFAULT_DIR" // #nosec
SecretPathFilePrefixEnvVar = "FLYTE_SECRETS_FILE_PREFIX" // #nosec
SecretEnvVarPrefix = "FLYTE_SECRETS_ENV_PREFIX" // #nosec
)
Programmatic Fetching (Embedded Mode)
In addition to Pod mutation, Flyte supports programmatically fetching secrets from the Kubernetes API using the K8sSecretFetcher (found in flyteplugins/go/tasks/pluginmachinery/secret/k8s_secret_fetcher.go). This is used when the Embedded secret manager type is configured, allowing Flyte components to retrieve secret values directly without relying on sidecars or volume mounts.
The fetcher uses the same hashing logic to locate the Kubernetes Secret object by its ID and retrieves the value associated with the requested key.