HashiCorp Vault Integration
Flyte integrates with HashiCorp Vault by leveraging the Vault Agent Sidecar Injector. When a task requests a secret, the VaultSecretManagerInjector adds specific annotations to the task pod. These annotations instruct the Vault Agent to retrieve secrets from Vault and mount them as files within the pod.
Configure the Vault Secret Manager
To enable Vault integration, you must configure the VaultSecretManagerConfig within the Flyte configuration. This configuration specifies the Vault role and any additional annotations required by your Vault setup.
{
"webhook": {
"secretManagerTypes": ["vault"],
"vaultSecretManager": {
"role": "flyte-task-role",
"annotations": {
"vault.hashicorp.com/agent-pre-populate-only": "true",
"vault.hashicorp.com/agent-limits-cpu": "100m"
}
}
}
}
The VaultSecretManagerConfig struct in flyteplugins/go/tasks/pluginmachinery/secret/config/config.go supports the following fields:
Role: The Vault role that the injector will use for authentication.Annotations: A map of custom annotations to add to the pod, allowing you to customize the Vault Agent behavior (e.g., resource limits or sidecar configuration).KVVersion: (Deprecated) The default KV engine version. Use theGroupVersionfield in the secret request instead.
Requesting Secrets in Tasks
Flyte maps secret requests to Vault paths using the Group and Key fields. The Group corresponds to the Vault secret path, and the Key corresponds to the specific key within that secret.
KV Engine Version 2 (Recommended)
For Vault KV Secrets Engine V2, specify kv2 in the GroupVersion field. This ensures the injector uses the correct template query (.Data.data) to extract the secret value.
# Example of how a secret request is structured in Flyte
secret = Secret(
group="secret/data/my-app",
key="api_key",
group_version="kv2"
)
The VaultSecretManagerInjector transforms this request into the following annotations (using a unique UUID to prevent collisions):
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "flyte-task-role"
vault.hashicorp.com/agent-inject-secret-<uuid>: "secret/data/my-app"
vault.hashicorp.com/agent-inject-template-<uuid>: '{{- with secret "secret/data/my-app" -}}{{ .Data.data.api_key }}{{- end -}}'
vault.hashicorp.com/agent-inject-file-<uuid>: "secret/data/my-app/api_key"
KV Engine Version 1
For unversioned secrets (KV V1), set the GroupVersion to kv1. This changes the template query to .Data.
secret = Secret(
group="secret/my-legacy-app",
key="password",
group_version="kv1"
)
Accessing Secrets in the Task
Secrets are mounted as files at a predictable path. The VaultSecretManagerInjector automatically sets the FLYTE_SECRETS_DEFAULT_DIR environment variable to /etc/flyte/secrets.
Files are organized by their group and key:
/etc/flyte/secrets/<SecretGroup>/<SecretKey>
For a secret with group="foo" and key="bar", the file will be located at:
/etc/flyte/secrets/foo/bar
Troubleshooting and Limitations
Unsupported Mount Requirements
The Vault injector only supports FILE or ANY mount requirements. If you attempt to use ENV_VAR, the injection will fail with an error:
// From flyteplugins/go/tasks/pluginmachinery/secret/vault_secret_manager.go
case coreIdl.Secret_ENV_VAR:
return p, false, fmt.Errorf("Env_Var is not a supported mount requirement for Vault Secret Manager")
Vault Agent Requirement
The VaultSecretManagerInjector does not communicate with Vault directly. It only adds annotations. A Vault Agent Sidecar Injector must be installed and configured in your Kubernetes cluster for these annotations to result in mounted secrets.
Multiple Secrets
Flyte supports requesting multiple secrets in a single task. The injector uses uuid.NewUUID() for each secret's annotation keys (e.g., agent-inject-secret-<uuid>) to ensure that multiple secrets from different paths can be mounted simultaneously without overwriting each other's configuration.