The External Secrets Enterprise is product suite is a premium product. It requires a specific subscription. Contact us for more information.
esi-cli operates in one of two primary modes, specified by the mandatory --mode flag. Each mode is tailored for different use cases in managing and injecting secrets into your applications.

init Mode (--mode=init)

This mode is designed for scenarios where secrets must be available as environment variables or files before an application’s main process starts. It’s commonly used within a Kubernetes init container. Key Behaviors & Characteristics:
  • Secret Fetching: Retrieves secrets based on the configurations provided by flags like --external-secrets, --inject-on-env, --inject-on-file, and federation flags.
  • Environment Variable Injection: If --external-secrets or --inject-on-env are used, esi-cli populates the environment with the fetched secret data.
  • File Injection: If --inject-on-file is used, esi-cli writes secret data to the specified file paths.
  • Application Execution: A crucial aspect of init mode is that it executes another application binary after setting up the environment. This is specified by the --binary-path flag. Any arguments for the application can be passed via the --args flag.
  • Lifecycle: esi-cli in init mode is short-lived. Once it fetches secrets, injects them, and executes the target binary, its job is done.
Primary Use Case: To prepare the complete secret environment (both environment variables and files) for an application and then launch that application process. This ensures the application starts with all necessary secrets readily available. Example Invocation Snippet Given the following ExternalSecret manifest:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: my-worker-settings-es
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: your-store
    kind: ClusterSecretStore
  target:
    name: app_settings
  data:
  - secretKey: foo_bar
    remoteRef:
      key: /foo/bar
  - secretKey: foo_baz
    remoteRef:
      key: /foo/baz

You can leverage esi-cli to render these env vars via:
esi-cli --mode=init \
  --namespace=my-app-ns \
  --external-secrets=my-worker-settings-es \
  --inject-on-env=FOO_BAR=app_settings.foo_bar,FOO_BAZ=app_settings.foo_baz \
  --binary-path=/usr/local/bin/my-application \
  --args="--your-app-flags=true, --config-file=/app/config/settings.yaml"
The --binary-path flag is required when using --mode=init.

daemon Mode (--mode=daemon)

This mode is designed for scenarios where secrets need to be available as files and potentially refreshed while an application is running. It’s commonly used within a Kubernetes sidecar container. Key Behaviors & Characteristics:
  • Secret Fetching: Retrieves secrets primarily for file injection, configured via --inject-on-file and federation flags.
  • File Injection: This is the main focus of daemon mode. Secrets are written to the specified file paths.
  • Long-Lived Process: Unlike init mode, esi-cli in daemon mode runs as a long-lived process. It does not execute another binary.
  • Secret Refreshing & Watching:
    • Local Kubernetes Mode: When fetching secrets directly from ExternalSecret resources in the same cluster (i.e., not using federation), esi-cli can watch for changes to these ExternalSecret resources. If a change is detected, it re-fetches the secrets and updates the target files.
    • Federation Mode / Fallback: It uses a periodic refresh interval, defined by --daemon-refresh-interval (defaulting to 2 minutes), to periodically re-fetch secrets and update files. This is the primary refresh mechanism when using ESI Federation and also serves as a fallback resync mechanism in local mode.
Primary Use Case: To provide secrets as files to a running application, with the capability for those files to be automatically updated if the underlying secrets change in the source (either Kubernetes ExternalSecret or a federated ESI server). Example Invocation Snippet Suppose you have two ExternalSecrets like this:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: my-worker-settings-es
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: your-store
    kind: ClusterSecretStore
  target:
    name: app_settings
    template:
      data:
        configFile: |
          foo_bar: {{ .foo_bar }}
          foo_baz: {{ .foo_baz }}
  data:
  - secretKey: foo_bar
    remoteRef:
      key: /foo/bar
  dataFrom:
    - remoteRef:
        key: /foo/baz
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: my-app-certs-es
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: your-store
    kind: ClusterSecretStore
  target:
    name: app_creds
    template:
      data:
        tls_crt: |
          {{ .tls_crt }}
        tls_key: |
          {{ .tls_key }}
  data:
  - secretKey: tls_crt
    remoteRef:
      key: tls.crt
  - secretKey: tls_key
    remoteRef:
      key: tls.key
You can leverage esi-cli to render these via:
esi-cli --mode=daemon \
  --namespace=worker-ns \
  --externalsecrets=my-worker-settings-es,my-app-certs-es \
  --inject-on-file=/mnt/secrets/config.json=app_settings.configFile,/mnt/certs/tls.crt=app_creds.tls_crt \
  --daemon-refresh-interval=5m
Applications consuming files written by esi-cli in daemon mode should be capable of detecting changes to these files and reloading their configuration if they need to pick up updated secret values dynamically.
Understanding these two modes is fundamental to effectively using esi-cli to manage secrets for your applications. Choose the mode that best fits your application’s architecture and secret consumption patterns.