Skip to main content

Overview

The External Secret Syncer (ESS) continuously syncs secrets and parameters from external providers into Control Plane secrets. This template deploys ESS as a workload that polls your configured providers on a set interval and creates or updates Control Plane secrets to match.

Supported Providers

What Gets Created

  • Workload — An ESS container (v1.2.4) with CPU-based autoscaling (1–3 replicas) and a readiness probe on /about.
  • Identity & Policy — An identity bound to the workload with manage permissions on all secrets, allowing ESS to create and update Control Plane secrets.
  • Secret — An opaque secret containing the sync configuration (providers and secret mappings).
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

  1. A secret or parameter stored in one of the supported providers.
  2. Credentials with read access to the desired secret (API token, IAM keys, etc.). Alternatively, you can use a cloud access identity instead of supplying keys directly.
To install, follow the instructions for your preferred method:

Configuration

The default values.yaml for this template:
workload:
  name: ess
  image: ghcr.io/controlplane-com/cpln-build/external-secret-syncer:v1.2.4
  resources:
    cpu: 200m
    memory: 256Mi
  port: 3004
  allowedIp:
    - 1.2.3.4 # Replace with your IP

essConfig:
  providers:
    - name: my-vault
      vault:
        address: https://my-vault.com:8200
        token: <TOKEN>
      syncInterval: 1m
    - name: my-aws-ssm
      awsParameterStore:
        region: us-east-1
        accessKeyId: <ACCESS_KEY>
        secretAccessKey: <SECRET_ACCESS_KEY>
    # - name: my-aws-secrets-manager
    #   awsSecretsManager:
    #     region: us-east-1
    #     accessKeyId: <ACCESS_KEY>
    #     secretAccessKey: <SECRET_ACCESS_KEY>
    # - name: my-1password
    #   onePassword:
    #     serviceAccountToken: <TOKEN>
    #     integrationName: my-ess <optional - defaults to syncer.cpln.io>
    #     integrationVersion: 1.0.0 <optional - defaults to image tag>
    # - name: my-doppler
    #   doppler:
    #     accessToken: <TOKEN>
  secrets:
    - name: auth
      provider: my-vault
      syncInterval: 20s
      dictionary:
        PORT:
          path: /v1/secret/data/app
          parse: data.port
          default: 5432
        PASSWORD:
          path: /v1/secret/data/app
          parse: data.password
        USERNAME:
          default: "no username"
          path: /v1/secret/data/app
          parse: data.username
    - name: ssm
      provider: my-aws
      syncInterval: 20s
      opaque: /example/app
    # - name: secrets-manager
    #   provider: my-aws-secrets-manager
    #   dictionary:
    #     PASSWORD:
    #       path: /example/app
    #       parse: password
    # - name: doppler
    #   provider: my-doppler
    #   opaque: /project/config/secret

Workload

  • workload.name — The name of the ESS workload.
  • workload.resources — CPU and memory allocated to the workload.
  • workload.port — The port ESS listens on (default 3004).
  • workload.allowedIp — IP addresses allowed inbound access to the workload.

Providers

Each entry in essConfig.providers defines a connection to an external secret store. Every provider must have a unique name.
ProviderRequired Fields
HashiCorp Vaultvault.address, vault.token
AWS Parameter StoreawsParameterStore.region
AWS Secrets ManagerawsSecretsManager.region
1PasswordonePassword.serviceAccountToken
Dopplerdoppler.accessToken
AWS providers optionally accept accessKeyId and secretAccessKey. If omitted, ESS falls back to credentials provided through the workload’s cloud access identity. A syncInterval can be set per provider to control how frequently ESS polls for changes (e.g., 30s, 1m, 5m).

Secrets

Each entry in essConfig.secrets maps an external secret to a Control Plane secret. Secrets support two types: Dictionary — Creates a dictionary secret with multiple key-value pairs. Each key specifies a path to fetch from, a parse expression to extract a specific field, and an optional default value.
secrets:
  - name: auth
    provider: my-vault
    dictionary:
      PORT:
        path: /v1/secret/data/app
        parse: data.port
        default: 5432
Opaque — Creates an opaque secret containing the raw value (or a parsed field) from the external source.
secrets:
  - name: ssm
    provider: my-aws-ssm
    opaque: /example/app
For opaque secrets that return base64-encoded content, add encoding: base64 to decode to plaintext. Each secret can also override the provider’s syncInterval with its own value.
Vault KV engine secrets are nested under a data key:
{
  "data": {
    "PORT": "1234"
  },
  "metadata": {
    "created_time": "2025-03-11T20:05:41.865209462Z",
    "custom_metadata": null,
    "deletion_time": "",
    "destroyed": false,
    "version": 1
  }
}
When using parse, start with data to access the secret content (e.g., data.port).

Synced Secret Output

A secret created by ESS will look like:
kind: secret
name: hello
description: hello
tags:
  syncer.cpln.io/lastError: '' # populated if ESS encounters an error
  syncer.cpln.io/source: //gvc/<gvc name>/workload/<ess workload name>
type: dictionary
data:
  PORT: '1234'
  PASSWORD: 'no pass' # default used if the key was not found
The syncer.cpln.io/lastError tag is empty on success. If ESS encounters an error syncing a secret, the tag is populated with the error message.

External References