Secrets
Applications need credentials: a token for a private container registry, a password for a database, an API key for a third-party service. Baking these into container images or into a compose file puts them in your source control and in every copy of the image, which is exactly where you do not want them.
Secrets hold those values on the platform instead, and deliver them to workloads at the point of use.
What a secret holds
A secret is a set of key-value pairs, stored encrypted, with the values base64-encoded. One secret can hold several related values — a username and a password, or a certificate and its key — so it maps naturally onto “the credentials for one thing”.
Access to the values is a separate permission from access to the secret. A principal can be allowed to see that a secret exists, and to see its name and description, without being allowed to read what is inside it. This is what makes it safe to give broad read access to a project without handing over every credential in it.
Use that distinction deliberately when granting roles: reading secret values is the permission to be careful with.
Where a secret lives
A secret can be placed at one of three scopes, and the choice matters more than it appears.
| Scope | Name | Visible to |
|---|---|---|
| Global | secrets/{secret} |
Not tied to a project. |
| Project | projects/{project}/secrets/{secret} |
The whole project, not tied to a region. |
| Project and region | projects/{project}/regions/{region}/secrets/{secret} |
The project, in that region. |
Unlike most resources, a secret is never synchronized across regions. A secret created in one region does not exist in another, and a device or workload in a different region cannot read it.
This is deliberate — sensitive material does not cross a regional boundary unless you put it there — but it has a practical consequence: a fleet spanning two regions needs the secret created in each region its devices occupy.
The failure this causes is characteristic. A deployment works perfectly in the region you tested in, and fails on exactly the devices in the other region, usually appearing as an image pull failure rather than anything mentioning secrets.
Using a secret
The two common uses both come from deploying applications.
Pulling from a private registry. Store the registry credentials in a secret and reference it as the image pull secret for your deployment. See Private container registry for the full walkthrough.
Passing configuration into a container. Reference the secret when deploying, and its values are made available to the container as a mounted volume, without appearing in your compose file.
For configuration that is not sensitive, use a config map instead. Config maps and secrets work the same way from a deployment’s point of view; the difference is that a config map’s contents are not treated as sensitive, so they are simpler to inspect and to reason about. Keep genuinely secret material in secrets and everything else in config maps, instead of putting all configuration in secrets because it is one fewer concept.
Rotating a secret
Updating a secret changes the stored value, but a running workload holds what it was given when it started. Rotation therefore has two steps, and skipping the second is the usual mistake:
- Update the secret.
- Restart the workloads that consume it, so they pick up the new value.
Plan for both when rotating a credential under time pressure — a rotated registry password with un-restarted workloads looks like it worked until the next time an image is pulled.
What not to put in a secret
Use the right mechanism for each kind of credential:
| For | Use |
|---|---|
| Credentials your workloads need | A secret. |
| Credentials your automation uses to call the SPEKTRA Edge API | A service account key. |
| Non-sensitive application configuration | A config map. |
| Device SSH authorized keys | The device’s SSH configuration, or a provisioning policy template. |
Be clear about the distinction between the first two. A secret is something the platform stores for your applications. A service account key is how something authenticates to the platform. Putting a service account key into a secret so that a workload can call the API is reasonable; using a secret as your automation’s own credential store is not.
Good practice
- One secret per credential, named for what it is. A single secret holding everything means every workload that needs one value can read all of them.
- Grant value-read access narrowly. Most people who need to work in a project do not need to read its credentials.
- Create them per region from the start if you are multi-region, instead of discovering the gap when you expand.
- Rotate on a schedule you choose, not on the schedule an incident chooses for you. Knowing the restart step is required makes this much easier to plan.
- Remember the audit trail. Reads of sensitive data are API calls like any other, so audit logs can tell you who has accessed a credential.
Related
- Private container registry — the most common use, end to end.
- Application configuration — config maps and volumes.
- Service accounts — credentials for calling the API.