The External Secrets Enterprise is product suite is a premium product. It requires a specific subscription. Contact us for more information.

Securing Applications with Runtime-Bound Credentials

Dynamic credentials are a cornerstone of modern application security, providing temporary, on-demand access to resources. Instead of relying on long-lived static secrets, applications receive credentials that are:
  • Runtime-Bound: Generated specifically for a Pod instance when it starts.
  • Disposable: Automatically revoked or expire when the Pod is deleted or their Time-To-Live (TTL) is reached.
  • Least Privilege: Scoped with the minimum necessary permissions for the task at hand.
External Secrets Enterprise orchestrates a powerful combination of its features – the Pod Webhook, esi-cli, ESI Federation, and Generators – to deliver a seamless dynamic credentials experience.

Key ESE Components for Dynamic Credentials

  • Pod Admission Webhook: Intercepts Pod creation/update events and automatically injects and configures an esi-cli init container based on Pod annotations.
  • esi-cli: Runs as an init container within your application Pod. It communicates with the ESI Federation server to fetch dynamic credentials from a Generator and injects them into the main application container (as environment variables or files).
  • ESI Federation: Enables esi-cli (as a client) to securely request secrets from a central Federation Server. This server can be the same ESE instance managing the Pod or a separate, dedicated ESE instance.
  • Generators: Custom Resources (CRs) deployed on the Federation Server. They define how to create dynamic secrets on-the-fly by interacting with backend systems like HashiCorp Vault, AWS IAM, GCP IAM, etc.

The Dynamic Credential Workflow

  1. Pod Creation: A Pod is defined with specific annotations instructing the ESE Pod Webhook to inject esi-cli and configure it for dynamic credential retrieval.
  2. Webhook Injection: The Pod Webhook intercepts the Pod creation request. It injects an esi-cli init container and configures it using the provided annotations (federation server URL, target generator, injection method, etc.).
  3. esi-cli Execution: The esi-cli init container starts before the main application container.
  4. Federation Request: esi-cli authenticates to the ESI Federation Server (typically using the Pod’s Service Account token) and requests a secret from the specified Generator.
  5. Generator Action: The Generator on the Federation Server interacts with its configured backend (e.g., Vault) to create a new, temporary credential.
  6. Credential Delivery: The Federation Server returns the dynamic credential to esi-cli.
  7. Secret Injection: esi-cli injects the received credential data into the application’s environment (e.g., as environment variables or files in a shared volume).
  8. Application Start: The esi-cli init container completes, and the main application container starts with the dynamic credential readily available.
  9. Credential Revocation: When the Pod is deleted, or the credential’s TTL expires, the Generator (or the backend system it manages) is responsible for revoking or ensuring the credential is no longer valid.

Example: Dynamic Vault Credentials for a Pod

Let’s illustrate with an example where a Pod needs temporary credentials from HashiCorp Vault. Prerequisites:
  • External Secrets Enterprise installed with Pod Webhook and Federation capabilities enabled.
  • HashiCorp Vault configured with a secrets engine and role suitable for generating dynamic credentials.
  • The ESE Federation Server must be configured to communicate with Vault (e.g., via a SecretStore pointing to Vault).
Step 1: Define and Install a Generator Create a Generator Custom Resource on the ESE Federation Server. This example uses a hypothetical VaultDynamicSecretGenerator that leverages an existing ESE SecretStore (which points to Vault) to generate credentials.
# On the ESE Federation Server cluster
apiVersion: generators.external-secrets.io/v1alpha1 
kind: VaultDynamicSecret
metadata:
  name: vault-app-creds-generator
  namespace: my-app
spec:
  #... your normal VaultDynamicGenerator  Spec
Apply this manifest to your ESE Federation Server cluster. Step 2: Configure Federation Access Control Create an Authorization CR on the ESE Federation Server to allow the Service Account of your application Pod to use the vault-app-creds-generator.
apiVersion: federation.external-secrets.io/v1alpha1
kind: KubernetesFederation
metadata:
  name: my-app-cluster
spec:
  url: "https://kubernetes.default.svc.cluster.local"
---
# On the ESE Federation Server cluster
apiVersion: federation.external-secrets.io/v1alpha1 
kind: Authorization
metadata:
  name: my-app-pod-can-use-vault-generator
  namespace: my-app
spec:
  subject:
    subject: "system:serviceaccount:my-app:my-app-sa"
    issuer: "https://oidc.my-app-cluster.example.com"
  federationRef:
    kind: KubernetesFederation
    name: my-app-cluster
  allowedGenerators:
  - kind: VaultDynamicSecretGenerator
    name: vault-app-creds-generator
    namespace: my-app
Apply this manifest. Step 3: Configure the Application Pod Define your application Pod with a Service Account and the necessary annotations for the ESE Pod Webhook and esi-cli.
# In the application's namespace: my-app-namespace
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-application-sa
  namespace: my-app
---
apiVersion: v1
kind: Pod
metadata:
  name: my-secure-application
  namespace: my-app
  annotations:
    "esi.external-secrets.io/federated-server-url": "https://external-secrets.external-secrets.svc.cluster.local:8443"
    "esi.external-secrets.io/federated-generators": "my-app/VaultDynamicSecret/vault-app-creds-generator" # targets the generator for vault
    # If the generator is namespaced and not in the default 'external-secrets' namespace (or the namespace ESE is configured to look in):

    # --- esi-cli Secret Injection Method ---
    "esi.external-secrets.io/env-vars": "DB_USERNAME=vault-app-creds-generator.username,DB_PASSWORD=vault-app-creds-generator.password"
spec:
  serviceAccountName: my-application-sa
  containers:
  - name: main-app-container
    image: your-application-image:latest
    command: 
    - /app/server # your application entrypoint
    ... # rest of your pod spec
When this Pod is created:
  1. The ESE webhook injects esi-cli.
  2. esi-cli uses the my-application-sa token to talk to the Federation Server.
  3. It requests credentials from vault-app-creds-generator.
  4. The generator contacts Vault, gets dynamic credentials (e.g., a temporary username and password).
  5. esi-cli sets DB_USER and DB_PASS environment variables for main-app-container.
  6. The application starts and uses these temporary credentials.
  7. When the Pod is deleted, Vault (if configured correctly for the role) revokes the lease for these credentials.

Benefits of ESE Dynamic Credentials

  • Enhanced Security Posture: Drastically reduces the risk associated with compromised static credentials.
  • Automated Lifecycle: Credential provisioning and injection are fully automated.
  • Centralized Policy and Audit: Generators and Authorizations on the Federation Server provide central control and can be audited.
  • Seamless Integration: Works with existing Kubernetes RBAC and Service Accounts.
  • Flexibility: Supports various backends through different Generator types and diverse injection methods (env vars, files).
By implementing dynamic credentials with External Secrets Enterprise, you significantly strengthen your application security in Kubernetes environments.