See first: Juju | Secret

See also:

In the context of the charm SDK, a secret always refers to a charm-created secret.

Secrets are supported starting with ops 2.0.0, but only when using Juju 3.0.2 or greater.

Charms can use relations to share secrets, such as API keys, a database’s address, credentials and so on. Like a relation has a “provider” and a “requirer”, so a secret has an “owner” and an “observer” – though these need not coincide with the applications’ roles in the relation.

Every secret has a scope, and that is the relation its lifecycle is tied to. If the relation is removed, the secret will be removed too.

When a unit adds a secret, it becomes that secret’s owner, and it will obtain from Juju a secret ID, which it can then pass to some remote application via relation data. Any remote unit with access to that ID can get the secret (that is, access its contents). Before that is possible, however, the owner needs to grant the secret to the whole application or a specific unit.

Once the remote unit (the secret observer) gets its contents for the first time, it starts to track that secret in Juju – more specifically, its latest revision, as we will see later. When the owner adds the secret, and when the observer gets it, they both have a chance to assign to the secret a label, a locally-unique string that will be associated with that secret and can be used by the charm to refer to the secret “by name”.

The owner can choose at any time to publish a new revision of the secret, that is, change its payload (for example, replace an old key with a new one). When that happens, the observer will be notified by means of a secret-changed event. The observer can then refresh the secret, which means inform Juju that it wishes to start tracking the latest revision. From that moment on, every time the unit gets the secret, it will receive the newly-tracked revision’s contents.

However, a unit does not have to immediately update whenever a new revision becomes available. It can peek the secret’s contents, which means to inspect the latest revision of the secret without updating to it, or choose to do nothing.

When a secret is added, the owner can configure it to have a rotation policy (hourly, daily, monthly, and so on). In that case, the owner will be periodically notified, by means of a secret-rotate event, that it is time to rotate the secret – that is, create a new revision for it.

Alternatively, it can be configured to have an expiration date, that is, a specific point in time at which the charm will be notified by Juju that it is time to retire the secret by means of a secret-expired event.

Juju maintains a list of which observers are tracking each revision of each secret. The idea is that if an observer receives a secret-changed event, it will update the secret and start tracking the latest revision. Once Juju notices that there are no observers left for a given revision, it will notify the secret owner that that secret revision can be safely removed – which corresponds to the secret-remove event.

When a unit gets a secret for the first time it will automatically be set to track the latest revision. A unit cannot choose to track an outdated revision, but it can in principle refuse to update to a newer one.

Contributors: @ppasotti