---
title: Charmhub | Deploy Vault using Charmhub - The Open Operator Collection
description: Deploy the latest version of Vault as a Kubernetes Operator on any cloud.
url: https://charmhub.io/vault-k8s/libraries/vault_kv
---

# Vault

[Canonical Telco](https://charmhub.io/publisher/telco-charmers "View all packages from Canonical Telco")

* [Canonical Telco](https://charmhub.io/publisher/telco-charmers "View all packages from Canonical Telco")

Platform:

2.0/stable 590

```
juju deploy vault-k8s --channel 2.0/stable
```

[Learn to deploy on juju >](https://juju.is/docs/juju/manage-applications)

[Toggle side navigation](https://charmhub.io/vault-k8s/libraries/vault_kv#drawer)

## charms.vault\_k8s.v0.vault\_kv

* [*Docstrings*Docstrings](https://charmhub.io/vault-k8s/libraries/vault_kv)
  [*Code*Source code](https://charmhub.io/vault-k8s/libraries/vault_kv/source-code)
* + Download

    Fetch library

    ```
    charmcraft fetch-lib charms.vault_k8s.v0.vault_kv
    ```

    [Download vault\_kv.py](https://charmhub.io/vault-k8s/libraries/vault_kv/download)
  + *Last updated* 24 Mar 2025
  + *Revision* Library version 0.16

Library for the vault-kv relation.

This library contains the Requires and Provides classes for handling the vault-kv
interface.

##### Getting Started

From a charm directory, fetch the library using `charmcraft`:

```
charmcraft fetch-lib charms.vault_k8s.v0.vault_kv
```

###### Requirer charm

The requirer charm is the charm requiring a secret value store. In this example, the requirer charm
is requiring a secret value store.

```
import secrets

from charms.vault_k8s.v0 import vault_kv
from ops.charm import CharmBase, InstallEvent
from ops.main import main
from ops.model import ActiveStatus, BlockedStatus

NONCE_SECRET_LABEL = "nonce"

class ExampleRequirerCharm(CharmBase):
    def __init__(self, *args):
        super().__init__(*args)
        self.interface = vault_kv.VaultKvRequires(
            self,
            "vault-kv",
            "my-suffix",
        )

        self.framework.observe(self.on.install, self._on_install)
        self.framework.observe(self.interface.on.connected, self._on_connected)
        self.framework.observe(self.interface.on.ready, self._on_ready)
        self.framework.observe(self.interface.on.gone_away, self._on_gone_away)
        self.framework.observe(self.on.update_status, self._on_update_status)

    def _on_install(self, event: InstallEvent):
        self.unit.add_secret(
            {"nonce": secrets.token_hex(16)},
            label=NONCE_SECRET_LABEL,
            description="Nonce for vault-kv relation",
        )
        self.unit.status = BlockedStatus("Waiting for vault-kv relation")

    def _on_connected(self, event: vault_kv.VaultKvConnectedEvent):
        relation = self.model.get_relation(event.relation_name, event.relation_id)
        egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet]
        egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet))
        self.interface.request_credentials(relation, egress_subnets, self.get_nonce())

    def _on_ready(self, event: vault_kv.VaultKvReadyEvent):
        relation = self.model.get_relation(event.relation_name, event.relation_id)
        if relation is None:
            return
        vault_url = self.interface.get_vault_url(relation)
        ca_certificate = self.interface.get_ca_certificate(relation)
        mount = self.interface.get_mount(relation)

        unit_credentials = self.interface.get_unit_credentials(relation)
        # unit_credentials is a juju secret id
        secret = self.model.get_secret(id=unit_credentials)
        secret_content = secret.get_content(refresh=True)
        role_id = secret_content["role-id"]
        role_secret_id = secret_content["role-secret-id"]

        self._configure(vault_url, ca_certificate, mount, role_id, role_secret_id)

        self.unit.status = ActiveStatus()

    def _on_gone_away(self, event: vault_kv.VaultKvGoneAwayEvent):
        self.unit.status = BlockedStatus("Waiting for vault-kv relation")

    def _configure(
        self,
        vault_url: str,
        ca_certificate: str,
        mount: str,
        role_id: str,
        role_secret_id: str,
    ):
        pass

    def _on_update_status(self, event):
        # Check somewhere that egress subnet has not changed i.e. pod has not been rescheduled
        # Update status might not be the best place
        binding = self.model.get_binding("vault-kv")
        if binding is not None:
            egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet]
            egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet))
            relation = self.model.get_relation(relation_name="vault-kv")
            self.interface.request_credentials(relation, egress_subnets, self.get_nonce())

    def get_nonce(self):
        secret = self.model.get_secret(label=NONCE_SECRET_LABEL)
        nonce = secret.get_content(refresh=True)["nonce"]
        return nonce

if __name__ == "__main__":
    main(ExampleRequirerCharm)
```

You can integrate both charms by running:

```
juju integrate <vault provider charm> <vault requirer charm>
```

---

Index

* [class LogAdapter](https://charmhub.io/vault-k8s/libraries/vault_kv#logadapter)
* + [def process(
    self,
    msg,
    kwargs)](https://charmhub.io/vault-k8s/libraries/vault_kv#logadapter-process)
* [class VaultKvProviderSchema](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvproviderschema)
* [class AppVaultKvRequirerSchema](https://charmhub.io/vault-k8s/libraries/vault_kv#appvaultkvrequirerschema)
* [class UnitVaultKvRequirerSchema](https://charmhub.io/vault-k8s/libraries/vault_kv#unitvaultkvrequirerschema)
* [class ProviderSchema](https://charmhub.io/vault-k8s/libraries/vault_kv#providerschema)
* [class RequirerSchema](https://charmhub.io/vault-k8s/libraries/vault_kv#requirerschema)
* [class KVRequest](https://charmhub.io/vault-k8s/libraries/vault_kv#kvrequest)
* [def get\_egress\_subnets\_list\_from\_relation\_data(
  relation\_databag
  )](https://charmhub.io/vault-k8s/libraries/vault_kv#get_egress_subnets_list_from_relation_data)
* [def is\_requirer\_data\_valid(
  app\_data,
  unit\_data
  )](https://charmhub.io/vault-k8s/libraries/vault_kv#is_requirer_data_valid)
* [def is\_provider\_data\_valid(
  data
  )](https://charmhub.io/vault-k8s/libraries/vault_kv#is_provider_data_valid)
* [class VaultKvGoneAwayEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvgoneawayevent)
* [class VaultKvClientDetachedEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvclientdetachedevent)
* + [def \_\_init\_\_(
    self,
    handle,
    unit\_name)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvclientdetachedevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvclientdetachedevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvclientdetachedevent-restore)
* [class NewVaultKvClientAttachedEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#newvaultkvclientattachedevent)
* + [def \_\_init\_\_(
    self,
    handle,
    relation,
    app\_name,
    unit\_name,
    mount\_suffix,
    egress\_subnets,
    nonce)](https://charmhub.io/vault-k8s/libraries/vault_kv#newvaultkvclientattachedevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/vault-k8s/libraries/vault_kv#newvaultkvclientattachedevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/vault-k8s/libraries/vault_kv#newvaultkvclientattachedevent-restore)
* [class VaultKvProviderEvents](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvproviderevents)
* [class VaultKvProvides](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides-__init__)
* + [def remove\_unit\_credentials(
    self,
    relation,
    nonce)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides-remove_unit_credentials)
* + [def get\_credentials(
    self,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides-get_credentials)
* + [def get\_kv\_requests(
    self,
    relation\_id)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides-get_kv_requests)
* + [def set\_kv\_data(
    self,
    relation,
    mount,
    ca\_certificate,
    vault\_url,
    nonce,
    credentials\_juju\_secret\_id)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvprovides-set_kv_data)
* [class VaultKvBaseEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvbaseevent)
* + [def \_\_init\_\_(
    self,
    handle,
    relation\_id,
    relation\_name,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvbaseevent-__init__)
* + [def snapshot(
    self)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvbaseevent-snapshot)
* + [def restore(
    self,
    snapshot)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvbaseevent-restore)
* [class VaultKvConnectedEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvconnectedevent)
* [class VaultKvReadyEvent](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvreadyevent)
* [class VaultKvRequireEvents](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequireevents)
* [class VaultKvRequires](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name,
    mount\_suffix)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-__init__)
* + [def request\_credentials(
    self,
    relation,
    egress\_subnet,
    nonce)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-request_credentials)
* + [def get\_vault\_url(
    self,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-get_vault_url)
* + [def get\_ca\_certificate(
    self,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-get_ca_certificate)
* + [def get\_mount(
    self,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-get_mount)
* + [def get\_unit\_credentials(
    self,
    relation)](https://charmhub.io/vault-k8s/libraries/vault_kv#vaultkvrequires-get_unit_credentials)

#### class LogAdapter

Description

Adapter for the logger to prepend a prefix to all log lines. None

Methods

LogAdapter.
process(

*self*

,
msg: str

,
kwargs: MutableMapping
)

Description

Decides the format for the prepended text. None

#### class VaultKvProviderSchema

Description

Provider side of the vault-kv interface. None

#### class AppVaultKvRequirerSchema

Description

App schema of the requirer side of the vault-kv interface. None

#### class UnitVaultKvRequirerSchema

Description

Unit schema of the requirer side of the vault-kv interface. None

#### class ProviderSchema

Description

The schema for the provider side of this interface. None

#### class RequirerSchema

Description

The schema for the requirer side of this interface. None

#### class KVRequest

Description

This class represents a kv request from an interface Requirer. None

#### def get\_egress\_subnets\_list\_from\_relation\_data(relation\_databag)

Return the egress\_subnet as a list.

Arguments

relation\_databag

the relation databag of the unit or the app.

Description

This function converts the string with values separated by commas to a list.

#### def is\_requirer\_data\_valid(     app\_data,     unit\_data )

Description

Return whether the requirer data is valid. None

#### def is\_provider\_data\_valid(data)

Description

Return whether the provider data is valid. None

#### class VaultKvGoneAwayEvent

Description

VaultKvGoneAwayEvent Event. None

#### class VaultKvClientDetachedEvent

Description

VaultKvClientDetachedEvent Event. None

Methods

VaultKvClientDetachedEvent.
\_\_init\_\_(

*self*

,
handle

,
unit\_name: str
)

VaultKvClientDetachedEvent.
snapshot(

*self*
)

Description

Return snapshot data that should be persisted. None

VaultKvClientDetachedEvent.
restore(

*self*

,
snapshot
)

Description

Restore the event from a snapshot. None

#### class NewVaultKvClientAttachedEvent

Description

New vault kv client attached event. None

Methods

NewVaultKvClientAttachedEvent.
\_\_init\_\_(

*self*

,
handle

,
relation

,
app\_name: str

,
unit\_name: str

,
mount\_suffix: str

,
egress\_subnets

,
nonce: str
)

NewVaultKvClientAttachedEvent.
snapshot(

*self*
)

Description

Return snapshot data that should be persisted. None

NewVaultKvClientAttachedEvent.
restore(

*self*

,
snapshot
)

Description

Restore the value state from a given snapshot. None

#### class VaultKvProviderEvents

Description

List of events that the Vault Kv provider charm can leverage. None

#### class VaultKvProvides

Description

Class to be instantiated by the providing side of the relation. None

Methods

VaultKvProvides.
\_\_init\_\_(

*self*

,
charm

,
relation\_name: str
)

VaultKvProvides.
remove\_unit\_credentials(

*self*

,
relation

,
nonce
)

Description

Remove nonce(s) from the relation. None

VaultKvProvides.
get\_credentials(

*self*

,
relation
)

Description

Get the unit credentials from the app relation data and load it as a dict. None

VaultKvProvides.
get\_kv\_requests(

*self*

,
relation\_id
)

Description

Get all KV requests for the relation. None

VaultKvProvides.
set\_kv\_data(

*self*

,
relation

,
mount: str

,
ca\_certificate: str

,
vault\_url: str

,
nonce: str

,
credentials\_juju\_secret\_id: str
)

Description

Set the kv data on the relation. None

#### class VaultKvBaseEvent

Description

Base class for VaultKV requirer events. None

Methods

VaultKvBaseEvent.
\_\_init\_\_(

*self*

,
handle

,
relation\_id: int

,
relation\_name: str

,
relation
)

VaultKvBaseEvent.
snapshot(

*self*
)

Description

Return snapshot data that should be persisted. None

VaultKvBaseEvent.
restore(

*self*

,
snapshot
)

Description

Restore the value state from a given snapshot. None

#### class VaultKvConnectedEvent

Description

VaultKvConnectedEvent Event. None

#### class VaultKvReadyEvent

Description

VaultKvReadyEvent Event. None

#### class VaultKvRequireEvents

Description

List of events that the Vault Kv requirer charm can leverage. None

#### class VaultKvRequires

Description

Class to be instantiated by the requiring side of the relation. None

Methods

VaultKvRequires.
\_\_init\_\_(

*self*

,
charm

,
relation\_name: str

,
mount\_suffix: str
)

VaultKvRequires.
request\_credentials(

*self*

,
relation

,
egress\_subnet

,
nonce: str
)

Request credentials from the vault-kv relation.

Arguments

relation

The relation object or the relation id.

egress\_subnet

The egress subnets requesting the credentials for.

nonce

The nonce that identifies the unit.

Description

Credentials are tied to the unit egress\_subnet, so if the egress\_subnet
changes a new secret id must be generated.

A change in egress\_subnets can happen when the pod is rescheduled to a different
node by the underlying substrate without a change from Juju.

VaultKvRequires.
get\_vault\_url(

*self*

,
relation
)

Description

Return the vault\_url from the relation. None

VaultKvRequires.
get\_ca\_certificate(

*self*

,
relation
)

Description

Return the ca\_certificate from the relation. None

VaultKvRequires.
get\_mount(

*self*

,
relation
)

Description

Return the mount from the relation. None

VaultKvRequires.
get\_unit\_credentials(

*self*

,
relation
)

Return the unit credentials from the relation.

Description

Unit credentials are stored in the relation data as a Juju secret id.
