BKE Bahriya Kubernetes Engine Start a 14-day trial

Secrets

BKE needs credentials for some components — Longhorn’s backup target, netdata’s Cloud claim token. It takes them from a directory on the node and never sends them anywhere.

One directory per Secret, one file per key

/etc/bke/secrets.d/
└── longhorn-backup/
    ├── AWS_ACCESS_KEY_ID
    ├── AWS_SECRET_ACCESS_KEY
    └── AWS_ENDPOINTS

The directory name is the Secret’s name. Each file’s name is a key; each file’s bytes are that key’s value. No quoting rules, no escaping, no format to get wrong.

Make sure the bytes are what you mean. echo appends a newline and most credentials do not want one:

printf '%s' 'AKIAEXAMPLE' > /etc/bke/secrets.d/longhorn-backup/AWS_ACCESS_KEY_ID

Permissions are checked

Each directory under secrets.d/ must be mode 0700 exactly. BKE reads the mode and refuses to run if it is anything else — not merely if it is readable by others.

chmod 0700 /etc/bke/secrets.d
chmod 0700 /etc/bke/secrets.d/*
chmod 0600 /etc/bke/secrets.d/*/*

apply.sh also requires root, and requires /etc/bke/license to be 0600.

This is not cosmetic. It exists because credentials sitting readable in a directory that syncs is a real failure we have found in practice, not a hypothetical one.

This directory is never transmitted

config.yaml is sent to api.maml.uk so your settings can be checked and the component configuration rendered, and /etc/bke/values/ is sent so an upgrade can be merged against what you have. secrets.d/ is not, and nothing sends it. They are separate precisely so that some can leave your cluster and this one cannot.

That separation is only as good as what you put where. values/<component>.yaml is yours to edit and BKE cannot tell a password in it from any other setting, so a credential belongs here, in secrets.d/, and is referred to by the Secret’s name. BKE’s own files name Secrets and never contain their values.

The consequence is that we cannot help you with the contents of this directory, and cannot see whether a value is correct. Which brings us to the part of this page that matters most.

What a missing key actually costs

In BKE as it stands, a missing key is always silent. The component starts, reports healthy, and the feature that needed the key does not work.

There are two ways a Helm chart can consume a Secret, and they behave oppositely. Both were measured on a cluster at this release’s Kubernetes version, with a Secret containing one key and pods asking for another:

Mechanism A missing key does this You would see
envFrom.secretRef pod Running, variable simply unset nothing at all
env.valueFrom.secretKeyRef pod Pending, CreateContainerConfigError a clear error naming the key

Every component BKE installs uses the first mechanism. Longhorn’s manager reads its credential through the Kubernetes API rather than a mount; netdata uses envFrom in all three of its pod specs. So the second row does not happen to you, and the first one does.

Per key

Secret Key Absent means
netdata’s claim Secret NETDATA_CLAIM_TOKEN netdata runs and never claims. The cluster does not appear in Netdata Cloud. No error anywhere
Longhorn’s backup Secret AWS_ACCESS_KEY_ID Longhorn runs; the backup target cannot authenticate, so backups do not happen
Longhorn’s backup Secret AWS_SECRET_ACCESS_KEY as above
Longhorn’s backup Secret AWS_ENDPOINTS Required only for S3 that is not AWS’s own. Legitimately absent on AWS S3 — which is why this warns rather than refuses

AWS_ENDPOINTS must carry a scheme: https://s3.example.com, not s3.example.com. A bare host is rejected by Longhorn as an invalid URI, and the result is a backup target that never becomes available — with the reason visible only in longhorn-manager’s log. We have had this one ourselves.

So BKE warns, loudly

Because the warning is the only signal you will get, apply.sh names any key it expected and did not find, and says in those words that the component will start anyway. Read those warnings. A clean-looking install with a backup target that has never worked is what those warnings are there to prevent.

It warns rather than refuses because BKE’s list of expected keys is fixed and a legitimate cluster can differ from it — AWS_ENDPOINTS on AWS S3 being exactly that case. Refusing would make BKE wrong about a working configuration.

Values are never read, only presence is checked. Extra keys are never mentioned.

A missing Secret, by contrast, refuses

Every Secret name referenced in config.yaml must resolve — to a directory here, or to a Secret already in the cluster if the name is in secrets.unmanaged. An unresolved name is a pre-flight refusal, before the first chart is fetched. Every unresolved reference is reported, not just the first one.

The distinction is the point: a missing Secret means you have not finished setting up, and stopping is right. A missing key might mean your configuration is legitimately different from the default one.

Keeping your own Secrets

If a Secret is produced by sealed-secrets, the External Secrets Operator, or by hand, list its name under secrets.unmanaged in config.yaml. BKE will verify it exists and create nothing.

Note that components.<name>.secrets and components.<name>.settings.*.credentialSecret are not the same list. secrets names what BKE must create; the settings name what the values reference. A cluster whose Secret comes from elsewhere references the name and lists nothing under secrets.

Rotating a credential

Edit the file and re-run apply.sh. The Secret is updated in place.

Updating a Secret does not by itself change a running pod. envFrom is resolved once, when the container starts, so pods holding the old value keep it. BKE restarts exactly the workloads that use a Secret it changed.

If you rotate a Secret by some other route — your own kubectl apply, or an operator syncing it — nothing restarts, and the old value stays in use until something else happens to restart those pods.

What does leave your cluster

Nothing on this page. secrets.d/ is read on the node, mapped onto Kubernetes Secrets, and never transmitted anywhere.

One thing does leave, on a schedule, and it is a different thing entirely: a daily report of your BKE and component versions, a node count and a cluster identifier. Cluster reporting sets out every field of it, what the job is and is not permitted to read, and how to turn it off.