Secrets and secret stores
Connection secrets are encrypted (AES-256-GCM), write-only and never returned or logged. To keep them in your own vault, an Admin adds a store under Settings → Secret stores (HashiCorp Vault KV v2, AWS Secrets Manager, Google Secret Manager, Kubernetes Secrets). Then every secret field of a source or destination offers Type it or From a secret store:
- Store — the project's stores, with whether each is connected.
- Secret — listed from the store (searchable; at most 1,000, beyond that or when the store's credentials may read but not list, you type the path).
- Key — the secret's key names, pre-picked when one is named like the field (
password,pwd,secretAccessKey, …) or is the only one. A plain-text secret (AWS, Google) has no keys and is used whole.
The reference is checked as you pick, and the dialog saves only once it resolves (Save anyway
is there for a store that isn't reachable from BeziSync yet; the deploy checks block it if it stays
broken). BeziSync stores only the reference — ref+<store>://<path>#<key>, e.g.
ref+vault://cdc/orders-db#password — and reads the value when a connector needs it. Values never
reach the browser: listing returns secret names and key names only. The API and MCP tools take the
same reference string; "Try a reference" on a store's card confirms one without showing the value.
Each store's card shows what it is set to and which credentials are saved (with when they were last replaced, never their values). Adding a store and Edit both test the settings before saving: if the test fails, nothing is saved, unless you choose Save anyway (for a vault that is not reachable yet). A store's name can't change, because connections refer to it.
What each store needs:
- Vault — KV version 2; read on the secrets, and
liston the mount'smetadata/paths for the picker to list them. - AWS Secrets Manager —
secretsmanager:GetSecretValue, plusListSecretsfor the picker; keys, or the control plane's IRSA / instance role when left empty. Endpoint (Expert) takes a VPC endpoint or an emulator. - Google Secret Manager — Secret Manager Secret Accessor, plus
secrets.listfor the picker; a service-account key, or Workload Identity when left empty. Endpoint (Expert) takes a private endpoint or an emulator; with no key, BeziSync sends no sign-in, as emulators expect. - Kubernetes Secrets —
getandliston Secrets in one namespace. This cluster uses BeziSync's own service account (the chart grants it in runtime namespaces). Another cluster asks for a kubeconfig whose user has a static ServiceAccount token; sign-in plugins (exec, such asgke-gcloud-auth-plugin, or auth providers) can't run in BeziSync. Paste it or Load from a file. Its API server goes through the same network guard as every other store. To make one:
NS=cdc-secrets
kubectl -n $NS create serviceaccount bezisync-reader
kubectl -n $NS create role bezisync-reader --verb=get,list --resource=secrets
kubectl -n $NS create rolebinding bezisync-reader --role=bezisync-reader --serviceaccount=$NS:bezisync-reader
kubectl -n $NS apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata: { name: bezisync-reader-token, annotations: { kubernetes.io/service-account.name: bezisync-reader } }
type: kubernetes.io/service-account-token
EOF
SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CA=$(kubectl -n $NS get secret bezisync-reader-token -o jsonpath='{.data.ca\.crt}')
TOKEN=$(kubectl -n $NS get secret bezisync-reader-token -o jsonpath='{.data.token}' | base64 -d)
cat > bezisync-kubeconfig.yaml <<EOF
apiVersion: v1
kind: Config
current-context: bezisync
clusters: [{ name: c, cluster: { server: $SERVER, certificate-authority-data: $CA } }]
contexts: [{ name: bezisync, context: { cluster: c, user: reader } }]
users: [{ name: reader, user: { token: $TOKEN } }]
EOF The server must be an address BeziSync can reach. Delete the local file once it's saved in
BeziSync.
Kubernetes runtimes ask the same way: their kubeconfig, GKE and EKS fields appear only for the sign-in chosen under Another cluster.
#Copy to another project
A connection's ⋯ → Copy to project… (or several selected rows) copies sources and destinations
into another project where you manage connections; the originals stay. The dialog shows the plan
first: a name the other project already uses is copied as name-2, or Update the existing one
replaces its settings (listing the changes and the pipelines there that use it) and keeps its own
password. Saved passwords and keys are left out by default: the copy says Needs its password,
and nothing that uses it deploys until someone there enters it. Admins can choose Copy them
(copied on the server, still encrypted, never shown). A secret that comes from a store the other
project lacks needs a choice: copy that store too (Admins), or use one of the other project's stores.
The other project's policies apply, and both audit logs record the copy. Admins copy a secret store
on its own with ⋯ → Copy to project… on its card. Promote offers the same copy when the
other project has no matching source or destination.