---
title: Charmhub | Deploy Istio Beacon using Charmhub - The Open Operator Collection
description: Deploy the latest version of Istio Beacon as a Kubernetes Operator on
  any cloud.
url: https://charmhub.io/istio-beacon-k8s/libraries/service_mesh
---

# Istio Beacon

[Canonical Observability](https://charmhub.io/publisher/observability "View all packages from Canonical Observability")

* [Canonical Observability](https://charmhub.io/publisher/observability "View all packages from Canonical Observability")

Platform:

1/stable rev34-3-g85bed59

```
juju deploy istio-beacon-k8s --channel 1/stable
```

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

[Toggle side navigation](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#drawer)

## charms.istio\_beacon\_k8s.v0.service\_mesh

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

    Fetch library

    ```
    charmcraft fetch-lib charms.istio_beacon_k8s.v0.service_mesh
    ```

    [Download service\_mesh.py](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh/download)
  + *Last updated* 05 Jun 2026
  + *Revision* Library version 0.20

#### Service Mesh Library.

This library facilitates adding your charmed application to a service mesh, leveraging the
`service_mesh` and `cross_model_mesh` interfaces to provide secure, policy-driven traffic
management between applications.

##### Overview

Service meshes provide capabilities for routing, controlling, and monitoring traffic between
applications. A key feature is the ability to restrict traffic between Pods. For example, you can define that Pod MetricsScraper can `GET` from Pod MetricsProducer
at `/metrics` on port `9090`, while preventing SomeOtherPod from accessing it.

##### Consumer

The ServiceMeshConsumer object subscribes a charm and its workloads to a related service mesh.
Since application relations often indicate traffic flow patterns (e.g., DbConsumer requiring
DbProducer), ServiceMeshConsumer provides automated creation of traffic rules based on
application relations.
The ServiceMeshConsumer implements the `requirer` side of the juju relation.

###### Setup

First, add the required relations to your `charmcraft.yaml`:

```
requires:
  service-mesh:
    limit: 1
    interface: service_mesh
    description: |
      Subscribe this charm into a service mesh to enforce authorization policies.
  require-cmr-mesh:
    interface: cross_model_mesh
    description: |
      Allow a cross-model application access to catalogue via the service mesh.
      This relation provides additional data required by the service mesh to enforce cross-model authorization policies.

provides:
  provide-cmr-mesh:
    interface: cross_model_mesh
    description: |
      Access a cross-model application from catalogue via the service mesh.
      This relation provides additional data required by the service mesh to enforce cross-model authorization policies.
```

Instantiate a ServiceMeshConsumer object in your charm's `__init__` method:

```
from charms.istio_beacon_k8s.v0.service_mesh import Method, Endpoint, AppPolicy, UnitPolicy, ServiceMeshConsumer

class MyCharm(CharmBase):
    def __init__(self, *args):
        super().__init__(*args)
        self._mesh = ServiceMeshConsumer(
            self,
            policies=[
                AppPolicy(
                    relation="data",
                    endpoints=[
                        Endpoint(
                            ports=[HTTP_LISTEN_PORT],
                            methods=[Method.get],
                            paths=["/data"],
                        ),
                    ],
                ),
                UnitPolicy(
                    relation="metrics",
                    ports=[HTTP_LISTEN_PORT],
                ),
            ],
        )
```

This example creates two policies:

* An app policy - When related over the `data` relation, allow the related application to `GET` this application's `/data` endpoint on the specified port through the app's Kubernetes service.
* A unit policy - When related over the `metrics` relation, allow the related application to access this application's unit pods directly on the specified port without any other restriction. UnitPolicy does not support fine-grained access control on the methods and paths via `Endpoints`.

An AppPolicy can be used to control how the source application can communicate with the target application via the app address.
A UnitPolicy allows access to the specified port but only to the unit pods of the charm via individual unit addresses.

###### Cross-Model Relations

To request service mesh policies for cross-model relations, additional information is required.

For any charm that wants to grant access to a related application (say, the above example
charm providing a `data` relation), these charms must also implement and relate over the
`cross_model_mesh` relation. For `cross_model_mesh`, the charm granting access should be the
provider, and the charm trying to communicate should be the requirer.

###### Joining the Mesh

For most charms, instantiating ServiceMeshConsumer automatically configures the charm
to join the mesh. For legacy "podspec" style charms or charms deploying custom
Kubernetes resources, you must manually apply the labels returned by
`ServiceMeshConsumer.labels()` to your pods.

##### Provider

The ServiceMeshProvider implements the provider side of the juju relation. To provide a service mesh, instantiate ServiceMeshProvider in your charm's `__init__` method:

```
from charms.istio_beacon_k8s.v0.service_mesh import ServiceMeshProvider

class MyServiceMeshCharm(CharmBase):
    def __init__(self, *args):
        super().__init__(*args)
        self._mesh = ServiceMeshProvider(
            charm=self,
            labels={"istio.io/dataplane-mode": "ambient"},
            mesh_relation_name="service-mesh",
        )
```

###### Configuration

The `labels` argument specifies the labels that indicate to the service mesh that a Pod
should be subscribed to the mesh. These labels are service-mesh specific, for eg.:

* For Istio ambient mesh: `{"istio.io/dataplane-mode": "ambient"}`
* For Istio sidecar mesh: `{"istio-injection": "enabled"}`

###### Accessing Mesh Policies

The provider exposes the `mesh_info()` method that returns a list of MeshPolicy objects
for configuring the service mesh:

```
for policy in self._mesh.mesh_info():
    configure_service_mesh_policy(policy)
```

##### Data Models

* **Method**: Defines enum for HTTP methods (GET, POST, PUT, etc.)
* **Endpoint**: Defines traffic endpoints with hosts, ports, methods, and paths
* **AppPolicy**: Defines application level authorization policy for the consumer
* **UnitPolicy**: Defines unit level authorization policy for the consumer
* **MeshPolicy**: Contains complete policy information for mesh configuration
* **CMRData**: Contains cross-model relation metadata

---

Index

* [class MeshType](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#meshtype)
* [class Method](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#method)
* [class Endpoint](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#endpoint)
* [class PolicyTargetType](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policytargettype)
* [class Policy](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policy)
* + [def \_\_init\_\_(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policy-__init__)
* [class AppPolicy](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#apppolicy)
* [class UnitPolicy](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#unitpolicy)
* [class MeshPolicy](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#meshpolicy)
* [class ServiceMeshProviderAppData](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshproviderappdata)
* [class CMRData](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#cmrdata)
* [class ServiceMeshConsumer](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer)
* + [def \_\_init\_\_(
    self,
    charm,
    mesh\_relation\_name,
    cross\_model\_mesh\_requires\_name,
    cross\_model\_mesh\_provides\_name,
    policies,
    auto\_join)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-__init__)
* + [def update\_service\_mesh(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-update_service_mesh)
* + [def labels(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-labels)
* + [def enabled(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-enabled)
* + [def mesh\_type(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-mesh_type)
* + [def lightkube\_client(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshconsumer-lightkube_client)
* [class ServiceMeshProvider](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshprovider)
* + [def \_\_init\_\_(
    self,
    charm,
    labels,
    mesh\_type,
    mesh\_relation\_name)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshprovider-__init__)
* + [def update\_relations(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshprovider-update_relations)
* + [def mesh\_info(
    self)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#servicemeshprovider-mesh_info)
* [def build\_mesh\_policies(
  relation\_mapping,
  target\_app\_name,
  target\_namespace,
  policies,
  cmr\_application\_data
  )](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#build_mesh_policies)
* [def reconcile\_charm\_labels(
  client,
  app\_name,
  namespace,
  label\_configmap\_name,
  labels
  )](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#reconcile_charm_labels)
* [class PolicyResourceManager](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policyresourcemanager)
* + [def \_\_init\_\_(
    self,
    charm,
    lightkube\_client,
    labels,
    logger)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policyresourcemanager-__init__)
* + [def reconcile(
    self,
    policies,
    mesh\_type,
    raw\_policies,
    force,
    ignore\_missing)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policyresourcemanager-reconcile)
* + [def delete(
    self,
    ignore\_missing)](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#policyresourcemanager-delete)
* [def get\_data\_from\_cmr\_relation(
  cmr\_relations
  )](https://charmhub.io/istio-beacon-k8s/libraries/service_mesh#get_data_from_cmr_relation)

#### class MeshType

Description

Supported mesh types. None

#### class Method

Description

HTTP method. None

#### class Endpoint

Description

Data type for a policy endpoint. None

#### class PolicyTargetType

Description

Target type for Policy classes. None

#### class Policy

Description

Data type for defining a policy for your charm. None

Methods

Policy.
\_\_init\_\_(

*self*
)

#### class AppPolicy

Description

Data type for defining a policy for your charm application. None

#### class UnitPolicy

Description

Data type for defining a policy for your charm unit. None

#### class MeshPolicy

A Generic MeshPolicy data type that describes mesh policies in a way that is agnostic to the mesh type.

Description

This is also used as the data type for storing service mesh policy information and thereby
defining a standard interface for charmed mesh managed policies.

Methods

#### class ServiceMeshProviderAppData

Description

Data type for the application data provided by the provider side of the service-mesh interface. None

#### class CMRData

Description

Data type containing the info required for cross-model relations. None

#### class ServiceMeshConsumer

Description

Class used for joining a service mesh. None

Methods

ServiceMeshConsumer.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
mesh\_relation\_name: str

,
cross\_model\_mesh\_requires\_name: str

,
cross\_model\_mesh\_provides\_name: str

,
policies

,
auto\_join: bool
)

Class used for joining a service mesh.

Arguments

charm

The charm instantiating this object.

mesh\_relation\_name

The relation name as defined in metadata.yaml or charmcraft.yaml
for the relation which uses the service\_mesh interface.

cross\_model\_mesh\_requires\_name

The relation name as defined in metadata.yaml or
charmcraft.yaml for the relation which requires the cross\_model\_mesh interface.

cross\_model\_mesh\_provides\_name

The relation name as defined in metadata.yaml or
charmcraft.yaml for the relation which provides the cross\_model\_mesh interface.

policies

List of access policies this charm supports.

auto\_join

Automatically join the mesh by applying labels to charm pods.

ServiceMeshConsumer.
update\_service\_mesh(

*self*
)

Update the service mesh.

Description

Gathers information from all relations of the charm and updates the mesh appropriately to
allow communication.

ServiceMeshConsumer.
labels(

*self*
)

Description

Labels required for a pod to join the mesh. None

ServiceMeshConsumer.
enabled(

*self*
)

Description

Return if the consumer is currently in the mesh. None

ServiceMeshConsumer.
mesh\_type(

*self*
)

Description

Return the type of the service mesh. None

ServiceMeshConsumer.
lightkube\_client(

*self*
)

Returns a lightkube client configured for this library.

Description

This indirection is implemented to avoid complex mocking in integration tests, allowing the integration tests to
do something equivalent to:
```python
mesh\_consumer = ServiceMeshConsumer(...)
mesh\_consumer.\_lightkube\_client = mocked\_lightkube\_client

#### class ServiceMeshProvider

Description

Provide a service mesh to applications. None

Methods

ServiceMeshProvider.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
labels

,
mesh\_type: MeshType

,
mesh\_relation\_name: str
)

Class used to provide information needed to join the service mesh.

Arguments

charm

The charm instantiating this object.

labels

The labels which related applications need to apply to use the mesh.

mesh\_type

The type of this service mesh.

mesh\_relation\_name

The relation name as defined in metadata.yaml or charmcraft.yaml
for the relation which uses the service\_mesh interface.

ServiceMeshProvider.
update\_relations(

*self*
)

Description

Update all relations with the labels needed to use the mesh. None

ServiceMeshProvider.
mesh\_info(

*self*
)

Description

Return the relation data that defines Policies requested by the related applications. None

#### def build\_mesh\_policies(     relation\_mapping: RelationMapping,     target\_app\_name: str,     target\_namespace: str,     policies,     cmr\_application\_data )

Generate MeshPolicy that implement the given policies for the currently related applications.

Arguments

relation\_mapping

Charm's RelationMapping object, for example self.model.relations.

target\_app\_name

The name of the target application, for example self.app.name.

target\_namespace

The namespace of the target application, for example self.model.name.

policies

List of AppPolicy, or UnitPolicy objects defining the access rules.

cmr\_application\_data

Data for cross-model relations, mapping app names to CMRData.

#### def reconcile\_charm\_labels(     client: Client,     app\_name: str,     namespace: str,     label\_configmap\_name: str,     labels )

Reconciles zero or more user-defined additional Kubernetes labels that are put on a Charm's Kubernetes objects.

Arguments

client

The lightkube Client to use for Kubernetes API calls.

app\_name

The name of the application (Charm) to reconcile labels for.

namespace

The namespace in which the application is running.

label\_configmap\_name

The name of the ConfigMap that stores the labels.

labels

A dictionary of labels to set on the Charm's Kubernetes objects. Any labels that were previously created
by this method but omitted in `labels` now will be removed from the Kubernetes objects.

Description

This function manages a group of user-defined labels that are added to a Charm's Kubernetes objects (the charm Pods
(via editing the StatefulSet) and Service). Its primary uses are:

* adding labels to a Charm's objects
* updating or removing labels on a Charm's Kubernetes objects that were previously set by this method

To enable removal of labels, we also create a ConfigMap that stores the labels we last set. This way the function
itself can be stateless.

This function takes a little care to avoid removing labels added by other means, but it does not provide exhaustive
guarantees for safety. It is up to the caller to ensure that the labels they pass in are not already in use.

#### class PolicyResourceManager

A Mesh agnostic policy resource manager that manages manifests of different policy manifests in Kubernetes.

Arguments

charm
(ops.CharmBase)

The charm instantiating this object.

lightkube\_client
(lightkube.Client)

Lightkube Client to use for all k8s operations.
This Client must be instantiated with a
field\_manager, otherwise it cannot be used to
.apply() resources because the kubernetes server
side apply patch method requires it. A good option
for this is to use the application name (eg:
`self.model.app.name` or
`self.model.app.name +'_' self.model.name`).

mesh\_type
(charms.istio\_beacon\_k8s.v0.service\_mesh.MeshType)

The type of service mesh for which
the policy resources are to be generated.
(eg: MeshType.istio)

labels
(dict)

A dict of labels to use as a label selector for all resources
managed by this KRM. These will be added to any applied resources at
.apply() time and will be used to find existing resources in
.get\_deployed\_resources().
Recommended input for this is:
labels = {
'app.kubernetes.io/name': f"{self.model.app.name}-{self.model.name}",
'kubernetes-resource-handler-scope': 'some-user-chosen-scope'
}
See `get_default_labels` for a helper to generate this label dict.

logger
(logging.Logger)

(Optional) A logger to use for logging (so that log messages
emitted here will appear under the caller's log namespace).
If not provided, a default logger will be created.

Description

This can be used by the charms to create and manage their own policy resources under circumstances like but not limited to
i. Using Canonical Service Mesh in a non-managed model\_name
ii. Managing highly custom policies that cannot be defined in the ServiceMeshConsumer
iii. Managing authorization policies between charms that are not related to the charmed service mesh's beacon.

The PolicyResourceManager provides a reconcile method that can be used in the charm's own reconciler methods for reconciling
the policies managed by the charm to the desired state.

Methods

PolicyResourceManager.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
lightkube\_client: Client

,
labels

,
logger
)

PolicyResourceManager.
reconcile(

*self*

,
policies

,
mesh\_type: MeshType

,
raw\_policies

,
force: bool

,
ignore\_missing: bool
)

Reconcile the given policies, removing, updating, or creating objects as required.

Arguments

policies

A list of MeshPolicy objects that define the required behaviour of the policy resources.

mesh\_type

The type of service mesh the charm is connected to. This information can be obtained from ServiceMeshConsumer.

raw\_policies

*(optional)* Pre-built policy resources to merge with the built policies.
These must be of supported types (e.g., AuthorizationPolicy for Istio).

force

*(optional)* Passed to self.apply(). This will force apply over any resources
marked as managed by another field manager.

ignore\_missing

*(optional)* Avoid raising 404 errors on deletion (defaults to True)

Description

The MeshPolicy objects are first converted into manifests for Kubernetes policy resources that the
service mesh can understand. eg: AuthorizationPolicy resources for Istio service mesh.

This method will:

* create a list of policy resources containing a policy resource for every provided MeshPolicy object
* optionally merge with raw\_policies (pre-built policy resources provided by the caller)
* get all resources currently deployed that match the label selector in self.labels
* compare the existing resources to the desired resources provided, deleting any resources
  that exist but are not in the desired resource list
* call krm.apply() to create any new resources and update any remaining existing ones to the
  desired state

PolicyResourceManager.
delete(

*self*

,
ignore\_missing
)

Delete all the policy resources handled by this manager.

Arguments

ignore\_missing

*(optional)* Avoid raising 404 errors on deletion (defaults to True)

Description

Requires that self.labels and self.resource\_types be set.

#### def get\_data\_from\_cmr\_relation(cmr\_relations)

Description

Return a dictionary of CMRData from the established cross-model relations. None
