(secret)= # Secret > See also: {ref}`manage-secrets` In Juju, (starting with Juju 3.0) a **secret** is a sensitive bit of information (e.g., account credential, password, certificate, SSH key, API key, encryption key, etc.) that a {ref}`charm ` needs to know. ## Secret taxonomy (charm-secret)= ### Charm A **charm secret** is a secret created by a charm. A charm secret is shared with another charm (the secret 'observer') over relation data. The secret is tied to the lifecycle of the relation. (unit-secret)= #### Unit A **unit secret** is a {ref}`charm secret ` created by a unit and owned by the unit. (application-secret)= #### Application An **application secret** is a {ref}`charm secret ` created by the leader unit and (because the leader unit does not have a fixed identity) owned by the application (i.e., when the leader unit changes, the secret is owned by the new leader). (user-secret)= ### User A **user secret** is a secret created by a user with a model `admin` access level and (because this does not have a fixed identity) owned by the model . A user secret is shared with a charm (the secret 'observer') via a configuration option. The charm must support the configuration option. ## Secret identification Secrets are identified by an automatically-assigned ID (a URI generated by Juju at creation time) or (for user secrets, also) a user-defined name. (secret-backend)= ## Secret backend > > See also: {ref}`manage-secret-backends` A **secret backend** is a service that is used to store sensitive content which Juju manages as {ref}`secrets `. Secret backends are per model. A secret backend is identified by a name and a type, and admits various configuration options, some of them generic and some backend-type-specific. ### Name The name of a secret backend can be: - `auto` (i.e., `internal` for machine models and `local` for Kubernetes models) - `internal` - `` The name is set via the `secret-backend` model configuration key. > See more: {ref}`list-of-model-configuration-keys` ### Type The type of a secret backend can be `controller`, `kubernetes`, and `vault`. ```{tip} For production use, we recommend `vault`. ``` #### `controller` The `controller` backend is the Juju model database. It is the default secret backend for machine (VM) models. #### `kubernetes` The `kubernetes` backend is the model's Kubernetes namespace. It is the default secret backend for container (Kubernetes) models. Available starting with Juju 3.1. #### `vault` The `vault` backend refers to the Hashicorp Vault. It is available as an opt-in to both machine and Kubernetes models. Available starting with Juju 3.1. (secret-backend-configuration-options)= ### Configuration options #### Generic The generic configuration keys currently include just the following: ||| |-|-| |`token-rotate` | The maximum period for which an access token is valid for. Some time prior to the token expiring Juju will generate a new one. Possible values: standard Go duration (e.g., 2h, 7d). The minimum is 1h.| The `vault` backend is the only one that supports it for now. #### Backend-specific The `vault` backend is the only one that supports specific configuration keys. These are: ||| |---|---| |`ca-cert`|The path to a PEM-encoded CA certificate file on the local disk. This file is used to verify the Vault server's SSL certificate.| |`client-cert`|The path to a PEM-encoded client certificate on the local disk. This file is used for TLS communication with the Vault server.| |`client-key`|The path to an unencrypted, PEM-encoded private key on disk which corresponds to the matching client certificate.| |`endpoint`|| |`namespace`|The namespace to use for the command. Setting this is not necessary but allows using relative paths.| |`tls-server-name`|The name to use as the SNI host when connecting via TLS.| |`token`|The vault authentication token.| > See more: [Vault | `vault server`](https://fig.io/manual/vault/server), [Hashicorp | Vault commands](https://developer.hashicorp.com/vault/docs/commands#args).
(You will see more options there as we currently support only support a subset.) A minimum configuration must include the `endpoint` and `token`. However, just that would not be insecure, as it wouldn't establish an encrypted TLS connection to Vault. For production you should configure your Vault securely, following recommendations in the upstream Vault documentation. ## Permissions around secrets An entity -- unit/app or user -- that has created / owns the secret can **manage** it (call `secret-set, secret-grant, secret-revoke, secret-info-get`, etc.). An entity that does not own the secret can only **view** it (call `secret-get`), and only if it has been granted access to it -- except for peer units or a model admin user, who get view access automatically. ## Secret lifecycle ```{important} This section currently covers only the lifecycle of a charm secret. ``` 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 access will be revoked. 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 charm 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, a charm secret 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. ```{important} 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. ```