# Cybus Connectware Documentation

Turn fragmented factory data into a unified, governed data foundation — managed as code.

Connectware connects PLCs, sensors, and machines to MES, analytics, AI, and cloud systems through a Unified Namespace (UNS), so you can deploy use cases faster and run reliable operations across all your sites. All connectivity is defined in YAML service commissioning files, versioned in Git, and deployed on Kubernetes or Docker.

## Explore the Documentation

<table data-view="cards"><thead><tr><th align="center"></th><th align="center"></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Discover Connectware</strong></td><td align="center">What Connectware is, how it works, and a hands-on start with a simulated machine.</td><td><a href="/files/kS4BKQVLl5ZnFQlrWRgL">/files/kS4BKQVLl5ZnFQlrWRgL</a></td><td><a href="/pages/AbdIbrcKCZDIdGVPoRHf">/pages/AbdIbrcKCZDIdGVPoRHf</a></td></tr><tr><td align="center"><strong>Deploying Connectware</strong></td><td align="center">Choose your platform, then install, upgrade, and license Connectware on Kubernetes or Docker.</td><td><a href="/files/co1tNi2ufVyV5ReVioH4">/files/co1tNi2ufVyV5ReVioH4</a></td><td><a href="/pages/3TAUy2kRTkhlVMtYxwYg">/pages/3TAUy2kRTkhlVMtYxwYg</a></td></tr><tr><td align="center"><strong>Access &#x26; Security</strong></td><td align="center">Users, roles, and permissions, SSO and MFA, the Client Registry, and TLS certificates.</td><td><a href="/files/AhcJczv4kkcsDDkWWsaW">/files/AhcJczv4kkcsDDkWWsaW</a></td><td><a href="/pages/9GBcYkOpgg4m80X38Mjs">/pages/9GBcYkOpgg4m80X38Mjs</a></td></tr><tr><td align="center"><strong>Building Data Flows</strong></td><td align="center">Services and service commissioning files, the Rule Engine, FlowSync, agents, and the Node-RED Workbench.</td><td><a href="/files/JQap0TsVsV8NtZ3eb6OJ">/files/JQap0TsVsV8NtZ3eb6OJ</a></td><td><a href="/pages/iJlzZfsopeLTyxbY6iU9">/pages/iJlzZfsopeLTyxbY6iU9</a></td></tr><tr><td align="center"><strong>Monitoring</strong></td><td align="center">Verify data flows with the Data Explorer and Live Data, and check system status.</td><td><a href="/files/Nsc34MNv8OAxOOX0WVHQ">/files/Nsc34MNv8OAxOOX0WVHQ</a></td><td><a href="/pages/0lD2MMAsH2LJbiUzlDRQ">/pages/0lD2MMAsH2LJbiUzlDRQ</a></td></tr><tr><td align="center"><strong>Connectors</strong></td><td align="center">Configuration reference for all shop floor and enterprise connectors, from OPC UA to Kafka.</td><td><a href="/files/6F1b8PMOWhgyRRkaylrt">/files/6F1b8PMOWhgyRRkaylrt</a></td><td><a href="/pages/4Ad8cZXYYeKev7ILps1e">/pages/4Ad8cZXYYeKev7ILps1e</a></td></tr><tr><td align="center"><strong>Guides</strong></td><td align="center">Step-by-step guides for machine connectivity, system integrations, and running Connectware at scale.</td><td><a href="/files/eV6rAxPqNrJOKXbJvb1b">/files/eV6rAxPqNrJOKXbJvb1b</a></td><td><a href="/pages/qGw6gnGL2Wx4y3DWoMjN">/pages/qGw6gnGL2Wx4y3DWoMjN</a></td></tr><tr><td align="center"><strong>API Reference</strong></td><td align="center">Automate everything Connectware does through its REST APIs.</td><td><a href="/files/xKiLsOPAPeB2ng8Vzu6S">/files/xKiLsOPAPeB2ng8Vzu6S</a></td><td><a href="/pages/gsEgOfuMeuvzALR9x1Pb">/pages/gsEgOfuMeuvzALR9x1Pb</a></td></tr><tr><td align="center"><strong>Changelog</strong></td><td align="center">New features, improvements, and fixes for every Connectware release.</td><td><a href="/files/jwVol9oiNKYOFW2emzan">/files/jwVol9oiNKYOFW2emzan</a></td><td><a href="/pages/WQsCXfI86SHyPaoQB37K">/pages/WQsCXfI86SHyPaoQB37K</a></td></tr></tbody></table>

## Need Help?

* [Cybus Support Portal](https://support.cybus.io)
* [Contact Cybus](https://www.cybus.io/contact)


# Changelog

Release notes for Connectware and Cybus Helm Charts, including new features, improvements, and bug fixes.

{% hint style="info" %}
Cybus Helm Charts are usually updated alongside a Connectware release. Occasionally, a Helm chart update ships independently to deliver Kubernetes improvements between product versions. See the tags of each changelog to identify whether it applies to <mark style="color:orange;background-color:orange;">Connectware</mark>, <mark style="color:cyan;background-color:cyan;">Cybus Helm Charts</mark>, or both.
{% endhint %}

{% updates format="full" %}
{% update date="2026-07-30" tags="cybus-helm-charts" %}

## Cybus Helm Charts 3.2.0

#### Added

**`connectware` chart**

* Added PodDisruptionBudget to auth-server, nats, resource-status-tracking, topic-explorer and broker workloads.
* Allow using existing ServiceAccounts instead of the RBAC setup orchestrated by the chart.

**`connectware-agent` chart**

* Allow adding additional persistant volume claim templates to agents through `protocolMapperAgentDefaults.extraVolumeClaimTemplates` or `protocolMapperAgents[*].extraVolumeClaimTemplates`.

#### Changed

**`connectware` chart**

* Internally used environment variables `CYBUS_NATS_AUTH_PASSWORD_HASH`, `CYBUS_NATS_SYS_AUTH_PASSWORD_HASH` and `CYBUS_NATS_SYS_PASSWORD_HASH` are now blocked from being set on the NATS StatefulSet by the user.
  {% endupdate %}

{% update date="2026-07-29" tags="connectware" %}

## Connectware 2.5.0

#### Added

**Auth Server**

* Added support for authenticating MQTT clients directly with LDAP credentials. See [Single Sign-On with LDAP](/access/user-management/single-sign-on-sso/sso-with-ldap).

**InfluxDB**

* Added support for InfluxDB 3 via the new `Influxdb3` protocol. See [InfluxDB 3 Support](/connectors/enterprise-connectors/influxdb#influxdb-3-support).

#### Changed

**Admin UI**

* Updated the Admin UI design elements.

**Cybus Helm Charts**

* Updated the `connectware` and `connectware-agent` Helm charts to version 3.1.0 to align with this Connectware release. Chart 3.1.0 contains no changes compared to [3.0.0](#cybus-helm-charts-3.0.0).
  {% endupdate %}

{% update date="2026-07-13" tags="connectware" %}

## Connectware 2.4.2

#### Added

**BACnet**

* Added support for configuring BACnet timing and retry behavior on slow, unreliable, or congested networks via new `Cybus::Connection` properties: `apduTimeoutMs`, `apduRetries`, and `sweepIntervalSeconds`. See [Handling Slow or Unreliable Devices](/connectors/shop-floor-connectors/bacnet#handling-slow-or-unreliable-devices).
* Added experimental support for reaching BACnet/IP devices on remote subnets via the new `bbmd` connection property. Full support is planned for a future release. See [Reaching Devices on Remote Subnets](/connectors/shop-floor-connectors/bacnet#reaching-devices-on-remote-subnets).

**Protocol Mapper**

* Log messages for messages discarded from a [write buffer](/data-flows/service-commissioning-files/resources/cybus-endpoint#buffering) now include the service name and endpoint ID, making it easier to identify which endpoint dropped expired items.

#### Changed

**Cybus Helm Charts**

* Updated the `connectware` and `connectware-agent` Helm charts to version 3.0.1 to align with this Connectware release. Chart 3.0.1 contains no changes compared to [3.0.0](#cybus-helm-charts-3.0.0).

**BACnet**

* The valid range for the `priority` endpoint property on BACnet write operations is now `1`–`16` (previously `0`–`16`). Services that set `priority: 0` are rejected and must be updated before upgrading to Connectware 2.4.2.

#### Fixed

**Admin UI**

* Fixed an issue in the service installation dialog where clearing the service ID field with <kbd>Backspace</kbd> triggered a validation error before the field was fully cleared. The field can now be edited freely, and validation runs on submit.

**Agents**

* Fixed an issue where agents could send progressively more heartbeats after repeated NATS reconnections, occasionally producing `too many requests` warnings.

**Auth Server**

* Improved log messages during PostgreSQL outages so that transient database errors are no longer reported as `username does not exist` during MQTT authorization.

**BACnet**

* Fixed an issue where reading BACnet array properties whose response exceeded a single APDU (\~1476 bytes) failed. The client now detects the oversized response and automatically reads the property in chunks, so large arrays such as `object-list` can be read without any manual configuration.

**Protocol Mapper**

* Fixed an issue where endpoints stopped capturing machine data when the internal broker connection was temporarily lost. Endpoints using `qos: 1` or `qos: 2` now buffer machine data locally until the broker is reachable again, reducing data loss during short CybusMQ outages. See [Connection Loss](/data-flows/agents/troubleshooting-agents#connection-loss).
* Extended write buffering to also engage when a write fails with a timeout or error, not only on a detected disconnection.
* Fixed an issue where a service update could leave a stale endpoint behind, resulting in symptoms such as the endpoint remaining in the `enabling` state or write buffers appearing to hold messages indefinitely. As a side effect, any messages still in a write buffer at the moment of a service update are no longer flushed.
* Fixed a rare case where a mapping using a custom connection could remain partially subscribed after a broker restart. Subscriptions are now reliably re-established on reconnect.

**Service Manager**

* Fixed an issue where installing many services concurrently through the asynchronous deployment endpoint could fail with HTTP 406 or YAML parse errors, or in rare cases produce inconsistent resources. Concurrent installs are now processed in isolation.

#### Removed

**HBM DAQ**

* The Hottinger Baldwin Messtechnik (HBM) DAQ connector (`HbmDaq` protocol) has been removed.
  {% endupdate %}

{% update date="2026-05-26" tags="cybus-helm-charts" %}

## Cybus Helm Charts 3.0.0

This release marks the first standalone update of the Cybus Helm charts, decoupled from the Connectware release cycle. Chart improvements can now ship independently, and you can plan chart and Connectware upgrades on separate schedules. See the [Compatibility Matrix](/cybus-helm-charts/compatibility-matrix) for supported combinations.

Chart 3.0.0 reorganizes the `values.yaml` file for both the `connectware` and `connectware-agent` charts, aligns naming with Kubernetes conventions, and lowers default resource requests to make smaller clusters easier to start with. The agent chart is now embedded as a subchart of the `connectware` chart, replacing the built-in agent templates with the same configuration surface used by standalone agent installations.

{% hint style="warning" %}

#### Upgrade Guide for Cybus Helm Charts 3.0.0

This release introduces breaking changes to `values.yaml` and requires manual upgrade steps. For detailed instructions, see [Upgrading connectware and connectware-agent Helm Charts to 3.0.0](/deployment/upgrading-connectware/on-kubernetes/helm-charts-to-3-0-0).
{% endhint %}

#### Added

**`connectware` and `connectware-agent` charts**

* Both charts now enforce a minimum required Connectware image version. Installs fail if the image tag is below this minimum, protecting against incompatible chart and Connectware version combinations. Custom registries and non-semver tags are not checked to allow custom use cases.
* Added `validVersion` as an opt-in Helm value. When set, the install fails unless the value matches the deployed chart version, protecting against mismatched chart and `values.yaml` combinations. See [Locking Helm Chart Version in values.yaml](/cybus-helm-charts/working-with-cybus-helm-charts/locking-chart-version).
* Each component now accepts `extraContainers` and `extraInitContainers` Helm values to inject sidecar or init containers into the workload, as well as `extraVolumes` and `extraVolumeMounts` Helm values to mount additional volumes. See [Adding Sidecars and Volumes](/cybus-helm-charts/working-with-cybus-helm-charts/adding-sidecars-and-volumes), as well as [Adding Init Containers](/cybus-helm-charts/working-with-cybus-helm-charts/adding-init-containers).
* Added `podPriorityClassName` Helm value, globally and per component, to assign a Kubernetes PriorityClass to the workload pods. See [Pod Priority Classes](/cybus-helm-charts/working-with-cybus-helm-charts/pod-priority-classes).
* Added `nodeSelector` Helm value, globally and per component, to constrain pods to nodes matching the given labels. See [Kubernetes Scheduling](/cybus-helm-charts/working-with-cybus-helm-charts/kubernetes-scheduling).
* Added `tolerations` Helm value, globally and per component, to schedule pods onto nodes with matching taints. See [Kubernetes Scheduling](/cybus-helm-charts/working-with-cybus-helm-charts/kubernetes-scheduling).

**`connectware` chart**

* The `connectware-agent` chart is now embedded as a subchart, replacing the built-in `global.protocolMapperAgents` templates. Users gain access to the `protocolMapperAgentDefaults` block to share values across agents, as was already possible with the standalone `connectware-agent` chart. See [Deploying Agents with Your Connectware Installation](/data-flows/agents/agents-in-kubernetes/deploying-agents-with-your-connectware-installation).
* Added [Helm values for MFA issuer and label](/access/user-management/multi-factor-authentication) (`global.authentication.mfa.issuer`, `global.authentication.mfa.label`). The equivalent environment variables `CYBUS_MFA_ISSUER` and `CYBUS_MFA_LABEL` are now blocked; use these Helm values instead.
* The [license key](/deployment/installing-connectware/on-kubernetes#method-2---kubernetes-secret), [license file](/deployment/installing-connectware/offline-on-kubernetes#providing-the-offline-license-details), [admin user](/access/user-management/users/default-admin-user#using-an-existing-kubernetes-secret-for-the-initial-admin-password-kubernetes-only), and [broker cluster secret](/deployment/installing-connectware/on-kubernetes#method-3---existing-kubernetes-secret) can now each be sourced from a pre-existing Kubernetes Secret, improving the GitOps-style deployment experience.
* The `connectwareIngress.service` block now accepts additional configuration: `type`, `ports`, `loadBalancerIP`, `loadBalancerClass`, `clusterIP`, and `externalTrafficPolicy`.
* Added `toolkit.enabled` to opt into deploying the Connectware toolkit container for debugging.
* Auth-server now defaults to two replicas for improved availability. Set `authServer.replicas: 1` to keep the previous single-replica behavior.
* The `broker` and `nats` components now accept an `extraVolumeClaimTemplates` Helm value to add custom StatefulSet volume claim templates.
* Added `global.initContainerSecurityContextOverride` to set the [security context for init containers](/cybus-helm-charts/working-with-cybus-helm-charts/overriding-security-contexts#configuring-a-global-security-context-override) across all components. By default, init containers inherit the effective `containerSecurityContext`.
* Added a headless Service for the CybusMQ broker. Cluster nodes now discover each other through stable DNS records, improving cluster formation and resilience under pod restarts.
* The `global.proxy` settings can now be overridden per component on `authServer.proxy` and `systemControlServer.proxy`. Use these overrides to route only specific components through a different HTTP proxy.

**`connectware-agent` chart**

* Added `existingAgentPasswordSecret` for managing the agent password through a pre-existing Kubernetes Secret.
* StatefulSets now set `persistentVolumeClaimRetentionPolicy` to `Retain` for both `whenDeleted` and `whenScaled`, so PersistentVolumeClaims survive scale-down and StatefulSet deletion on Kubernetes 1.32 and later on clusters where the default behavior is changed.

#### Changed

**`connectware` and `connectware-agent` charts**

* Charts are now distributed via an [OCI registry](https://helm.sh/docs/topics/registries/) at `oci://repo.cybus.io` instead of a Helm chart repository. Chart versions are pulled by exact tag, removing the need to manage a registered repo or run `helm repo update`. For offline installations, charts and container images can now be [mirrored to the same registry](/cybus-helm-charts/working-with-cybus-helm-charts#copying-a-helm-chart-to-a-custom-registry).
* Chart versioning is now decoupled from Connectware versioning. Chart upgrades and Connectware upgrades can be planned independently. See [Compatibility Matrix](/cybus-helm-charts/compatibility-matrix).
* Helm 4 is now required.
* Kubernetes 1.25 or later is now required. The chart does not deploy on older versions.
* Security context values no longer merge with chart defaults. The new keys `podSecurityContextOverride` and `containerSecurityContextOverride` fully replace the defaults when set. Either omit them to keep the defaults, or provide a complete security context with all fields you want applied. There is no partial override. See [Overriding Security Contexts](/cybus-helm-charts/working-with-cybus-helm-charts/overriding-security-contexts).
* Default compute resources have been adjusted: CPU and memory requests are reduced for most components and agents, and default resource limits have been removed. Lower defaults make it easier to get started on smaller clusters. For production workloads, set explicit `resources` values. If you are unsure about what values are required for your installation, see [Right-Sizing Kubernetes Resources for Connectware](/guides/operations/right-sizing-kubernetes-resources).

**`connectware` chart**

* Component configuration blocks (`adminWebApp`, `authServer`, `broker`, `containerManager`, `ingressController`, `nats`, `postgresql`, `protocolMapper`, `resourceStatusTracking`, `serviceManager`, `systemControlServer`, `topicExplorer`, `workbench`) have moved from `global.*` to the top level, following Helm best practices.
* `global.ingress` is now `connectwareIngress`, and its Deployment is renamed from `connectware` to `connectware-ingress`. The new name conveys more clearly that the component is an ingress proxy for Connectware, distinct from a Kubernetes Ingress.
* `global.userManagement` is merged into `global.authentication`. `global.userManagement.adminUser.initialPassword` becomes `global.authentication.adminUser.initialPassword` and now [accepts plain text instead of base64](/access/user-management/users/default-admin-user#admin-user-parameters-kubernetes).
* `global.authentication.adminUser.enabled` is now a boolean instead of the strings `"true"`/`"false"`.
* `storage` blocks are renamed to `persistence` across the chart. This affects `global.storage` → `global.persistence` and the per-component blocks on `broker`, `nats`, `postgresql`, `systemControlServer`, and `workbench`. Inner keys (`size`, `storageClassName`, `data`, `log`, `accessMode`) are unchanged.
* Keys with initialisms now use uppercase to align with Kubernetes conventions (`ingressDnsNames` → `ingressDNSNames`, `postgresql.persistence.preprovisionedNfs` → `postgresql.persistence.preprovisionedNFS`).
* Resource limits and requests are now configured directly on each component. The `global.podResources.*` block has been removed.
* Several CybusMQ broker keys were renamed or retyped: `replicaCount` → `replicas`, `messageQueueSize` → `onlineMessageQueueSize`, and the `allowRegisterDuringClusterFormation`, `allowPublishDuringClusterFormation`, `allowSubscribeDuringClusterFormation`, and `allowUnsubscribeDuringClusterFormation` keys now take booleans instead of `"on"`/`"off"` strings.
* The CybusMQ broker cluster secret now supports three options: leave `broker.clusterSecret` empty (`""`) to let Helm auto-generate the secret at install time, set the new `broker.existingClusterSecret` to reference a pre-existing Kubernetes Secret, or keep providing the literal secret string in `broker.clusterSecret`. See [Specifying the Broker Cluster Secret](/deployment/installing-connectware/on-kubernetes#specifying-the-broker-cluster-secret).
* The `nats.metrics.prometheus` intermediate block is removed. All configuration (`enabled`, `resources`, `serviceMonitor.*`) now lives directly under `nats.metrics.*`.
* `global.image.version` is renamed to `global.image.tag` to match the Kubernetes convention. The value controls the container image tag, not necessarily a version.
* `global.licensekey` is renamed to `global.licenseKey`. Custom registry users are now configured by [referencing a pull secret](/cybus-helm-charts/working-with-cybus-helm-charts/registries-and-pull-secrets#configuring-pull-secrets) through `global.image.pullSecrets` because `global.registryUser` is removed.
* Workloads now carry the standard `app.kubernetes.io/name=<component>` label instead of the short `app=<component>` label. This aligns with the [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) and matches the `connectware-agent` chart.
* The `connectware` LoadBalancer Service no longer exposes ports `40000` to `40009` by default. If you use `Cybus::IngressRoute` resources of type `tcp`, add the required ports to `connectwareIngress.service.ports`. See [Configuring the Load Balancer for the connectware Helm Chart](/cybus-helm-charts/connectware-helm-chart/load-balancer).
* The Kubernetes RBAC Role `pod-manager` is replaced with a new role with read-only access. The role is no longer bound to the default ServiceAccount; the chart now creates a dedicated ServiceAccount, which is used exclusively by the `container-manager` workload.

**`connectware-agent` chart**

* The chart now strips reserved environment variables (`CYBUS_AGENT_MODE`, `CYBUS_AGENT_NAME`, `CYBUS_HOSTNAME_INGRESS`, `CYBUS_PROTOCOL_MAPPER_PASSWORD`, `CYBUS_USE_MUTUAL_TLS`, and any name starting with `CYBUS_DATAPLANE_` or `CYBUS_STREAMSERVER_`) from any `env` list. Agent identity, connectivity, and security can no longer be silently misconfigured. Dedicated Helm values are provided for each of these settings, unless they are automatically computed.
* The deprecated `mTLS.caChain.*` path has been removed. Use `tls.ca.*` instead. See [Configuring CA Certificate Chain for Agents with the connectware-agent Helm Chart](/cybus-helm-charts/connectware-agent-helm-chart/ca-certificate-chain).
* The auto-generated image pull secret is renamed from `<release>-cybus-docker-registry` to `<release>-image-registry`.

#### Removed

**`connectware` chart**

* `global.setImmutableLabels` has been removed. Labels on immutable objects are now always set.
* `global.loadBalancer.metalLB.addressPoolName` has been removed. Configure MetalLB through annotations on `connectwareIngress.service.annotations` instead.
  {% endupdate %}

{% update date="2026-06-02" tags="connectware" %}

## Connectware 2.4.1

#### Fixed

**Protocol Mapper**

* Fixed an edge case where a buffered write endpoint prevented the buffer from being flushed.
  {% endupdate %}

{% update date="2026-05-20" tags="connectware" %}

## Connectware 2.4.0

{% hint style="warning" %}

## Upgrade Guide for Connectware 2.4.0

If you are using the OPC UA Server with a custom PKI, you must update your service commissioning files after upgrading. If you do not use the OPC UA Server, no action is required.

For detailed instructions, see:

* [Upgrading Connectware to 2.4.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-4-0-on-kubernetes)
* [Upgrading Connectware to 2.4.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-4-0-on-docker)
  {% endhint %}

#### Added

**Services**

* Updated the Node.js version on the majority of Node-based Connectware services.

**OPC UA Server**

* Added the [caFile](/connectors/servers/opc-ua-server/opcuaserver#cafile-string) property, allowing you to specify the path to a custom CA certificate file instead of placing it manually in the OPC UA server's trusted certificates directory. See [CA Certificate](/connectors/servers/opc-ua-server#ca-certificate) for more information.

**Admin UI**

* Refreshed icons, typography, side navigation, and the color palette across the Connectware user interface.

#### Fixed

**OPC UA**

* Fixed an issue where OPC UA method calls did not accept the `{"value": <value>}` input argument format.
  {% endupdate %}

{% update date="2026-05-15" tags="connectware" %}

## Connectware 2.3.1

#### Added

**CybusMQ**

* CybusMQ now processes subscribe and unsubscribe requests in batches, significantly reducing authorization, storage, and replication overhead for clients with large numbers of subscriptions.

#### Fixed

**CybusMQ**

* Fixed an edge case where synchronous subscribe handling could freeze client sessions during broker restarts, using a secondary detection mechanism to avoid waiting on unavailable nodes.
* Fixed an edge case where a hanging TCP connection from a crashed server blocked connections from the new instance; old nodes are now automatically cleaned up on detection.
* Metadata store sync timeouts between broker nodes now detect peer failures significantly faster.
  {% endupdate %}

{% update date="2026-04-02" tags="connectware" %}

## Connectware 2.3.0

#### Added

**Modbus/TCP**

* Added batch processing support for Modbus read requests via the new `batchReadEnabled` and `maxBatchSize` connection parameters. Connectware can now group multiple read requests into fewer, larger ones, reducing communication overhead with the device. For more information, see [Batch Read Processing](/connectors/shop-floor-connectors/modbus-tcp#batch-read-processing).

**BACnet**

* Added support for the `multi-state-value` object type in [BACnet Endpoint Properties](/connectors/shop-floor-connectors/bacnet/bacnetendpoint).

#### Fixed

**CybusMQ**

* Fixed MQTT5 subscribe authorization not being enforced correctly in certain cases.
* Fixed an issue where internal broker cluster connections could drop under certain network conditions.

**Services**

* Fixed an issue where Connectware could become unresponsive during startup under heavy system load, preventing agents from connecting.
* Fixed an issue where the startup script produced a corrupted TLS certificate file (`cybus_combined_ca.crt`) on Azure File volumes, which could cause TLS failures.
* Fixed an issue where resources with `targetState: disabled` in service commissioning files were incorrectly shown as deviated.
* Fixed an issue where Connectware could permanently fail to reconnect to internal services after a restart if the messaging layer was temporarily unavailable. Connectware now retries indefinitely with increasing intervals between attempts.

**BACnet**

* Fixed an issue where certain BACnet data requests were incorrectly reported as device connectivity errors. These failures are now logged with a specific message to aid diagnosis.

**Admin UI**

* Fixed an issue where the role search field in the **Create User** and **Edit User** dialogs did not accept multi-character input.
* Fixed an issue where valid login requests to the Admin UI could intermittently fail, particularly when multiple requests were processed in parallel.
  {% endupdate %}

{% update date="2026-03-03" tags="connectware" %}

## Connectware 2.1.2

#### Added

**Reliability & Robustness**

* Added optional message buffering for MQTT connections using persistent sessions with QoS 1 or QoS 2. The new `messageBufferWindowMs` and `maxBufferedMessages` properties prevent message loss during endpoint reconstruction after reconnect. For more information, see [Configuring Message Buffering](/connectors/enterprise-connectors/mqtt#configuring-message-buffering).
  {% endupdate %}

{% update date="2026-02-26" tags="connectware" %}

## Connectware 2.1.1

#### Fixed

**Reliability & Robustness**

* Fixed an issue where the BACnet, FOCAS, and S7+ protocols could fail to start correctly after upgrading to 2.1.0.
* Fixed an issue that prevented the BACnet, FOCAS, and S7+ protocols from running concurrently within the same protocol mapper instance. These protocols can now be used in parallel as intended.
  {% endupdate %}

{% update date="2026-02-23" tags="connectware" %}

## Connectware 2.1.0

Connectware 2.1.0 introduces support for the Siemens SIMATIC S7+ protocol and OPC UA complex data types. It also reintroduces service-level tracking for the Systemstate protocol, offering improved performance. Furthermore, it provides significant enhancements to resource deviation tracking and OPC UA reliability. See below for a complete list of changes.

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.1.0

This release includes an optional cleanup step to reclaim disk space from the deprecated `resourceStates` NATS bucket.

For detailed instructions, see:

* [Upgrading Connectware to 2.1.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-1-0-on-kubernetes)
* [Upgrading Connectware to 2.1.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-1-0-on-docker)
  {% endhint %}

#### Added

**Innovation & Enhancement**

* Added support for the Siemens SIMATIC S7+ protocol. For more information, see [Siemens SIMATIC S7+](/connectors/shop-floor-connectors/siemens-simatic-s7-plus).
* Added support for OPC UA complex data types, enabling the protocol-mapper to handle more sophisticated data structures and expanding its applicability to a wider range of use cases. For more information, see [Complex Data Types](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#complex-data-types).
* Added service-level tracking to the System State protocol. For more information, see [Systemstate](/connectors/enterprise-connectors/systemstate).
* [Systemstate](/connectors/enterprise-connectors/systemstate) instances are now managed by a centralized microservice, enabling reliable tracking of large-scale deployments with improved performance.

**Reliability & Robustness**

* Resource deviation tracking has been optimized to provide higher accuracy, reliability, and resilience during peak load scenarios or infrastructure issues. Deviation state traffic has been reduced by 50%.
* Added the `CYBUS_RESOURCE_CATEGORIES_GRAPH_ENDPOINTS_DEPEND_ON_MAPPINGS` environment variable to configure the resource deployment order of endpoints and mappings. For more information, see [Environment Variables](/reference/environment-variables).

#### Fixed

**Security & Stability**

* Fixed a race condition that could cause an older resource state to overwrite a newer one.
* Fixed MQTT connections to correctly create a secure context even when a CA certificate is not provided.

**Reliability & Robustness**

* **BACnet**
  * Fixed an edge case where BACnet connections did not recover automatically after connection loss.
* **OPC UA**
  * Fixed subscriptions failing when multiple endpoints reference the same nodeId.
  * Fixed memory leak caused by frequent re-subscription attempts for non-existent nodeIds.
  * Fixed event subscriptions creating infinite retry loops due to `BadTooManyMonitoredItems` errors, preventing monitored items from accumulating on the PLC.
    {% endupdate %}

{% update date="2026-01-28" tags="connectware" %}

## Connectware 2.0.6

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.0.6 (Kubernetes only)

If you are running Connectware on Kubernetes, you must follow a specific upgrade guide. For detailed instructions, see:

* [Upgrading Connectware to 2.0.6 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-6-on-kubernetes)
  {% endhint %}

#### Fixed

**Reliability & Robustness**

* Systemstate: Fixed an issue with Systemstate functionality on agents.
  {% endupdate %}

{% update date="2026-01-27" tags="connectware" %}

## Connectware 2.0.5

This release brings significant improvements to OPC UA reliability and CybusMQ performance, reducing message loss and improving system stability under load.

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.0.5

This upgrade requires you to delete the data volumes that store the metadata of CybusMQ.

For detailed instructions, see:

* [Upgrading Connectware to 2.0.5 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-5-on-kubernetes)
* [Upgrading Connectware to 2.0.5 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-5-on-docker)
  {% endhint %}

#### Added

**Reliability & Robustness**

* **OPC UA**
  * Reduced overall OPC UA message volume to lower server-side stress and improve performance.
  * Improved OPC UA monitoring behavior to prevent potential message loss.
* **CybusMQ**
  * Added synchronous subscription handling to CybusMQ to prevent potential message loss and out-of-memory issues.

#### Fixed

**Reliability & Robustness**

* **OPC UA**
  * Fixed potential loss of initial value updates for OPC UA subscription endpoints.
  * Fixed potential protocol-mapper crash after connection loss to OPC UA servers.
  * Restored OPC UA event functionality that was not working correctly.
  * Read and write endpoints no longer send unnecessary monitoring requests.
  * Fixed issues after reconnect that could lead to incorrect connection states and message loss.
* **CybusMQ**
  * Fixed metadata store issues to prevent unnecessary CPU and memory usage.
  * Fixed webhook caching issues to prevent unnecessary CPU and memory usage.

#### Changed

* **CORS Policy**
  * The HTML5 cross-origin resource sharing (CORS) policy is now disabled for all services except the Node-RED Workbench. This update enhances security by restricting cross-origin requests.
  * To also disable CORS for the [Node-RED Workbench](/data-flows/node-red-workbench), you must manually remove permissions for its HTTP endpoints. Remove permissions for `/workbench` and `/workbench/#` from all users and roles. For detailed instructions, see [Removing Permissions from Roles](/access/user-management/roles#removing-permissions-from-roles) and [Removing Permissions from Users](/access/user-management/users#removing-permissions-from-users).
    {% endupdate %}

{% update date="2025-12-10" tags="connectware" %}

## Connectware 2.0.4

#### Added

**Maintenance & Adaptability**

* Connectware's MQTT server now automatically identifies whether a connection uses [TLS and mutual TLS](/access/security/tls-certificates) based on the provided client certificate. The `CYBUS_BROKER_USE_MUTUAL_TLS` environment variable has been removed.
  {% endupdate %}

{% update date="2025-11-24" tags="connectware" %}

## Connectware 2.0.3

#### Added

**Security & Stability**

* Administrators can now define how long a user stays signed in before being logged out for security reasons. For more information, see [User Session Expiration](/access/user-management/users/user-session-expiration).

**Usability & Accessibility**

* The values of the HTTP connection parameters `agentOptions` and `requestTimeout` are now displayed in the [Configuration tab](/data-flows/services/service-resources-view/connections-view#configuration) of the **Connections** view.

#### Removed

* The Backup & Restore view has been removed from the Admin UI.
  {% endupdate %}

{% update date="2025-11-03" tags="connectware" %}

## Connectware 2.0.2

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.0.2

Connectware 2.0.2 introduces new configuration options for HTTP connections.

After upgrading to Connectware 2.0.2, you must apply the new HTTP connection options to existing services. To do so, [disable](/data-flows/services/managing/disabling) and re-[enable](/data-flows/services/managing/enabling) each affected service after upgrading.
{% endhint %}

#### Added

**Reliability & Robustness**

* New [HTTP connection parameters](/connectors/enterprise-connectors/http-rest/httpconnection) (`maxSockets`, `maxFreeSockets`, `timeout`, `keepAliveMsecs`) allow you to customize agent options and request timeouts directly in the service commissioning file. Newly installed HTTP-based services automatically use the new default values unless overridden. If you want to use the new configuration parameters for existing services, [disable](/data-flows/services/managing/disabling) and re-[enable](/data-flows/services/managing/enabling) each affected service after upgrading. For more information, see [HTTPS Agent and Socket Management](/connectors/enterprise-connectors/http-rest#https-agent-and-socket-management).
* All Axios-based HTTP operations use a default `requestTimeout` value of 10000 ms (10 s). This configuration ensures that requests terminate if the target server does not respond within the specified time frame, improving reliability and preventing indefinitely hanging requests. For more information, see [Controlling How Long Requests Wait for a Response](/connectors/enterprise-connectors/http-rest#controlling-how-long-requests-wait-for-a-response).

**Performance & Scalability**

* [CybusMQ](/broker/cybusmq): Reduced memory usage when clients subscribe or unsubscribe from topics.
  {% endupdate %}

{% update date="2025-10-14" tags="connectware" %}

## Connectware 2.0.1

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.0.1

Connectware 2.0.1 introduces enhancements to the Data Explorer. If you are running services that are configured with `CYBUS_MQTT_ROOT`, this upgrade requires you to run a migration script to populate missing database entries.

Additionally, Connectware 2.0.1 adds a new microservice for MQTT topic exploration. As a result, Connectware requires more resources.

For more information, see the 2.0.1 upgrade guide:

* [Upgrading Connectware to 2.0.1 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-1-on-kubernetes)
* [Upgrading Connectware to 2.0.1 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-1-on-docker)
  {% endhint %}

#### Added

**Reliability & Robustness**

* Subscribe endpoints now enter an `Enabling` state during temporary OPC UA node unavailability until the connectivity is restored.

**Usability & Accessibility**

* System-level topics are now filtered out from the [Data Explorer](/monitoring/data-explorer).
* The Data Explorer now uses the new [Topic Explorer API](/reference/api-reference/topic-explorer-api) service to retrieve topics for resources.

#### Fixed

**Reliability & Robustness**

* Resolved an issue where OPC UA servers and nodes failed to initialize correctly when the server's resource name differed from the default `opcuaServer` value.
* Agent-to-Connectware version compatibility verification has been reinstated.
  {% endupdate %}

{% update date="2025-09-05" tags="connectware" %}

## Connectware 2.0.0

Connectware has always been built for reliability in production environments — with version 2.0.0, that foundation has been significantly reinforced. The platform now runs on a rearchitected core with isolated microservices, ensuring failures remain contained. A simplified control plane and new Service Manager reduce operational complexity, while PostgreSQL and NATS provide a robust backbone for consistent state management and communication.

The major advancement: Connectware now scales from tens of thousands of resources to millions, with verified throughput of 1 billion data points per hour. Recovery from failures is faster and deterministic, ensuring continuous data integrity even under heavy load. Smaller deployments also gain clear benefits: shorter startup times, more consistent logging, and automated service recovery reduce manual effort in daily operations.

Across all environments, the event-driven design makes the system easier to maintain, extend, and troubleshoot — establishing a resilient platform, there to support the journey of your factory data integration.

{% hint style="warning" %}

#### Upgrade Guide for Connectware 2.0.0

This release requires manual upgrade steps.

* [Upgrading Connectware to 2.0.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes)
* [Upgrading Connectware to 2.0.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker)
  {% endhint %}

#### Added

**Security & Stability**

Highlights

* Improved security due to a more strict TLS verification by the Connectware Agents. See [TLS Changes (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes#1-tls-changes) and [TLS Changes (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker#1-tls-changes).
* Deterministic state recovery. Lost messages and corrupted states eliminated.

Technical changes

* TLS trust enforced by default; self-signed certificates rejected unless explicitly configured.
* Default user/group is only created when the service commissioning file uses the parameter `Cybus::MqttUser`.

**Performance & Scalability**

Highlights

* Capacity increased from \~50,000 to 3M+ resources.
* Verified throughput of 1 billion data points/hour.
* Also small deployments run with lower latency and higher stability.
* Progressive service deployment for Connectware agents to stagger startup fetches after restarts, reducing load spikes on large deployments. See [Progressive Service Deployment](/data-flows/agents/configuring-agents/progressive-service-deployment).

Technical changes

* Services and resources are no longer stored on the service-manager volume, but inside the PostgreSQL database.
* Service state is decoupled from startup behavior.

**Usability & Accessibility**

Highlights

* Unified MQTT topic structure simplifies automation scripts with stable, consistent naming. See [Auto-Generated MQTT Topics of Resources (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes#6-auto-generated-mqtt-topics-of-resources) and [Auto-Generated MQTT Topics of Resources (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker#6-auto-generated-mqtt-topics-of-resources).
* Added **Deviated Services** view in the left sidebar of the Services section to easily check for deviated services. See [Deviations](/data-flows/services/deviations).

Technical changes

* MQTT topics standardized to `<Cybus::MqttRoot>/<serviceId>/<resourceName>`.
* You may need to update your service commissioning files if they relied on literal references to previously auto-generated topics.

**Maintenance & Adaptability**

Highlights

* Event-driven architecture (CQRS, event sourcing) ensures maintainability and extensibility.
* New control plane improves developer workflows and debugging.
* Improved Custom Connectors reliability. See [Custom Connectors (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes#2-custom-connectors) and [Custom Connectors (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker#2-custom-connectors).

Technical changes

* Control plane broker removed, simplifying deployments.
* VRPC fully removed across Protocol Mapper (and agents), Service Manager, Container Manager, System Control Server, and Admin UI.
* NATS introduced to transport and store control plane information.

**Monitoring & Resilience**

Highlights

* Retry logic, correlation IDs, and transparent logging improve troubleshooting.

Technical changes

* Expanded logging across components.
* Improved observability in the control plane.

**Reliability & Robustness**

Highlights

* Fault isolation: Microservices are \~90% independent, reducing failure impact.
* Deterministic state recovery across all deployments.
* OPC UA: Optional override the [change-of-value (COV)](/data-flows/rule-engine/data-processing-rules#cov) filter to enforce interval-based updates. This ensures predictable, time-synchronized delivery, even when values do not change. Introduces new OPC UA endpoint parameters: `trigger`, `deadbandType`, `deadbandValue`. See [OPC UA Endpoint Properties](/connectors/shop-floor-connectors/opc-ua/opc-ua-client/opcuaendpoint#trigger-string-enum).

#### Technical Changes

* JSONata rules are validated during service installation. See [Installing Services](/data-flows/services/managing/installing).
* Services with missing dependencies (child service without a parent service) can be installed but not enabled until all parent services (dependencies) are enabled. See [Inter-Service Referencing](/data-flows/services/inter-service-referencing#service-dependency-behavior).
* Installing a service with the same ID as a deleted service is now prevented for 5 seconds. This delay can be configured via the `CYBUS_SERVICE_REINSTALL_DELAY_SECONDS` environment variable. See [Deleting Services](/data-flows/services/managing/deleting).
* [Data Explorer](/monitoring/data-explorer): MQTT topics in are currently only shown if they have at least one active subscription. Additionally, topics that are not linked to a Connectware resource are now visible.
  {% endupdate %}
  {% endupdates %}

## Version History

<details>

<summary>Connectware 1.11.0</summary>

## What has changed in 1.11.0?

{% hint style="warning" %}
We have identified a critical bug in this release. Please do not upgrade to 1.11.0. We are working on a fix that will be released soon.
{% endhint %}

**Release date:** 06.03.2025

Connectware 1.11.0 represents a major step in our comprehensive architecture evolution to deliver long-term benefits in performance, scalability, and maintainability.

However, version 1.11.0 is not intended for production use.

**Who should install Connectware 1.11.0?**

Only those who have been directly advised to do so by our Customer Success team.

For most implementations, we strongly recommend continuing to use Connectware 1.10.1 until the architecture update is completed in a future Connectware release.

{% hint style="warning" %}

#### Upgrade Guide for Connectware 1.11.0

This release includes breaking changes and requires manual upgrade steps. Upgrade to Connectware 2.0.0, which will also require manual upgrade steps. In case of questions, our Customer Success team is able to advise you.

* [Upgrading Connectware to 2.0.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes)
* [Upgrading Connectware to 2.0.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker)
  {% endhint %}

#### Added

**Performance & Scalability**

* Introduces two new microservices (`resource-status-tracking` and `nats`) for Resource Status Tracking to provide more reliable tracking of Cybus resources at larger scales, with both HTTP and websocket API support.
* CybusMQ: Enhanced message routing scalability following cluster reception.

**Maintenance & Adaptability**

* Updated the Connectware Toolkit Container to the latest version.

**Reliability & Robustness**

* Integrated NATS streaming broker to support Connectware's new Control Plane technology.

</details>

<details>

<summary>Connectware 1.10.0 – 1.10.2</summary>

## What has changed in 1.10.0?

**Release date:** 14.01.2025

#### Added

**Security & Stability:**

* Added [Microsoft Entra ID](/access/user-management/single-sign-on-sso/sso-with-microsoft-entra-id) support for single sign-on authentication in Connectware.

## What has changed in 1.10.1?

**Release date:** 27.01.2025

#### Added

**Security & Stability:**

* New [environment variable](/reference/environment-variables): `CYBUS_SENSITIVE_ENVIRONMENT_VARIABLES` allows you to specify the environment variable names that must be hidden when container data is sent to a client.
* New [environment variable](/reference/environment-variables): `CYBUS_ALLOW_INSECURE_TLS_CIPHERS` allows you to control the use of insecure Transport Layer Security (TLS) cipher suites in Connectware.

**Reliability & Robustness:**

* Enhanced the speed and stability of service installations that involve multiple endpoints.

#### Fixed

**Security & Stability:**

* Token redirects now only work for Connectware related sites to improve [JSON Web Token](/access/security/json-web-tokens) security.
* Enhanced LDAP authorization security by improving wildcard handling.
* Improved the reliability of agent reconnection processes.

**Usability & Accessibility:**

* Improved error messages for failed login attempts with the same username for Entra ID and local.
* **MFA Usage Mandatory** button will not be shown when [multi-factor authentication](/access/user-management/multi-factor-authentication) is disabled.

**Reliability & Robustness**

* Made FlowSync more resilient to configuration errors.

## What has changed in 1.10.2?

**Release date:** 25.04.2025

#### Fixed

**Reliability & Robustness**

* OPC UA connections are now reliably restored after a connection loss, ensuring higher robustness in continuous operations.

#### Added

**Security & Stability:**

* Mandatory security mode for user authentication:
  * Clients connecting to an OPC UA server with user credentials (username/password) must now use a security mode.
  * This change enhances communication security and aligns with updated OPC UA library requirements.

</details>

<details>

<summary>Connectware 1.9.0</summary>

## What has changed in 1.9.0?

**Release date:** 11.12.2024

#### Added

**Reliability & Robustness:**

* Introduced [FlowSync](/data-flows/flowsync) for advanced message synchronization.

**Usability & Accessibility:**

* Support for OPC UA methods for nodes and endpoints.
* Updated [Live Data](/monitoring/live-data) view to support nodes that do not contain topics.

#### Fixed

**Usability & Accessibility:**

* Fixed Rule Sandbox issue.

</details>

<details>

<summary>Connectware 1.8.0</summary>

## What has changed in 1.8.0?

**Release date:** 13.11.2024

#### Added

**Security & Stability:**

* The license ID is now hidden by default to improve security.

**Usability & Accessibility:**

* Users with restricted **Data Explorer** permissions will see a notification that guides them to the **Service Details View**, where they can select a service to explore its live data.
* The Connectware documentation has been redesigned for better usability and an improved user experience. It is now available exclusively at [docs.cybus.io](https://docs.cybus.io/) and is no longer included in the Connectware installation package. Documentation for Connectware 1.7.3 and prior remains available at [docs-old.cybus.io](https://docs-old.cybus.io/).
* Documentation links in Connectware now direct to the online documentation at [docs.cybus.io](https://docs.cybus.io/).

**Monitoring & Resilience:**

* Added a new **Live Data** tab in the **Service Details View** that shows live data for each service. See [Live Data](/monitoring/live-data).
* The **Service Details View** and the tabs for **Mappings**, **Connections**, and **Endpoints** now show to which agent the resource is assigned to. See [Services Overview](/data-flows/services/service-overview).

#### Fixed

**Security & Stability:**

* Fixed an issue where required permissions for auth/mfa were missing when multi-factor authentication (MFA) was enforced during login.

**Usability & Accessibility:**

* Fixed an incorrect permissions changed popup that appeared for users with minimum access on the **Service Details View**.

**Reliability & Robustness:**

* Fixed an issue where Kafka producer and consumer connections became inconsistent after losing network connection to the broker.

</details>

<details>

<summary>Connectware 1.7.0 – 1.7.3</summary>

## What has changed in 1.7.0?

For Connectware 1.7.0, we’ve improved the performance and stability of CybusMQ.

As part of these improvements, older broker data volumes are not compatible with brokers of Connectware 1.7.0 and newer. To successfully upgrade to Connectware 1.7.0 or later, you’ll need to follow some additional update procedures.

{% hint style="warning" %}

#### Upgrade Guide for Connectware 1.7.0

This release requires manual upgrade steps. Read the following Connectware 1.7.0 Upgrade Guide carefully:

* [Upgrading Connectware to 1.7.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-1-7-0-on-kubernetes)
* [Upgrading Connectware to 1.7.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-1-7-0-on-docker)
  {% endhint %}

#### Added

**Security & Stability:**

* CybusMQ now uses an upgraded Debian Linux 11.9

**Performance & Scalability:**

* Improved CybusMQ cluster’s metadata replication performance
* Optimized image size of CybusMQ
* Service manager can now allocate up to 16GB of RAM as potentially required for large deployments

**Usability & Accessibility:**

* Admin UI: Added column in users overview table that shows if multi-factor authentication (MFA) is enabled or not
* Admin UI: MFA options are now hidden for users if MFA is not enabled
* Admin UI: Users are now automatically notified when the administrator enforces MFA or changes user permissions
* Admin UI: Added notification to inform users of the number of login attempts with MFA and if they are banned after more than 5 failed login attempts

**Maintenance & Adaptability:**

* `imagePullSecrets` for microservices can now be specified with the option to change the imagePullPolicy for installations
* Added new variable to enable or disable MFA

#### Fixed

**Performance & Scalability:**

* Improved ability of CybusMQ to start with large number of objects in metadata store on disk

**Usability & Accessibility:**

* Selected table items in the service overview are only being de-selected in case they are gone from the view
* Endpoint `/api/session` returns the reduced set of permissions when user has MFA enforced but not enabled yet
* Notifications in the Data Explorer inform when corresponding service endpoints are unavailable

**Maintenance & Adaptability:**

## What has changed in 1.7.1?

#### Added

**Usability & Accessibility:**

* Made /api/topics usage optional, allowing users without read access to still load and use the Rule Engine and Data Explorer pages.
* Added warning on Data Explorer to notify users with limited permissions that loading topics metadata is not possible.

**Reliability & Robustness:**

* Improved clustering connection stability in CybusMQ, enabling reliable clustered mode operation and reducing message loss.

#### Fixed

**Usability & Accessibility:**

* Corrected the link to wildcards in the documentation to use the proper href format, ensuring accessibility and preventing permission errors.

**Reliability & Robustness:**

* Enabled message reception of a service sharing the same MQTT topic as another service by removing wildcard topic handling for overlapping topics.
* Ensured MQTT connections using default credentials reconnect successfully after a Connectware restart.

## What has changed in 1.7.2?

#### Added

**Security & Stability:**

* Fixed LDAP certificate mounting for Helm installations.

## What has changed in 1.7.3?

**Release date:** 29.08.2024

#### Added

**Security & Stability:**

* KafkaJS Library Update

**Usability:**

* Protocol Mapper is listed under the Agents tab on the System Status page
* Improved Deviations notification on Service Overview page now supports pagination
* Enhanced the Service Details Page with a Deviations tab
* Removed “type” column from Deviations list in Service Details page
* Notification on changed permission (due to MFA) is now dismissible

#### Fixed

**Security & Stability:**

* Fixed issue of TCP ingress routes with matching targets leading to flood of logs.

**Reliability & Robustness:**

* Resolved Services Graph data corruption in large deployments by moving storage to PSQL.

</details>

<details>

<summary>Connectware 1.6.0 – 1.6.2</summary>

## What has changed in 1.6.0?

#### Added

**Performance & Scalability:**

* Updated service behavior to allow immediate HTTP connection attempts upon enabling.

**Usability & Accessibility:**

* Redesigned the interface for an improved user experience and easier workflow.
* Improved error handling when updating an existing service.
* Introduced a validation endpoint `/api/validate/service` to ensure correctness of Service Commissioning Files and enhance error detection.

**Monitoring & Resilience:**

* Service Manager is now more resilient on larger deployments.
* Better VRPC timeout flexibility to improve support for large-scale deployments.
* Improved data flow recovery in services, ensuring consistent data publishing resumes after any disruptions.

#### Fixed

**Security & Stability:**

* Updated the admin-web-app image to ensure the Frontend remains accessible when started as the root user.
* Fixed access issues for MFA-enabled users, ensuring they can now access the workbench.

**Usability & Accessibility:**

* Enabled successful DateTime write operations to OPC UA variables, ensuring accurate updates on the server.
* OPC UA write endpoint returns error on failing writing attempts when data types are mismatching.

**Maintenance & Adaptability:**

* OPC UA StatusCode for variable values is now accessible for read endpoints.

**Monitoring & Resilience:**

* Improved system resilience by ensuring smooth service enablement and stable Protocol-Mapper operation, even when custom protocol agents are absent during Service-Manager restarts.

## What has changed in 1.6.1?

#### Added

* General backend: Started using ESLint
* Protocol Mapper: OPC UA read endpoints now have access to the full raw payload
* Admin UI: VRPC timeout is configurable from the UI
* Helm charts: VRPC timeout support added

#### Fixed

* General backend: Fixed an issue with running automated tests
* Protocol Mapper: SOPAS - Fixed an issue with the EventListener being removed too early
* Admin UI: Fixed an issue with not being able to write a configuration when not using the default user
* Broker: Fixed an issue with cleaning up Broker cache entries

## What has changed in 1.6.2?

#### Fixed

**Usability & Accessibility:**

* OPC UA: Fixed edge case falsely returning `BadTypeMismatch` when writing numerical values

</details>

<details>

<summary>Connectware 1.5.0</summary>

## What has changed in 1.5.0?

{% hint style="warning" %}

#### Upgrade Guide for Connectware 1.5.0

This release requires manual upgrade steps when upgrading from a version below 1.5.0. The dedicated upgrade guides for this version have been removed. If you still run a Connectware version below 1.5.0, contact the [Cybus Support Portal](https://support.cybus.io).
{% endhint %}

In the latest version of Connectware, version 1.5.0, we’ve enhanced our approach to using elevated system permissions. Our focus is on improving security by adhering to the principle of least privilege across our software components.

As part of these improvements, we’ve altered the system user account under which certain containers run. To successfully upgrade to Connectware 1.5.0 or later, you’ll need to follow some additional update procedures.

#### Added

**Security & Stability:**

* Lowered system user privileges across several containers for enhanced security
* Altered the internal ports for Connectware containers; external access remains unchanged on the original ports
* Enhanced broker resilience to handle unexpected shutdowns more effectively
* Enabled MQTT clients with persistent sessions to have their QoS 0 messages stored by the broker, minimizing message loss even for QoS 0 subscriptions (disabled by default)

**Usability & Accessibility:**

* Implemented message deduplication for MQTT clients with overlapping subscriptions to prevent message duplication across matching topics (enabled by default). For more information, see [Duplicate Message Delivery in MQTT Clients](/broker/cybusmq/configuration/duplicate-message-delivery).

**Monitoring & Resilience:**

* Revised the logging format of our broker to incorporate the current date for better tracking

#### Fixed

**Monitoring & Resilience:**

* Container logs can now be displayed when third party workloads are present in the same Kubernetes namespace

</details>

<details>

<summary>Connectware 1.4.0 – 1.4.1</summary>

## What has changed in 1.4.0?

Users can now enable MFA (Multi-Factor Authentication) for their login process. The HTTP server has been upgraded to seamlessly request MQTT credentials through GET requests.

#### Added

* Admin UI: MFA support
* Auth Server: MFA support
* Protocol Mapper: added GET support for HTTP server

#### Fixed

* Protocol Mapper: Fixed problems related to MaxListenersExceededWarning
* fixed wrong OAuth access token format for HTTP client
* Reconnection of OPC UA connections is much faster now
* Child services do not stay in deviation when parent service got updated

## What has changed in 1.4.1?

We’ve fixed a bug causing some endpoint resources to be hidden when intentionally disabled. Now, after updating, all disabled endpoint resources will show up as expected.

#### Fixed

* Protocol Mapper: Fixed a bug that caused endpoint resources to not be displayed if they were explicitly disabled.

</details>

<details>

<summary>Connectware 1.3.0 – 1.3.2</summary>

## What has changed in 1.3.0?

Introducing the latest version of Cybus Connectware. This release brings exciting new features and important fixes to enhance your experience.

With the updated Admin UI, you now have the ability to filter logs by date and type, providing easier navigation and analysis. We have also made styling enhancements for a more seamless and visually appealing interface. In addition, the Auth Server now supports LDAP authentication, ensuring secure user access. The Broker now includes MQTT 5 simple authentication support, and the Protocol Mapper introduces MQTT 5 shared subscription support. We have also addressed various issues, including notification rendering, message delivery, and duplicate message retrieval.

Upgrade now to enjoy the enhanced capabilities of Cybus Connectware.

#### Added

* Admin UI: Introduced ability to filter logs by date and type
* Admin UI: Overall styling enhancements
* Auth Server: LDAP support
* Broker: MQTT 5 simple authentication support
* Protocol Mapper: MQTT 5 shared subscription support

#### Fixed

* Admin UI: Fixed notifications sometimes not being rendered correctly
* Broker: Fixed some messages not being delivered under certain configurations
* Protocol Mapper: ADS - Fixed retrieval of duplicate messages after reconnection

## What has changed in 1.3.1?

We’re excited to bring you a set of essential fixes in this update of Connectware. This update addresses an issue where optional parameters in Write Endpoints were not functioning as intended. It also resolves a bug that prevented proper parsing of MQTT payloads into JSON-compliant representation.

#### Fixed

* Protocol Mapper: Fix missing payload parsing for endpoint resource read operation
* Protocol Mapper: MQTT - Fix payload send to broker to be JSON compliant

## What has changed in 1.3.2?

{% hint style="warning" %}
Parts of this release affect required UI permissions. Please ensure to incorporate them in case you are using custom roles.
{% endhint %}

Users can now change their password using the settings page. MQTT shared subscriptions can now handle Rule Engine context variables, and we have improved error messages. For Kafka, we have fixed issues related to connecting to servers over TLS and improved the OPC UA Server behavior during startup. Furthermore, we have significantly optimized overall resource consumption and our FANUC FOCAS protocol integration now supports AddressType E for even heavier lifting.

#### Fixed

* Admin UI: Consistent language throughout the whole product (EN)
* Admin UI: Changing password using settings page
* Protocol Mapper: Significantly improved overall resource consumption
* Protocol Mapper: Fixed handling of Rule Engine context vars with MQTT shared subscriptions
* Protocol Mapper: FANUC FOCAS - Adjusted configuration to support additional address types
* Protocol Mapper: HTTP - Fixed auto generated endpoint topic name
* Protocol Mapper: HTTP - Fixed missing error message on failed post request at TCP level
* Protocol Mapper: Kafka - Fixed connecting to server using TLS
* Protocol Mapper: OPC UA Server - Fixed potential race condition during startup

</details>

<details>

<summary>Connectware 1.2.0 – 1.2.1</summary>

## What has changed in 1.2.0?

We’re excited to announce the release of version 1.2.0, which brings a whole new User Interface, as well as a range of improvements and bug fixes to our Factory Data Hub.

The whole new User Interface, with a sleeker, more intuitive and modernized design, enables a better overall experience managing your assets. We’ve enabled support for horizontal scaling on the Auth Server, which will allow it to handle an increased workload as needed. Additionally, we’ve fixed some issues related to registering Agents using mTLS, which will help streamline the authentication process. On the Protocol Mapper side, we’ve added support for OPC UA Server Historical Access StartBound aggregation, a configurable probe timeout to HTTP Connection resources, and the ability to send binary data on HTTP Write Endpoints.

We’ve also improved deviation detection for Kafka protocol write operations, which will enhance the ability to detect and address any anomalies that may occur during data transmission. Lastly, some infrequent broker issues related to publish authentication timing were resolved, which significantly improved the reliability of message delivery.

Overall, these changes aim to improve scalability, historical access, binary data transmission, and fix bugs, resulting in a smoother and more reliable user experience.

#### Added

* Admin UI: Completely revamped look, to get you where you want to be faster, with new in-app explanations and contextualization about Connectware.
* Admin UI: User Management UI is now faster, with better warnings for dangerous commands and a more intuitive usage and search
* Auth Server: Enabled support for horizontal scaling
* Protocol Mapper: Added support for OPC UA Server Historical Access StartBound aggregation
* Protocol Mapper: Added configurable probe timeout to HTTP Connection resource
* Protocol Mapper: Added support of sending binary data on HTTP Write Endpoint

#### Fixed

* Admin UI: Will no longer crash if a user goes from a mapping details to the services page
* Admin UI: Change password form now displays the correct error message when using the wrong credentials to perform an operation
* Admin UI: Now better explains server unavailability errors
* Auth Server: Fixed issues when registering Agents using mTLS
* Broker: Fixed rare publish authentication timing issues
* Protocol Mapper: Deviation detection for Kafka protocol write operations now works as expected

## What has changed in 1.2.1?

We are excited to announce the release of Version 1.2.1 of our product, packed with powerful enhancements and optimizations. This release focuses on significantly improving the overall message throughput performance, ensuring a faster and more efficient user experience.

Enhanced Message Processing: We have fine-tuned the underlying algorithms and systems to streamline the message processing mechanism.

As a result, you will notice a substantial increase in the speed at which messages are handled, leading to quicker response times.

#### Added

* Protocol Mapper: Optimized overall message performance

</details>

<details>

<summary>Connectware 1.1.0 – 1.1.5</summary>

## What has changed in 1.1.0?

This release increases the reliability and resilience of Connectware, especially when run in Kubernetes and in high load scenarios. Many of the changes also benefit deployments that run in Docker. The changes include updates to the Admin UI, improved Helm chart usability and improved stability and connectivity of Connectware services.

When you upgrade Connectware to version 1.1.0, all services are disabled. After upgrading, you must enable the services that you want to use again.

#### Added

* Admin UI: You can now load resources via HTTP instead of WebSocket for most resources
* Admin UI: Refresh license button on offline installations is now disabled
* Admin UI: Loading times for resources on the User Management page have been improved
* Admin UI: Users without management access can now access the detail pages
* Admin UI: Improved error messages when installing commissioning files that contain errors
* Broker: Cluster join/leave logic has been improved
* Container Manager: You can now use HTTP endpoints to start/restart/stop containers by specifying their identifier
* Implement optional MQTT traffic decoupling for Control Plane & Payload Data by using different brokers
* Kubernetes: Add Helm value to configure storage class
* Kubernetes: Add common Helm value for mTLS and enable mTLS in control-plane-broker
* Kubernetes: Change default access mode for postgres volume to ReadWriteOnce and introduce configuration option
* Kubernetes: Add Helm configuration for securityContext
* Kubernetes: Change Helm podResources to allow setups without limits
* Kubernetes: You can now configure the protocol-mapper resource requests/limits via protocolMapperAgent
* Kubernetes: Support for Helm best practices labels
* Kubernetes: Support labels and annotations for resources with Helm installation
* Kubernetes: Added init container to broker that checks Kubernetes API availability
* Protocol Mapper Agent: Enable support for mTLS registration/authentication
* Protocol Mapper: The resource Cybus::HttpServer now accepts configurable payload sizes of up to 512 KB
* Service Manager: Services Graph is now enabled by default

#### Fixed

* Admin UI: Custom topics are now displayed on the Explorer page
* Admin UI: Stopping multiple containers now works as intended
* Admin UI: You can now remove endpoints that are enabled
* Admin UI: Rule Engine Sandbox and Mapping fix unexpected failure when non-JSON message is processed in transform rule
* Admin UI: It is no longer possible to remove critical certificates from the Certificates page
* Broker: MQTT clients are no longer interrupted and continue all operations when broker cluster nodes are down or not fully initialized
* Service Manager: Restarting the Broker no longer makes Connectware Services unreachable
* Protocol Mapper: Services with deviated connections are now displayed as deviated
* Protocol Mapper: Kafka consumer no longer blocks execution on connection loss
* Protocol Mapper: OPC UA value sanitizer now handles previously undetected errors

## What has changed in 1.1.1?

This release increases the performance of the MQTT protocol both internally and when used in Services.

#### Added

* Protocol Mapper: Increase performance of MQTT protocol

## What has changed in 1.1.2?

This release includes a fix for credentials handling for resources of type Server and Node in Agents in the case of restarts.

#### Fixed

* Protocol Mapper: Fix incorrect handling of credentials for Server and Node resources causing authentication errors

## What has changed in 1.1.3?

This release includes a fix for the Server resource type and fixes for Agents’ credential handling Additionally we now support certificates using SAN for mTLS authentication and we expose some variables to configure the duration of broker authentication and authorization results.

#### Fixed

* Protocol Mapper: agents crash after registering with `CYBUS_PROTOCOL_MAPPER_PASSWORD` environment variable set
* Protocol Mapper: improve credential management in Agents when using custom password rules
* Protocol Mapper: improve credential management in Agents using mTLS when the registration process is aborted
* Protocol Mapper: avoid potential crash when HTTP Server resource attempts to bind multiple times to its TCP port

#### Added

* Auth Server: make cache timeouts for broker auth endpoints configurable
* Ingress Controller: added support for certificates using SAN
* Kubernetes: Use podAntiAffinity to schedule broker pods on different K8s nodes
* Kubernetes: Make broker volume sizes configurable
* Kubernetes: Expose cache timeouts for broker auth endpoints environment variables

## What has changed in 1.1.4?

This release includes a fix for mTLS and improvements to the Broker and Auth Server.

#### Fixed

* Connectware: add support for docker compose plugin
* Protocol Mapper: fix potential data loss in Mappings
* Protocol Mapper: fix mTLS authentication for Mappings

#### Added

* Protocol Mapper: correct log texts
* Auth Server: retry mechanism for migration in case of failure

## What has changed in 1.1.5?

This release includes improvements to the MQTT broker to improve authentication handling, cluster formation, and logging improvements. Additionally Protocol Mapper uses a better strategy in cases when Broker is restarted for maintenance or due to migration of Broker Pods.

#### Added

* Broker: make authentication more resilient
* Broker: improve cluster formation to make it more deterministic
* Broker: Investigate and implement possible robustness improvement around read-only filesystem
* Kubernetes: Increase terminationGracePeriodSeconds for Broker and Control Plane Broker StatefulSets
* Protocol Mapper: improve resilience when connection to the Broker is temporarily lost

</details>

<details>

<summary>Connectware 1.0.0 – 1.0.93</summary>

## What has changed in 1.0.0?

This is the first 1.0 stable release in the 1.0 series of the Connectware. Data governance and connectivity from the shop floor to the enterprise is now easier and more reliable than ever.

#### Changes from last beta version

**Changed**

* Unify swagger filenames to swagger.yaml everywhere
* Update node.js in protocol-mapper to 12.16.x

**Fixed**

* Clarified constraints on username/password length in UI and REST API
* Improved OPC UA reconnect behavior
* Mapping resource to respect the state of external MQTT connections
* Fix erroneous handling of service id in REST API
* Improved SOPAS sopas reconnection behavior
* Fixed performance of frontend adding separate event-backends in react-vrpc, unmounting views not seen in details view, filtering results in parent components and separating state changes into smaller components

## What has changed in 1.0.1?

Minor bug fixes with improved stability.

#### Added

* Added Rest API for Cybus::Link resource at /services/links
* Added Agent view in Admin Web App so users can view currently connected agents

#### Fixed

* Fixed general bugs in Cybus services swagger files
* Fixed issues with 0 or false values in default parameters in service files
* Fixed issues with protocol mapper with a number of issues fixed in the MSSQL protocol

## What has changed in 1.0.2?

Stability improvements with some bug fixes.

#### Changed

* The node.js version is upgraded to 12.18.0 which includes security updates

#### Fixed

* Service count number on home page view is fixed
* REST API-based creation and deletion of services is now integrated correctly with admin ui
* Topic generation in BACnet is fixed
* OPC UA re-subscription which failed in certain re-connection scenarios is now fixed
* S7 data write format is fixed

## What has changed in 1.0.3?

The [Heidenhain](/connectors/shop-floor-connectors/heidenhain-dnc) protocol has been added and further stability improvements have been implemented, along with regular bug fixes and UI improvements.

#### Added

* [Heidenhain](/connectors/shop-floor-connectors/heidenhain-dnc) protocol has been added and completed in 1.0
* Log files can be downloaded as .csv files from UI
* Installer script has alternative offline installation mode

#### Changed

* Node-RED version in [workbench](/data-flows/node-red-workbench) updated to current 1.0.6
* More npm dependencies have been updated to current versions
* Updated CI pipeline with Balena OS VM images build and push

#### Fixed

* Fix all warnings from react in admin-web-app
* Fix problem with topic construction on unsubscribe
* Installer script checks even more for potentially missing Internet connection

## What has changed in 1.0.4?

Feature updates and maintenance: Two new protocols have been added, [SINUMERIK](/connectors/shop-floor-connectors/sinumerik) and [Beckhoff ADS](/connectors/shop-floor-connectors/ads). Also, many stability improvements have been implemented, along with regular bug fixes and UI improvements.

#### Added

* Protocol implementation for [SINUMERIK](/connectors/shop-floor-connectors/sinumerik) controls
* Protocol implementation for [Beckhoff](/connectors/shop-floor-connectors/ads) controls (ADS protocol)
* Implemented mutual TLS authentication for MQTT

#### Changed

* Improve date/time format in filename of log download
* Prohibit deletion of admin user and connectware-admin role in admin-ui and REST API
* REST API call correlation-id is renamed to `id` according to JSON-RPC
* user documentation: sample commissioning files improved

#### Fixed

* S7 protocol write method was dropping data on high load, now fixed
* Fix selection of correct service in admin-ui service view
* Fix burst rule in Rule Engine
* user documentation: fix missing parts of Heidenhain protocol
* Fix auth-server lock-up due to issues with PostgreSQL connection handling
* Fix issues on disabling WERMA connections
* REST API service delete is fixed
* Fixed issue in incomplete disabling of mapping resources

## What has changed in 1.0.5?

This release was skipped due to QA issues. The changes are listed in the 1.0.6 release.

## What has changed in 1.0.6?

This release includes various stability and ease of life improvements as well as new features regarding service updates and configuration as well as agent tracking.

#### Added

* Enabled in-place update of service parameters and/or commissioning files
* Agents are being tracked and emit messages on deviation
* Possibility to specify `qos` and `retain` options for MQTT within mapping configuration

#### Changed

* Documentation regarding Connectware users and services has been improved
* SINUMERIK initial compatibility checking of OPC UA server has been improved
* Node.js updated to 12.18.2, node-red workbench updated to 1.1.0

#### Fixed

* Fixed authentication limitations under load (PostgreSQL communication improved)
* Fixed issue with subscribe topic resolution on wildcard ‘#’ mapping when published on parent
* Fixed UI problem when pressing escape key in roles dropdown
* Fixed issues with API calls to `POST /services` when used in combination with `targetState: enabled`
* Fixed problems on disabling or deleting mappings in UI

## What has changed in 1.0.7?

This release brings a large number of stability improvements and better explanations in the user documentation.

#### Added

* HTTP protocol: Added options to configure client certificates (SSL) and certificate policy
* License file can be uploaded to system control server by REST endpoint
* SINUMERIK protocol: Data point “number of teeth” added

#### Changed

* User documentation improved for protocols Http, Modbus, Sopas, and for Connection resource
* Admin-UI: User interface has been refactored and improved for better performance in Service, Connection, Endpoint, Mapping view
* Update node.js to latest 12.18.3

#### Fixed

* Admin-UI: Fixed displaying of information when an external broker is involved during mapping
* User documentation: HTTP permission explanation improved
* Fix integer type interpretation of Cybus::MqttPort parameter
* Admin-UI: serviceId parameter description fixed in configuration dialog
* Admin-UI: favicon size set correctly in manifest
* Admin-UI: button tooltips added where missing
* Admin-UI: fixed issues with role names from commissioning file
* Fix yaml schema to allow qos and retain options at mapping and endpoint resources
* Fix missing docker label at bootstrap container
* Performance fix when creating larger number of services
* Fix authorization of REST calls with query string

## What has changed in 1.0.8?

This release includes various stability and ease of life improvements as well as slightly more compact file size of the docker images of the Connectware.

#### Changed

* Reduce docker image sizes and application package by partly compiling application source code and javascript libraries
* Reduce connectware networks to only one. Also, change default network mask to a slightly less common IP range 172.30.0.0/24
* Improve error log message on endpoint creation if endpoint does not find its connection, to simplify debugging

#### Fixed

* OPC UA protocol: [OpcuaEndpoint](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#endpoint-properties) allows either nodeId or browsePath, where it previously required nodeId alone, but now allows either of both.
* Mapping: Fix MQTT message handling with named wildcards, which previously stopped working after the first message, but now works correctly.
* Fix erroneous deviation message on user or role permissions which contain pseudo-parameters
* Admin-UI: fix various UI problems when deleting individual resources: Fix delete button of connections, fix deletion of endpoints, fix display update of volume list after deleting a volume
* Documentation: Fix explanation of [parameter section](/data-flows/service-commissioning-files/parameters) in commissioning file

## What has changed in 1.0.9?

With this release, performance for complex systems has been improved significantly. Additionally, numerous improvements in the Admin-UI and overall stability fixes have been included. Also, the installer will now remove old unused Docker images of previous Connectware versions, decreasing disk size usage and improving stability, too.

#### Added

* UI Explorer view: Data values which are JSON objects can be copied to clipboard by clicking on a newly introduced Clipboard icon, see [Copying Data to Clipboard](/monitoring/data-explorer#copying-data-to-clipboard)

#### Changed

* Installer: Add removal of old docker images after pulling the newest ones.
* Update vrpc to 2.1.6 which also improves instance creation performance, so that now at least 200 endpoints can be handled quickly, with more to come
* Improved API of genericVrpc protocol (subscribe now uses id instead of callback)
* Improve change-of-value (cov) filter behavior. The COV Filter should now work as expected, independently from its position in the rule chain.
* Use the native redsocks instead of our custom container in Balena release
* The qos level for all internal MQTT connection was set to default 0 (zero) to improve overall connection performance.

#### Fixed

* Admin-UI: hide private (internal) roles in user overview upon sorting
* Admin-UI: List view sorting and selection is not reset quickly anymore
* Admin-UI: fix UI hang in resource/connection view if internal connection exists
* Admin-UI: Fix log time display to use range 0..23 hours instead of 1..24
* Installer: fix erroneous usage of curl if only wget is available
* Mappings: fix incomplete removal of mappings causing duplicate connections (“zombie connections”)
* Fix balena-iso-config-configuration
* Protocol Mapper: Endpoint waiting for connection now works more than once

## What has changed in 1.0.10?

This regular update release brings further performance improvements and bugfixes. The bootstrap container has been removed and its functions have been integrated into other containers. The new protocol [Ethernet/IP](/connectors/shop-floor-connectors/ethernet-ip) has been added.

#### Added

* New protocol: [Ethernet/IP protocol](/connectors/shop-floor-connectors/ethernet-ip)

#### Removed

* Move bootstrap functionality into system-control-server, removing bootstrap container completely

#### Changed

* Auth-server: improve SQL queries for the user and role model to improve auth-server performance even more
* User docs: Add hint about required license if examples use Docker image from Cybus registry
* Implement license validation in system control server
* Improve container [log file download](/monitoring/system-status/system-container-status#container-logs)
* Admin-UI: improvement for success and failure messages on service state changes
* Admin-UI: Service deviation information is now aggregated in backend instead of frontend to improve performance and response time in UI

#### Fixed

* Fix broken mapping [rules](/data-flows/rule-engine) for messages with non-JSON content. This was broken in 1.0.9 release, fixed in 1.0.10 release.
* Admin-UI: Fix endpoint display in service details to show only relevant subset
* Installer: fix installer in offline mode if docker-compose.yml is the same file

## What has changed in 1.0.11?

Another regular update is published which brings further performance improvements and bugfixes. In particular, an annoying problem with duplicate messages after disabling and enabling services with mappings has been fixed. Also, the explorer window is working much faster right now, and more issues have been fixed, too.

#### Changed

* Improved internal communication performance by switching internal mqtt connections to bestEffort (qos=0) usage, except for the non-local connection of a protocol-mapper agent to the connectware

#### Fixed

* Increased performance of explorer view
* Fix remaining duplicate subscriptions after disabling and enabling again any Mapping resource with more than one mapping
* Fix wrong tooltips in toolbar of connection overview, and also fix endpoint and connection button functions
* fixed installer in silent mode to be really silent

## What has changed in 1.0.12?

The next weekly regular update with several bugfixes and performance improvements.

#### Changed

* Improve stability at docker container handling by preventing race conditions on docker calls
* Update node-red to 1.1.3

#### Fixed

* OPC UA: Some bugfix at reconnection handling
* Installer: Fix problems at removing old bootstrap container and image
* Fix erroneous generation of default serviceId which allowed only a very restricted character set for metadata.name.
* Admin-UI: In service detail view, make sure to show only matching connection, endpoint, mapping, not ones from other services.
* Admin-UI: Fix missing parameter default value 0 which was not displayed in the configuration dialog
* Fix resourceId parsing which is now allowed to start with a number, too.
* Remove any mention of old log-server and device-dispatcher, fixing spurious DNS queries for those outdated hostnames.
* BACnet: Bugfix in logging statements

## What has changed in 1.0.13?

Next weekly regular update with several bugfixes and performance improvements. Also, this release now includes the Pfannenberg protocol.

#### Added

* Pfannenberg protocol ported to v1.0

#### Fixed

* Admin-UI: Fix connection and endpoint pages when Agents get offline
* Admin-UI: Fix container overview page selections by only updating on data change
* Admin-UI: Fix toolbar button availability if multiple services are selected
* Mapping: Further fix potential message duplication when multiple Mapping resources were subscribing to the same topic
* Improve connection cleanup on endpoint disable by removing event listeners on state change
* BACnet: decrease verbosity in normal operation
* RuleEngine: Fix parse rule for boolean values
* ADS: removing unnecessary verbose error message

## What has changed in 1.0.14?

A new weekly regular update with several bugfixes, some performance improvements in the user interface, and much speed-up of enabling and disabling of services.

#### Changed

* Make resource creation and deletion in parallel, and fix delete order. This significantly accelerates enabling and disabling of services
* Clarify, clean up and improve [parse rule in RuleEngine](/data-flows/rule-engine/data-processing-rules#parse)
* Admin-UI: Improve UI performance for Endpoints
* Update nodejs version to 12.18.4

#### Fixed

* User docs: Improved [documentation for MQTT\_ROOT](/data-flows/service-commissioning-files/parameters#global-pre-defined-parameters)
* User docs: The documented REST API health endpoint was not working as expected, but instead /api/system/info is available to be used for health checking.
* Admin-UI: Fix endpoint deletion in overview page
* Improved genericVrpc to be resilient against instantiation order
* Admin-UI: let all tables in the ui keep their local state to fix disappearing selection on state changes
* Distributed agents: Fixed resource deletion on agents
* SHDR: Fix endpoint key mismatch
* BACnet: Fix TypeError crash
* Let persistence of objects ignore files with parsing errors
* Pfannenberg: Fix crashes on mismatching object declarations

## What has changed in 1.0.15?

A new regular update with several bugfixes, some performance improvements in the user interface, and even more stability in working with services. Also, a general [SQL connection protocol](/connectors/enterprise-connectors/sql) has been added for connecting the MariaDB database.

#### Added

* New protocol: [SQL connection protocol](/connectors/enterprise-connectors/sql) for e.g. MariaDB has been added

#### Changed

* LDAP: Security and stability update. LDAP UTF-8 filter values now strictly required to be escaped following the XX hex notation (see [LDAP Filters Documentation](/access/user-management/single-sign-on-sso/sso-with-ldap#ldap-filters)).

#### Fixed

* Admin-UI: Fixing buttons in service detail page to appear automatically after enabling the service
* Fixed buttons on service detail page that were broken after re-start
* Admin-UI: In connection overview and connection detail page, show IP address also for various protocols like Heidenhain and BACnet
* Docker: Improve error message on failing docker image pull
* GenericVRPC: Fixing issues with deleting resources
* Beckhoff: Fix subscribe/unsubscribe in Beckhoff ADS
* Fix race condition that caused corrupt resource persistence storage by ensuring that all persistence access is protected against race conditions
* Admin-UI: fix missing error message display on volume deletion
* SINUMERIK: Fixed writing of SINUMERIK teethCount parameter
* Fix container-manager memory leak
* Modbus: Fix typo preventing processing discrete input
* Service Manager: Fixed instabilities after restart by improving resource polling for deviation detection
* Service Manager: Fix endpoints to not get stuck in enabling state
* Service Manager: Fix confusing short user/role deviation display at service startup
* Fix sopas reconnecting
* User docs: Fix spelling of protocol names in docs

## What has changed in 1.0.16?

Next regular update release with several bugfixes, in particular fixing an issue with resource persistence and also for OPC UA reconnection stability. Additionally, another new protocol [OPC DA](/connectors/shop-floor-connectors/opc-da) has been added, and plenty of small bugfix improvements make life easier in production use of the Connectware.

#### Added

* Implement [OPC DA protocol](/connectors/shop-floor-connectors/opc-da)

#### Changed

* Commissioning files: Allow more characters in [serviceId](/data-flows/services/serviceid) and [resourceId](/data-flows/service-commissioning-files/resources#resource-id). For backward compatibility reasons, the rule for auto-generation of a serviceId is kept unchanged, so that an auto-generated serviceId is still all lowercase.
* Admin-UI: Implement more details overview of currently used Connectware license
* All protocols: Introduce versioning in protocol-mapper so that distributed agents can check for compatible versions
* Installer: Improve installer script to self-contain the docker-compose.yml file so that no extra download is needed anymore

#### Fixed

* Severe bugfix in Admin-UI: Fix erroneous removal of listeners from service instances, causing breaking persistence of resources and unexpectedly restore of older resource versions on Connectware restart
* Admin-UI: Fill the host/port field in the Authorize dialog and the Connection overview and detail pages for all protocols
* Admin-UI: In the Grant Client Registry dialog, also display the requested roles
* All protocols: Improve logging statements in protocol-mapper to let all contain context
* All protocols: Fix partly broken subscription restore on reconnect by improving the Connection base class API, especially for OPC UA
* OPC UA: Fix remaining issues with OPC UA reconnection behavior to be much more stable
* Pfannenberg: Fix polling data access, improve stability of subscribe data access
* Modbus: Fix boolean datatype in modbus data

## What has changed in 1.0.17?

This week’s regular update release brings again several bugfixes, in particular related to the [Beckhoff ADS protocol](/connectors/shop-floor-connectors/ads). Additionally, some user interface improvements were added, such as a notice about newer version availability on the [Home](/monitoring/system-status) section of the Admin-UI.

#### Changed

* Admin-UI: Improve user experience for Internet Connectivity checking
* Admin-UI: Display available newer versions on Home page
* Admin-UI: Improve display of hostname in agent overview
* MsSQL: Extend mssql read function to use templates, similar to mssql write function
* MsSQL: Add property to skip SQL query format validation, to enable using specific MsSQL syntax variants
* Installer: Add extra operation mode for installer to prepare offline installation files

#### Fixed

* ADS: Fix Beckhoff crash by adding missing delete of async handler
* ADS: Fixed subscriptions by choosing the correct subscribe mode
* ADS: Update ADS client library from github
* OPC DA: Improve wording for OPC DA error messages
* Installer: Let the installer not logout if it was logged in before
* Services: Fix missing termination condition when setting up state checking, related to the noted bugs
* Services: On failing service update, improve cleaning up of resources for rollback
* Startup: Fix blocked start-up of system-control-server by fixing an erroneous awk command in bootstrap script
* Startup: Fix postgresql error message when User.read is called with empty userId

## What has changed in 1.0.18?

This week’s update release brings stability improvements and bugfixes, especially regarding service commissioning files with larger number of endpoints. Additionally, some user interface improvements were implemented, such as an improved license handling and some minor usability improvements when no services are installed yet, to get started even easier.

#### Added

* OPC UA Server: New OPC UA server is added, available as Cybus::Server resource, using port 4841, along with historical access (using an InfluxDB internally). Documentation is still in preparation.
* REST: Added /api/system/health endpoint which returns information about the connectware system container.

#### Changed

* [License file handling](/deployment/licensing) improved and better connected with Cybus Portal management interface
* Admin-UI: Some UX improvement on empty connectware

#### Fixed

* BACnet: Updated BACnet code for improved stability and reliability
* Service files: Enable enabling of a large number of endpoints (2000-3000 endpoints)
* Service files: Fix cleanup on service rollback if service cannot be installed or updated
* Service files: Fixed mapping resource validation on error
* EtherNet/IP: programName property can now be null
* EtherNet/IP: Optimized connectivity by removing watchdog in favor of reconnection logic in the scanning.
* Beckhoff ADS: Fix problems with larger number of endpoints

## What has changed in 1.0.19?

This week’s bugfix update improves some issues in SQL (MariaDB) and Beckhoff ADS protocols, along with further stability improvements.

#### Added

* Admin-UI: Let distributed agents show their versions in the Agent overview page
* SQL protocol (MariaDB): Extend error reporting for when a query validation fails

#### Changed

* Beckhoff ADS protocol: Adding id, timestamp and value to protocol output
* ADS protocol: User documentation improved by explaining input/output message format in detail
* Admin-UI: Make endpoint overview page faster for large number of endpoints
* Admin-UI: Improve display refresh of system health page

#### Fixed

* Beckhoff ADS protocol: Fix occasional segmentation fault on disconnect

## What has changed in 1.0.20?

Another regular bugfix update of the Connectware. This time, some EtherNet/IP and MsSQL protocol issues have been fixed, some structure improvements with the [OPC UA Server](/connectors/servers/opc-ua-server) were added, and several overall stability improvements were implemented.

#### Changed

* Admin-UI: On a Balena managed appliance, show a different link for updating
* Agent performs version check upon connecting to central broker, for now just printing a clear log message on version mismatch, but in the future more automatic actions are being prepared.

#### Fixed

* OPC UA Server: Simplify configuration to only define server and node, no more “parent node” resources. Various other configuration clarifications.
* OPC UA Server: Several unhandled promise exceptions are fixed. Deviation tracking is fixed, too, and also UI representation.
* Mssql protocol: Fixed host parameter which could not be changed on subsequent connection attempts.
* EtherNet/IP protocol: Fix unhandled promise rejection on errors in scanning process
* REST API: Fix client registration behavior if username already exists
* Authentication: Fix errors with username and rolename with spaces
* Container handling: Fix annoying log error messages about unhandled promise rejections after containers have been restarted
* Admin-UI: Fix crashing UI on deleting service in service overview

## What has changed in 1.0.21?

This regular bugfix update improves the stability of the new [OPC UA server](/connectors/servers/opc-ua-server) considerably. Also, issues with MQTT connections, in Heidenhain protocol, and in the user interface have been fixed. And the first beta version of the Service Catalog for downloading services online from the Cybus Portal has been added - more content will be added there over the upcoming weeks and months.

#### Added

* Admin UI: Added first draft of Service Catalog for installing services online from the portal
* Docker resources: Add properties to limit CPU and memory usage

#### Changed

* OPC UA Server: enable OPC UA secure channel by default. BREAKING CHANGE: Connectivity to OPC UA Server is now only possible by “SecuritySetting: Basic256Sha256, SecurityMode: SignAndEncrypt”
* Modbus protocol: Improved error messages in case of modbus server disconnect
* Update some npm dependencies packages

#### Fixed

* OPC UA Server: Fix for nonexposure of Namespace metadata for cybus namespace
* OPC UA Server: Fixed errors when more than one root node is specified
* OPC UA Server: Fix error with array datatypes
* OPC UA Server: Fix initialValue 0 not accepted
* OPC UA Server: Fix slow endpoint creation if service contains also nodes
* OPC UA Server: Catch errors and exceptions on starting OPC UA server if e.g. port is in use
* MQTT and GenericVRPC protocols: Fix mqtt-package dependency to non-broken version 6.7.0 where the previous version 6.6.0 caused “Error: Invalid length” exceptions. The erroneous dependency affected Connectware 1.0.18, 1.0.19, and 1.0.20.
* Heidenhain protocol: Fix endpoint schema to allow function call parameters on subscribe
* Admin UI: Fix unsorted service overview table
* Admin UI: Fix various mui-datatables deprecation warnings
* Admin UI: Fix blank screen for service details if agent is offline
* Admin-UI: Fix wrong character encoding on downloading commissioning files with non-ascii characters
* Managed Appliances: Fix missing NODE\_ENV in balena docker-compose.yml file

## What has changed in 1.0.22?

#### Added

* Add local caching of valid license file so that offline instances can restart without additional license file handling
* OPC UA Server: Added 64-bit integer number support
* ADS protocol: Added data type conversion directly in endpoints

#### Changed

* Docker: Change docker image tags to version number instead of git commit hash
* OPC UA Server Historical Access: Use the original data timestamp when writing to influx database
* OPC UA Server Historical Access: Improved retention policy handling

#### Fixed

* OPC UA Server: fixing server behavior if MQTT broker is reconnecting
* SQL protocol (MariaDB): Fix sql insertion when template variables contain non-ascii characters
* OPC UA Server: Fix error on influx setup preventing OPC UA access at all

## What has changed in 1.0.23?

This regular bugfix update improves stability and scalability, but also brings new features. The release includes ingress routes to custom service containers now not only for HTTP protocol connections but also for general TCP/IP connections. Also, the FOCAS protocol for FANUC CNC machines has been added.

#### Added

* New ingress routes for TCP/IP added, so that not only HTTP but also general TCP/IP connections can be routed to service containers via [Cybus::IngressRoute](/data-flows/service-commissioning-files/resources/cybus-ingressroute).
* New protocol added: [FANUC FOCAS](/connectors/shop-floor-connectors/focas)

#### Changed

* Admin UI: Service catalog display page is updated with categories and more pointers on how to create and deploy further services

#### Fixed

* Modbus protocol: connection status not updating on half-open TCP socket
* OPC UA Server: Increase large number of nodes that can be created
* Documentation: Update docs to reflect actual default for QOS on mappings
* Admin-UI: Fix double upload needed on license upload
* Admin UI: Fix system status page reload
* OPC UA Server: fix OPC UA Server’s different endpoint specification preventing some client access
* Commissioning files: Fix bug in circular dependency detection algorithm

## What has changed in 1.0.24?

Another regular maintenance release for the beginning of the year, bringing some bugfixes for OPC UA Server and improving the recently added FOCAS protocol.

#### Changed

* Update NodeJS to version 12.20.1, including security updates
* All protocols: Switch base image of protocol-mapper from alpine linux to debian (buster-slim) to avoid compatibility issues with musl-libc and now just use standard glibc
* MQTT Broker: Upgrade VerneMQ to version 1.11, fixing issues with overly consuming disk space

#### Fixed

* OPC UA Server: Fix for Mismatch of UserIdentityTokens, fixing some connection problems from specific OPC UA clients.
* FOCAS protocol: Make FOCAS connection asynchronous again
* FOCAS protocol: Fix crash on return value conversion of pmc\_rdpmcrng method
* Documentation: Fix modbus example files to always define a dataType property on all endpoints

## What has changed in 1.0.25?

This is just another regular maintenance release for the beginning of the year, bringing mainly some bugfixes for the OPC UA Server and some small improvements in SQL protocol and workbench handling.

#### Added

* SQL protocol: Enabled submitting multiple records per message into one SQL statement
* Workbench: Added node-red project support (git repository)

#### Changed

* Ingress proxy: Update Envoy to version 1.17
* User docs: Added documentation for Cybus::Container resource limitations introduced in 1.0.21

#### Fixed

* OPC UA Server: Fix connection from UAExpert
* OPC UA Server: Fix crashing protocol-mapper on additional services in parallel to OPC UA Server
* OPC UA Server: Let OPC UA Server also start correctly from persistence
* Containers: all containers should exit when authorization is not possible. VRPC update to 2.3.0.
* User docs: Fix mistake in OPC UA docs and adjust FOCAS endpoint properties description.

## What has changed in 1.0.26?

The next regular maintenance release of the Connectware, including a collection of connectivity bugfixes for various protocols and for the OPC UA Server.

#### Changed

* OPC DA protocol: Improve handling of connection errors and wrong connection parameters to quickly show an understandable error message
* FOCAS Protocol: Update FOCAS library to version 4.16 (February 2018)
* Admin-UI: Let the Agent overview page also display Heidenhain agents
* Containers will now exit on missing permissions

#### Fixed

* OPC UA Server: finalize integration testing
* GenericVrpc protocol: Fix multiple connects in remote agent
* OPC UA Server: Fix parsing int64 values and also initial values
* BACnet protocol: Fix BACnet connection errors (on subscribe)
* MQTT Protocol: Fix MQTTS connection errors
* Heidenhain protocol: Fix broken reconnect if agents are restarted

## What has changed in 1.0.27?

Another regular maintenance release of the Connectware, including a collection of OPC UA bugfixes and other protocol improvements.

#### Fixed

* OPC UA Server: Fix handling of initialValues for receivingDataNodes
* OPC UA Server: Prohibit enabling if duplicate browseName was used
* OPC UA: Update node-opcua to 2.31.0, fixing connection problems with Heidenhain client
* ADS protocol: Fix cancelling of blocking connection requests
* Fix spurious Endpoint/Node persistence files after deletion of service

## What has changed in 1.0.28?

This release brings a new protocol for connecting to InfluxDB databases directly from the Connectware. Also, OPC UA Server can now have nodes added and removed at runtime flexibly. And some additional bugfixes for OPC UA Server, ADS protocol, and agent installation are improving Connectware stability and reliability continuously.

#### Added

* InfluxDB protocol: Add support for InfluxDB connection protocol

#### Changed

* Ingress: Update ingress-controller implementation to use Envoy API V3.
* OPC UA Server: Enabled inter-service referencing for server nodes, so that additional nodes can be enabled and disabled while the server is running

#### Fixed

* OPC UA Server: Fix re-creation of service after restarting connectware
* OPC UA Server: Print useful error message for out-of-range values, in case a JSON message contains a value that does not fit in the range of the OPC UA node
* OPC UA Server, MQTT protocol: Node and Endpoint with improved qos option handling
* Agents: Fix permission problem on restarting previously running agents
* Installer: Clarify default value of systemd install option
* Service enabling: Improve error message on offline agent
* Service catalog: fix download counter on installing a service from the services catalog
* ADS protocol: fix error on write operation
* ADS Protocol: Code cleanup and better error reporting

## What has changed in 1.0.29?

This regular maintenance release of the Connectware brings some OPC UA and ingress timing bugfixes.

#### Changed

* Ingress: Increase ingress route timeout to 30 seconds, and also add `CYBUS_ROUTE_TIMEOUT` as environment variable to the docker-compose.yml file.
* OPC UA Server: Integration of prebuilt Nodeset files
* Modules update: nodejs to 12.20.2, vrpc to 2.3.2, pg to 8.5.1, db-migrate-pg to 1.2.2

#### Fixed

* OPC UA: Fix deletion of endpoints to not take too long anymore
* Admin-UI: Fix TCP ingress routes erroneously shown as HTTP routes

## What has changed in 1.0.30?

This regular maintenance release of the Connectware brings some protocol enhancements as well as a new node.js security patch and improvements to interdependent service handling.

#### Changed

* Service manager: Introduce inter-service dependent enabling/disabling so that disabling a parent service with dependent child services will cause those to be disabled as well.
* WERMA protocol: Improve reconnection state handling
* Update node.js to 12.21.0, which includes security updates
* Container manager: Fix checking for docker container’s hostname string length which must not exceed 63 characters. Watch out: Under certain conditions, longer container names were silently accepted and seemed to work, but will no longer be accepted now.

#### Removed

* MSSQL protocol: Removed optional SQL syntax checking option. If the option is still used, a deprecation warning is logged, but nothing happens anyway now.

#### Fixed

* OPC UA Server: Fix error on deletion, and fix large numbers of endpoint and node deletion

## What has changed in 1.0.31?

Another regular maintenance release of the Connectware. There are bugfixes in some protocols, some user documentation, and optimizations.

#### Changed

* SQL protocol: increased connection probe delay and reduced logging level.
* Auth-server: Optimize basic auth API
* OPC UA Server: ObjectNode integration. Allows creation of OPC UA object types by commissioning files and the ObjectType node creates a JSON topic that is published on MQTT topic.
* Admin-UI: In the System->Agents list, allow offline agent entries to be deleted from the list.

#### Fixed

* User docs: Added instructions on how to deploy an agent on the Modbus Agent example
* Connection parameters: AdditionalProperties property was set to false in all protocol connections and endpoints schema.

## What has changed in 1.0.32?

This regular maintenance release of the Connectware brings stability improvements for OPC UA, some improvements on error reporting for container resources and container logs, and some bugfixes on InfluxDB and Modbus protocols.

#### Added

* Container resources: Add support for configuring ulimit -n in containers from commissioning file properties, see [ulimit](/data-flows/service-commissioning-files/resources/cybus-container#ulimit).
* Admin-UI: For container logs, added “Download raw logs” button for retrieving more details for bug fixing, see [Container Logs](/monitoring/system-status/system-container-status#container-logs).

#### Changed

* Container manager: better feedback on missing registry permissions for pulling Docker images
* OPC UA client: Some log output improvements for larger customer setups
* Docker logs: Set docker logging parameter max-file default to 2, so that there should be one log file always available

#### Fixed

* OPC UA server: Fix occasional problems after service deletion when enabling another service with new OPC UA server
* InfluxDB protocol: Fix disconnection tracking and improve configuration
* Modbus protocol: Fix too quickly reported state changes, especially on startup

## What has changed in 1.0.33?

Another regular maintenance release of the Connectware. This time, stability for larger commissioning files is improved, as well as error reporting in OPC UA server, InfluxDB, and other places. And there are many other bugfixes and overall improvements.

#### Added

* OPC UA client: Add optional check by TCP whether the target host and port is actually reachable (needs checkHostReachable: true)
* OPC UA Server: Add OPC UA object types that can be received or published via JSON structures on MQTT topics.

#### Changed

* Container manager: Add more descriptive error message if setting ulimit in container fails due to missing permissions, which are not available on some Docker host setups, see [ulimit](/data-flows/service-commissioning-files/resources/cybus-container#ulimit)
* OPC UA Server: Again introduce better error reporting on duplicate browse name errors
* Admin-UI docker logs: Change button “raw logs download” to really return raw logs, which is the output from the Docker daemon’s logs, not anymore a JSON file, see [Container Logs](/monitoring/system-status/system-container-status#container-logs).
* InfluxDB protocol: Improve InfluxDB user documentation and example, and improve error handling

#### Fixed

* OPC UA protocol: Fixed handling of large number of endpoints by managing endpoint in address groups internally
* Services: Some fixing of deviation tracking in larger commissioning files. Also, fix criterion when deviation tracking is switched on or off for larger amount of endpoints.
* Services: Reduce proxy timeout errors when subscribing deviation tracking
* Services: Improve the loading behavior of persisted Service instances on service-manager restart
* Protocol-mapper: Fix endpoint creation on container restart to also use batch creation

## What has changed in 1.0.34?

This next regular maintenance release of the Connectware comes with a significant improvement towards handling very large systems and commissioning files. Many inconveniences and issues with large files have been fixed, together with some bugfixes in the Admin-UI and the OPC UA Server.

#### Added

* Add logLevel parameter to [SQL connection](/connectors/enterprise-connectors/sql#loglevel-string-enum): Adds a new flag for the SQL connection, logLevel, to switch on per-request log messages.
* User docs: Adding kubernetes deployment example to the [agents documentation](/data-flows/agents/installing-agents/installing-agents-via-kubernetes)

#### Changed

* Service management: Several improvements to significantly increase speed and stability when dealing with large service commissioning files throughout their whole life cycle: At installation from Admin-UI, at installation from REST endpoint, at deviation tracking during runtime, at restarting of the protocol-mapper or other containers, and at disabling and deletion.
* Mapping resources: Significantly improve performance when enabling large amounts of mappings
* Admin-UI: Internal refactoring to improve response times and stability
* Admin-UI: Implemented a warning display if frontend and backend may operate on different versions if page is not manually refreshed by user

#### Fixed

* Fix /api/services/post REST endpoint to accept large files
* Service management: Fix various crashes with large number of endpoints
* OPC UA Server: Check for duplicate browsenames and nodeids and display appropriate error messages
* Pfannenberg protocol: Fix too often renewal of subscriptions
* Admin-UI: fixed count of resources in service detail page after resources have been deleted

## What has changed in 1.0.35?

Our next regular maintenance release of the Connectware comes with more speed and stability improvements for larger commissioning files, and some bugfixes in various protocols.

#### Changed

* OPC UA user documentation: Add [example endpoint](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#simple-example) into documentation for commissioning files with only one connection, which might need also one simple endpoint (as a workaround for some OPC UA server that closes a connection after 30 seconds if it has no endpoint)
* Modbus protocol: Adding support for configured data types on [input data](/connectors/shop-floor-connectors/modbus-tcp#input-format) for write operation
* Service files: Speed up the initial file parsing considerably
* Admin-UI: Code refactoring to improve handling of large files. Also, change service installation window to give better overview of upcoming parameters.
* Update node.js to 12.22.0

#### Fixed

* Admin-UI: Fix missing resource count update on enabling
* Admin-UI and REST endpoint: Prevent default role `protocol-mapper-agent` from being deleted
* OPC UA server: Fix accidental server shutdown after 60 minutes
* Service files: Fix error messages about `createBatch timeout` which are not necessarily a problem
* System startup: Fix occasional startup timing issues; sometimes error message `“Could not create EndpointView instance" 6000ms timeout”` appeared, sometimes the service-manager could not establish the connection to the container-manager, or vice versa.
* System startup: Avoid writing resources with failed initialization to docker volume persistence.

## What has changed in 1.0.36?

Another regular maintenance release of the Connectware. Again the stability and configuration time for larger commissioning files is improved, as well as error reporting in OPC UA client protocol, BACnet, InfluxDB, and other places. And there are many other bugfixes and overall improvements.

#### Changed

* OPC UA protocol: Clarify [reconnection timing behavior in user documentation](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#reconnection-behavior), and decreasing default maximum waiting time between subsequent re-connection trials from 60 seconds to 30 seconds.
* OPC UA protocol: Check and report if endpoint requests nodeId that does not exist on server. The respective endpoint will change into “disabled” state.
* OPC UA server: Extend historical access methods to also allow aggregation functions Average, Minimum, and Maximum.
* BACnet [user documentation](/connectors/shop-floor-connectors/bacnet) improvements
* Admin-UI: Further improvements for loading large commissioning files, avoiding timeout error messages and increasing efficiency on loading the file in the backend. Improve efficiency on service delete, too.
* Ingress-controller: Update Golang to 1.16.3 and use Alpine 3.13 for all Golang images

#### Fixed

* Admin-UI: Fix ingress routing issue with some service dashboards where permissions were missing
* Admin-UI: Fix page redirect after deleting a container resource
* Admin-UI: Fix missing cache-cleaning when reloading web-app after version upgrade in some browsers
* Docker: Fix docker image permission check if the license requires exact match, where the permission check erroneously reported that the current license does not have permission for some docker image
* InfluxDB protocol: Fix occasional crash on disconnection which unfortunately caused a protocol-mapper crash
* Container-manager: Fix startup behavior
* Fix re-attaching ingress route on restarting connectware if a service is enabled (broken since 1.0.33)
* Fix service delete/install via REST API not showing up in UI (broken since 1.0.34)

## What has changed in 1.0.37?

This next regular maintenance release of the Connectware comes with some improvements in most protocols about the reconnection timing, more stability towards handling very large commissioning files, and some more bugfixes and minor updates all across the board.

#### Added

* All protocols: Add incremental delays for re-connection attempts, so that instead of trying a reconnection every 1 second, the waiting time is now increasing until 30 second maximum, and can be configured by the `connectionStrategy` property, see [Cybus::Connection](/data-flows/service-commissioning-files/resources/cybus-connection)

#### Changed

* Upgrade BACnet stack to version 1.0.0
* Update various npm packages with minor and major version updates
* Container-manager: Fix startup procedure of container-manager to not have it exit multiple times
* OPC UA client: minor [user docs improvement](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#nodeid-string) to clarify nodeId syntax

#### Fixed

* Fix service delete/install via REST API not showing up in UI
* Improve loading of large files in REST: Re-use Parser results in Service constructor
* Admin-UI: fixed rendering of service metadata in service details view
* OPC UA server: Finish exposing metadata for historizing aggregations
* Influxdb: Simplify the topic name for InfluxDB endpoints

## What has changed in 1.0.38?

Our next regular maintenance release of the Connectware comes with some bugfixes in various protocols, an interesting new polling [schedule feature](/data-flows/service-commissioning-files/resources/cybus-endpoint#polling-interval-and-subscribe) on endpoints, and overall speed and stability improvements.

#### Added

* Some protocols: Cron expressions for polling at [fixed time points on endpoints](/data-flows/service-commissioning-files/resources/cybus-endpoint#polling-interval-and-subscribe) have been implemented.

#### Changed

* InfluxDB: Simplify the topic name for InfluxDB endpoints. The topic name for endpoints now uses either the name of the measurement for writing or “data” for read/subscribe

#### Fixed

* Agents: Fix missing mqtt scheme when creating the internal MqttConnection, causing problems for agents that want to use “mqtts” instead of “mqtt”
* OPC UA: Better error reporting with MonitoredItemGroup in case of initialization failure

## What has changed in 1.0.39?

Another regular maintenance release of the Connectware. The Admin-UI has been improved in the service details view, and several bugfixes and improvements regarding large number of endpoints have been implemented. And there is the regular share of further stability improvements.

#### Changed

* Admin-UI: Service details page for [updating services](/data-flows/services/managing/updating) restructured: Buttons are placed in a more structured form; install, update, and reconfigure all use the same new two-section window. Further internal refactoring to reduce technical debt.

#### Fixed

* Admin-UI: Services with no parameters will have a clear message about it
* Admin-UI: Rows per page is now fixed on service resource tables and logs tables (but not yet on tables elsewhere)
* Admin-UI/Explorer: Let mapping topics with named wildcard show messages in history
* Admin-UI: Better error reporting when handling a service runs into an error
* Service deviation detection: Fix deviation tracking and reporting for Endpoints, also for larger number
* Admin-UI Deviation detection: Collect deviation events before emitting them, to fix freezing admin-ui on larger number of endpoints
* Admin-UI: Available Service Catalog version is now always displayed on the service details page
* OPC UA: Better cleanup after early termination of MonitoredItemGroup
* Licensing: Fix expiration date to correctly keep working until day’s end of that date
* BACnet protocol: fix potential leftover polling timers to avoid double messages after fast reconnections or service updates

## What has changed in 1.0.40?

This is a bugfix release to improve the behavior on two issues recently discovered. In the Admin-UI, the “links” buttons are fixed again, and in BACnet the disable/enable behavior has been improved. Also, minor other updates are included.

#### Fixed

* BACnet: Fix leftover connections (“zombie”) after disabling some BACnet services. This also enables the `cronExpression` property for BACnet endpoints.
* Admin-UI: Fix broken “Links” urls on the service detail pages

## What has changed in 1.0.41?

This next regular maintenance release of the Connectware comes with some bugfixes in various protocols, some helpful new configuration properties for [OPC UA connections](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#connection-properties), and overall speed and stability improvements.

#### Added

* OPC UA client: Add configuration property maxMonitoredItemsPerCall in [OPC UA connections](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#connection-properties). This allows to let the group registration be done with the given maximum number of items per call, if the server requires such a restriction.

#### Changed

* Admin UI: Further refactoring to prepare login with different permission sets. On a changed connectware version the admin-ui will now logout.

#### Fixed

* Admin-UI: Revert service “links” style into buttons again
* Admin-UI: Fixing issue where non-default parameters would not be loaded in update dialog
* Admin-UI: Fix missing connection host/port to be displayed in overview table
* Service manager: Fix waiting time upon service start that causes very long time on restart
* Heidenhain protocol: Fix unhandled promise rejection on agent restarting by fixing missing await. Fix sanity check on disconnect. Also, fix lookup of instance name in ‘instanceGone’ event. Add more sanity checks where appropriate. Should fix missing reconnection on machine restarting.
* Container-manager with more robust startup to run multiple attempts to instantiate a ProtectedDocker instance

## What has changed in 1.0.42?

Our next regular maintenance release of the Connectware comes with some bugfixes in various protocols, an interesting new protocol [Systemstate](/connectors/enterprise-connectors/systemstate) for notifications of internal states, and overall speed and stability improvements.

#### Added

* Systemstate protocol: Added a new protocol [Systemstate](/connectors/enterprise-connectors/systemstate) that enables access to internal Connectware events as mqtt messages.
* OPC UA Server: New Object Type [Opcua:Reference](/connectors/servers/opc-ua-server-references) was added for usage in commissioning files. This enables users to reference preexisting nodes and structures in a commissioning file. The Reference type also creates an MQTT topic that publishes the value of the nodeId.
* Deployment: Adds initial support for running Connectware in a Kubernetes cluster
* Influxdb protocol: Added writing of multiple data records per message for InfluxDB.

#### Fixed

* Fix missing MQTT endpoint/connection schema validation in service manager
* Influxdb: Added default value `http` for connection scheme
* Heidenhain: Make sure to not do anything if we are disconnected, to avoid any activity after service disabling.

## What has changed in 1.0.43?

Another regular maintenance release of the Connectware. There are some helpful improvements in the commissioning file and in handling of container networks, and there are performance improvements in MQTT and S7 protocol. Also, the user interface has been worked on to fix some minor bugs and improve stability in general.

#### Changed

* Commissioning files: The agentName of an Endpoint does no longer need to be specified but is looked up from the Connection resource
* Container manager: Networks that are created by deploying container resources are now cleaned up again on service disabling
* Kubernetes: improve manifests, broker clustering, and volumes.
* Admin UI: Add alternative permissions for services table and extend REST endpoint

#### Fixed

* S7 protocol: Fix “BAD 255” values when polling
* MQTT protocol: Ensure that we never publish to a MQTT topic with wildcards, as this would terminate the mqtt connection immediately.
* MQTT Performance: Improve auth-server performance for handling many mqtt clients
* Admin UI: System Control Service changes for improved stability
* Admin UI: Fix service links on the admin web ui to again open in new tab
* Admin UI: Fixing issues where the services would appear for half a second to not be loaded when first loading the application

## What has changed in 1.0.44?

This next regular maintenance release of the Connectware comes with some minor new feature for special login situations, several usability improvements in the Admin User Interface with earlier error checking, and various stability improvements and bugfixes in the general resource handling.

#### Added

* Implement potential long-lived JWT tokens to be passed in the URL. Those tokens can be created and managed through the REST API and are intended to be used in shop floor display devices where no keyboard login is usually used. (There is no UI to manage those tokens, yet)

#### Fixed

* Distributed agent: Fix too quick discarding of existing credentials, if on re-connecting to the central connectware there is no immediate login possible. Now, the distributed agent will keep re-trying with existing credentials on unreachable connectware and unreachable auth-server.
* Admin-UI: Check and prevent issues with long service Id and too long container names. If the commissioning file contains docker containers, the length of the serviceId is now limited according the the resourceId so that the resulting container name is within the 63 character limit. Before, there was no limit on the serviceId length, but the service enabling would eventually fail due to the limit on the container name.
* Mapping: Fix [setContextVars](/data-flows/rule-engine/data-processing-rules#setcontextvars) rule which was not working correctly, but is documented and working correctly now.
* Auth-Server: Improve performance when querying roles and permissions
* User docs: improve [OPC UA](/connectors/shop-floor-connectors/opc-ua) documentation

## What has changed in 1.0.45?

This regular maintenance release of the Connectware brings another new protocol for connecting to Apache [Kafka](/connectors/enterprise-connectors/kafka) clusters, and some bugfixes throughout the system, in particular with the startup procedure of the system control server, in order to improve overall stability.

#### Added

* [Kafka protocol](/connectors/enterprise-connectors/kafka) implementation. This change adds the Kafka protocol that allows connectivity to Apache Kafka clusters/brokers.

#### Fixed

* User docs: mqtt client [documentation](/connectors/enterprise-connectors/mqtt) improvements
* Improve startup timing of system control server, fixing some conditions where the connection between system control server and container manager was not set up correctly
* Fix parsing error on using `Cybus::MqttPort` [global parameter](/data-flows/service-commissioning-files/parameters#global-pre-defined-parameters) which used to be refused in certain contexts requiring an integer value
* Admin UI: removed beta tag from service catalog menu item

## What has changed in 1.0.46?

Our next regular maintenance release of the Connectware brings a brand-new explorer page in the Admin UI where custom topics can be added, topics can be filters, and topic selection is much improved. Many more bugfixes in the Admin UI and some minor fixes in other areas are added, too, to achieve overall speed and stability improvements.

#### Added

* Admin UI: New Explorer UI is now live: Button for “Add custom topics”, filter by topic types, collapsable history, improved performance
* Admin UI: Extend deviation reporting: Add “reason” to state event
* Distributed mappings: Mappings now can run on agents by specifying an `agentName` property, see [Cybus::Mapping](/data-flows/service-commissioning-files/resources/cybus-mapping)

#### Fixed

* Admin UI: Connection details now displays extended properties
* Admin UI: Fixed rows per page issue on Connections table and on Mappings table
* Admin UI: Fixed sorting issues on Connections and Mappings table
* Admin UI: Fixed issue with explorer UI where one could not copy JSON topic messages on the UI
* Admin UI: Fixed issues with Sections expansion on Services (and now Connections)
* Admin UI: Fixed issue on Admin Web UI where previous service parameters would be overwritten by the new default ones
* Admin UI: Fixed issue where appbar breadcrumbs would use singular name instead of plural
* Admin UI: Fixed issue with Admin Web UI rendering the wrong breadcrumbs on User and Role views
* Auth-server: Fix creating and reading of roles with no permissions
* OPC UA Server: Fix wrong if-clause before accessing this.\_historyManager

## What has changed in 1.0.47?

This regular release of the Connectware brings significant improvements in the Mapping resources by adding the possibility to list many [subscribe](/data-flows/service-commissioning-files/resources/cybus-mapping#subscribe) topics for a single mapping, together with the [collect](/data-flows/rule-engine/data-processing-rules#collect) rule to combine these easily. The user interface for the Mapping got improved by displaying the data directly on the Admin-UI, together with potential errors from rules, to make rule debugging significantly easier and faster. The [OPC DA](/connectors/shop-floor-connectors/opc-da) protocol has been extended to support also simple write endpoints and an OPC DA bug with newer windows versions was fixed. Also, some more documentation improvements have been implemented, and more bugfixes in Mapping and OPC UA Server have been implemented.

#### Added

* Mapping: Support multiple endpoints/topics in Mapping subscription and add new collect rule (see [subscribe](/data-flows/service-commissioning-files/resources/cybus-mapping#subscribe) and [collect](/data-flows/rule-engine/data-processing-rules#collect))
* Admin UI: Add new MQTT message display in Mapping page, and also displaying errors from Mapping Rules directly in the Mapping page.
* OPC DA: The write operation was implemented on the [OPC DA](/connectors/shop-floor-connectors/opc-da) protocol.
* User docs: Explain the definition of array parameters better in documentation (see [Additional properties for arrays](/data-flows/service-commissioning-files/parameters#additional-properties-for-arrays))
* User docs: Add docs about system requirements (see [System Requirements](/deployment/installing-connectware/system-requirements))
* User docs: Complete list of S7 data types (see [Siemens SIMATIC S7](/connectors/shop-floor-connectors/siemens-simatic-s7))
* OPC UA Server: add config settings for max connections server in [Custom Server Properties](/connectors/servers/opc-ua-server#custom-server-properties)

#### Fixed

* OPC DA: Fix OPC DA protocol version for newer windows versions to fix `RPC_E_INVALID_HEADER` error message
* Mapping: Fix potentially duplicated messages on re-enabled mapping, especially when connecting to an external MQTT broker northbound
* Admin UI: Choose default MQTT message display types similar to what they have been before

## What has changed in 1.0.48?

This regular release of the Connectware brings improvements to the Admin UI in the Permissions and Roles section, improvements to the Protocol Mapper in the form of OPC UA object crawling, support for MQTT V5 options in the MQTT endpoints and connections, and improved support for mutual TLS verification for the Broker.

#### Added

* Admin UI: New system role with limited permissions added
* Platform: Add env file option `CYBUS_BROKER_USE_MUTUAL_TLS` for mqtt mutual TLS configuration (NOTE: docker-compose.yml file change)
* Protocol Mapper: Add MQTT5 support in MQTT protocol for both connection and endpoint

#### Changed

* Admin UI: Improved License management on Admin UI, the license information, including id, can now be viewed by every user on the Connectware and other general improvements
* Service Manger: Decrease log verbosity of systemstate protocol connections

#### Fixed

* Broker: Fixes in mutual TLS code and configuration
* Protocol Mapper: Fixes for crawling of OPC UA structures
* Service Manager: Fixes to deviation tracking
* Admin UI: Improved permissions management

## What has changed in 1.0.49?

This regular maintenance release of the Connectware brings a new overview table of all “links” (e.g. dashboard buttons) in the Admin-UI, some more improvements in the recently overhauled Explorer page, and some more bugfixes in OPC UA protocol, SQL protocol, Kafka protocol and throughout the software.

#### Added

* Admin-UI: Created Services Link table under the resources navigation tab, available also for non admin users
* Kubernetes deployment: Added initial Helm chart integration

#### Fixed

* Admin-UI: Fixed issue with table sorting being reset after new items are added
* Admin-UI Explorer: Now showing grayed out topic check-boxes if the children beneath it have multiple selection states. Added unsubscribe button to Monitored Topics section. Fixed issue with topic messages or paths being too long. Do not load topics that the user does not have permission to subscribe to. Instantly display monitored topics if they do not contain a wildcard
* OPC UA: Detailed error logging for createmonitoreditems request
* SQL protocol: Placeholders for SQL read endpoints
* Kafka protocol: Improved Kafka connection state handling
* Service Manager: Fixes to usage reporting

## What has changed in 1.0.50?

Our next regular maintenance release of the Connectware brings further user interface improvements in the Admin-UI Explorer page, as well as improved Kubernetes deployment capabilities using a Helm Umbrella chart. Also, some bugfixes in the Admin-UI and also the rest of the software are improving the overall stability.

#### Changed

* Admin-UI Explorer: Added a new popover to display resources associated with a topic
* Admin-UI Explorer: Now it is possible to filter topics by their associated resource
* Admin-UI Explorer: Now removing irrelevant topics
* Admin-UI Explorer: Now hiding Admin UI Explorer's monitored topic action buttons when not hovered

#### Fixed

* Admin-UI: Fixed issue where publish endpoints would cause an error on the recently added Admin UI, either in the mapping detail page or in more places of the admin-ui
* Admin-UI: Added loader screen after login while waiting for some UI components to initialize fully, to avoid showing an empty screen instead

#### Changes for Kubernetes deployment

* Container-manager: Adapt container-manager to k8s, so that at least its first set of features (logs, container creation and deletion) are available in k8s as well
* Broker cluster self-healing
* Change Broker k8s Service to an StatefulSet
* Make resource requests and limits configurable in the Helm chart
* Add namespace to container-manager roles
* Add an init container to the broker-cluster deployment

## What has changed in 1.0.51?

This regular maintenance release of the Connectware brings a set of bugfixes in various protocols. The “write” operation now has return values added. And various improvements are implemented throughout the code.

#### Changed

* All protocols: The “write” operation will now also return a response value
* Ingress: Increase possible number of incoming connections by adding possibility to configure the maximum number of connections in ingress-controller. The env variable `MAX_TCP_CONNECTIONS` (default: 10,000) is added to the docker-compose.yml configuration file (previously the maximum was 1024). (NOTE: docker-compose.yml file change)

#### Fixed

* OPC UA client: Fix BadTooManyOperations error on unsubscribing from servers with MaxMonitoredItemPerCall limits
* OPC DA protocol: string type for values is fixed again
* Container-manager: Fix to work on Kubernetes by adding k8s namespace and docker ingressHostname as configuration variables
* Agent: Fix accidental dropping of credentials on receiving a HTTP 504 response code

## What has changed in 1.0.52?

Our next regular maintenance release of the Connectware makes the explorer page even more powerful, and well-performing even for very large number of subscribed topics and messages. Additionally, in the S7 protocol there is an important bugfix, in the SQL protocol the connectivity to PostgreSQL has been added, and some more performance improvements have been implemented.

#### Added

* SQL Protocol: Support for [connecting to PostgreSQL databases](/connectors/enterprise-connectors/sql#connection) has been added

#### Changed

* Auth-server: The internal databases have been optimized to improve performance on large number of connecting clients
* Connectware containers: The startup log messages of the node.js containers have been improved and skip the distracting info messages about added GET etc. routes.

#### Fixed

* Admin UI: On home screen, fix the displayed number of services
* Admin UI: On login, always redirect users to the home screen regardless of the previous URL, to avoid displaying confusing permission error messages
* Admin UI: Fix explorer page for large number of topics so that the browser does not freeze anymore and many messages can be displayed
* S7 protocol: Fix undefined variable in code, causing crash on “Bad 255” occurrence (unfortunately introduces in CYB-2933 version 1.0.43). Fixed now.

## What has changed in 1.0.53?

This regular maintenance release of the Connectware adds a new overview table for the current system usage, and contains some important bugfixes concerning deviation tracking, OPC UA writing to SIMATIC S7 OPC UA servers, and ADS connectivity. The performance for large numbers of resources is also being improved continuously.

#### Added

* Admin-UI: Add new information in page System -> Metrics where the collected usage numbers are shown in a table view.

#### Fixed

* Fix deviation display problems when larger number of resources are being used. Sometimes the Admin-UI shows deviations even though the resources were working fine, which has been fixed now.
* OPC UA: Fix failing write for S7 OPC UA servers. Also, an error message is logged in case OPC UA write is failing.
* ADS: Fix connection problems for when the net ids and port are invalid causing the protocol-mapper to enter in a reconnect loop and crash.
* Admin-UI: Now showing connecting label on button while connection is connecting on the Admin UI. Fixed issued where influx db connection would not reconnect
* Admin-UI: Fixed issue where user without admin service custom routes access would be thrown in a authentication loop and the user cannot login anymore

## What has changed in 1.0.54?

Another maintenance release of the Connectware is available, this time also bringing new HTTP OAuth authentication support, and EUROMAP 77 features in OPC UA server, and some useful bugfixes especially at the Admin-UI. Additionally performance and stability got improved in general.

#### Added

* HTTP protocol: Add OAuth Client Credentials authentication support to HTTP Protocol, see [Oauth 2.0 Client Credentials Grant](https://docs.cybus.io/pages/n3tWloQNT8Iu3zL9xXZQ#oauth-2.0-client-credentials-grant)
* OPC UA: Add basic EUROMAP 77 integration, so that the OPC UA server can serve the data in EUROMAP 77 format by using the suitable `nodesetFiles` property in the [configuration](/connectors/servers/opc-ua-server#custom-server-properties)

#### Fixed

* Admin-UI: Fix empty services list when switching between pages
* Heidenhain protocol: Fix parallel reconnect trigger if multiple instances are being used
* Kubernetes deployment: Fix service-manager volume mounting issue at startup

## What has changed in 1.0.55?

This regular maintenance release of the Connectware brings performance improvements for large number of MQTT users, some fixes in the Admin-UI frontend where the pages were not displaying, and overall some updated and improve stability.

#### Changed

* Auth-Server: Improve authentication performance for large number of MQTT users by caching the login credentials also on MQTT logins (which have already been cached for HTTP logins since many versions)
* System-control-server, Admin-UI: Fix all outdated mentioning of portal.cybus.io as backend URL, which has been replaced by a new backend URL graphql-server.cybus.io since version 1.0.49. (Yes, the DNS name is somewhat technical, but that’s the current setup.) The features requiring online connection (license update, Service catalog) use the new URL since version 1.0.49 but the preflight checks were still mentioning the old URL, which is fixed now.
* Introduces a barebone protocol-mapper-base docker image ‘protocol-mapper-base’ that can be used for creating special protocol-mapper agent Docker images that implement custom protocols

#### Fixed

* Admin-UI: Fix several “vrpc connection lost” bugs by setting up the backend connection in a better way
* Admin-UI: fix connectware metrics ordering in display
* Usage metrics: Fix collecting number of messages in case of power cycling of broker to avoid negative numbers

## What has changed in 1.0.56?

Another maintenance release of the Connectware is available with plenty of bugfixes all around the product. REST endpoints for bulk user handling are added, some dependencies have been updated, HTTP proxy handling has been improved, and bugs with GenericVrpc, distributed agents, and in the Admin-UI have been fixed.

#### Added

* Auth-server: Add REST endpoint for bulk insertion and deletion of users

#### Changed

* Workbench: Update node-red version to 2.0.6 (major update from 1.x to 2.0).
* Update node.js version to 12.22.6
* ADS: Allow minimum read interval to be as low as zero, so that it is the user’s responsibility to find a useful minimum value for a given system configuration

#### Fixed

* Admin-UI: Fixed issue where the list of endpoints shows all resources, not only endpoint
* Admin-UI: Fixing issue with occasional connection errors to backend
* Container Startup: At startup when checking for existence of shared files, also check read permissions of those files
* User docs: Fix portal backend address mentioning to be only a non-clickable DNS name
* Distributed agent: Drop credentials only on 401 response. We change the policy on when the stored agent credentials are re-used and when they are dropped: Before, they were dropped on any result (including refused connection due to offline connectware) except a 501 or 503 timeout response from the ingress (which was caused by e.g. a overloaded auth-server). Now, they are dropped only on a valid http connection that gets a 401 response.
* System Control Server: improve license validation and connectivity checks when the system is deployed behind a corporate proxy and add CYBUS\_PROXY environment variables to docker-compose.yml file (NOTE: docker-compose.yml file change)
* GenericVrpc: fix deviation cleanup after reconnect

## What has changed in 1.0.57?

This regular maintenance release of the Connectware brings many internal version updates, some stability improvements on restarts and shutdowns of containers, and a User Interface for managing certificates.

#### Added

* Admin-UI: Add certificates management on the Admin UI (under the User Management menu), or /api/certificates HTTP endpoints.

#### Changed

* Service-manager: Allow the “protocol” property of Connection and Endpoint to be set to an arbitrary value. Validation of child properties is skipped if the value is not one of the known list of protocols. In those cases validation is now done upon enabling those service and resources, not at installation time.
* Version updates: Node.js from 12 to Node.js 14 in all containers; alpine runtime base image from 3.11 to alpine 3.12; VerneMQ to 1.12.3; node-opcua to 2.50.0

#### Fixed

* Add correct handling of SIGTERM in containers, so that shutdown/restart of containers works considerably faster and under more control.
* Admin-UI with reduced permission: Fix interpretation of readWrite to be accepted for read, too
* Protocol-mapper: Improve error messages if x509 certificate errors are encountered during startup (such as expired internal certificates)
* GenericVrpc: Fix crash on disable GenericVrpc resource
* Fix auth-server startup warning about unknown sys-protocol-mapper user

## What has changed in 1.0.58?

Our next regular maintenance release of the Connectware brings a few bugfixes in various areas, and a small improvement for the license file at startup, especially for installation without Internet connectivity. Minor bugs have been fixed in OPC UA, S7, HTTP, and the installer script, and the overall stability has been improved.

#### Added

* License file can be passed to system-control-server by injecting an environment variable (see [Uploading License File into Connectware](/deployment/licensing#setting-up-your-license-using-environment-variables)), especially for installations without Internet connectivity

#### Fixed

* OPC UA Server: Fix publishing of retained MQTT message
* User docs: clarify dot operator in JSONata which gives confusing behavior if input messages are of array type
* Fix installer –download-license-file option to be identical to the download from Portal website (NOTE: connectware-online-installer.sh file change)
* Set default proxy configuration to empty in installer template (NOTE: connectware-online-installer.sh file change)
* S7: minor improvements in error logging on connection timeouts
* HTTP: Fix http probe on cleared \_client

## What has changed in 1.0.59?

Another maintenance release of the Connectware brings several new features all around the product: Ingress routes can be extended with custom http headers to enable automated log-in at service webpages; Kafka gets more properties; OPC UA can be used with event subscriptions; OPC UA now has PLCOpen node types for S7 servers; Modbus gets more data type byte orders. Also, many bugfixes in the Admin-UI and several protocols have been implemented, increasing overall stability and performance.

#### Added

* Ingress routes: Add support for adding [http headers](/data-flows/service-commissioning-files/resources/cybus-ingressroute) to ingress routes. Adds support for configuring headers to be added to requests processed by Envoy for Cybus::IngressRoutes.
* Kafka: Implemented additional properties at Kafka messages. The [message payload](/connectors/enterprise-connectors/kafka#message-assembly) for the `write` operation of the Kafka protocol was reworked to accept more properties. The main change was that now each MQTT message can hold one or more messages in the payload to be sent to the Kafka Broker.
* OPC UA client: Implement OPC UA [event subscriptions](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#events-for-opc-ua). OPC UA endpoints can now be configured to set up event subscriptions instead of normal node (monitored item) subscriptions. This needs the properties eventTypes and and fields to be set.
* OPC UA client: Implement PLCOpen node types for OPC UA servers running on SIMATIC S7. Some OPC UA servers running on a S7 PLC contains some nodes which use data types from the PLCOpen nodeset files. This change includes this nodeset files into our code, and also introduces a local type cache which should correctly handle the case when the OPC UA server has nodes with those types instead of running into issued with the standard OPC UA types.
* Modbus: Added modbus datatypes floatBEWS and floatLEWS as datatype conversions for word swap float values.

#### Fixed

* Admin-UI: Fixed issue where connections and other resources would be hidden if they were not from the protocol mapper agent.
* Admin-UI: Fixing issue on the Admin UI where one could not consistently disable/delete/enable a cybus resource.
* ADS: Fix endpoint deviation behavior on subscription issues. ADS protocol endpoints will now become deviated when a subscription issue an error.
* FOCAS: Fixed FOCAS connection on disconnect. Improved connect/disconnect methods with a state variable avoid connecting an already connected protocol or disconnect a disconnected one.
* S7: Improve connection tracking for S7
* S7: avoid protocol-mapper crash when attempting invalid reads. Add input validation and slight improvements to response in S7. Improve docs on S7 write operation.
* Modbus: Improve disconnection state handling for Modbus.
* Modbus: Add extra log for Modbus errors and improve disconnect on endpoint failure. Adds an extra error log in the case the jsmodbus library returns an error stating to check the response body of the request.
* Kafka: The kafka protocol Write operation now correctly returns a message on the `/res` topic, indicating either success or an error.
* Kafka: Only reset the connection on KafkaJSNumberOfRetriesExceeded exceptions, not on less severe errors.
* User docs: Fix error in example for collect rule docs
* Installer: Set default proxy configuration to empty to avoid issues on some outdated environments picking up empty string as a value

## What has changed in 1.0.60?

This is our next maintenance release with a set of bugfixes, a minor addition in the FOCAS protocol, and improving overall stability and performance.

#### Added

* FOCAS: Adding new FOCAS methods: cncRdspeed, cncRdspload and cncRdgcode

#### Fixed

* Admin-UI: Fix missing endpoint display if endpoints are on remote agents
* OPC UA server and retained messages: fix typo where an undefined variable was used in the code
* OPC UA events: fix typo in example yaml file
* OPC UA events: fix eventtype filtering for OPC UA endpoints

## What has changed in 1.0.61?

This is a quick maintenance release because in version 1.0.60 the service catalog was unfortunately not working, but is working now again.

#### Fixed

* Fix broken access to Service Catalog

## What has changed in 1.0.62?

This regular weekly Connectware release brings two new features, where the commissioning file now has a new [Cybus::File](/data-flows/service-commissioning-files/resources/cybus-file) resource, and the FOCAS protocol also has the [program\_download](/connectors/shop-floor-connectors/focas) command. Additionally, some minor bugfixes and stability improvements have been added to make working with the Connectware even more powerful and reliable.

#### Added

* Service resources: Add new [Cybus::File resource type](/data-flows/service-commissioning-files/resources/cybus-file) into commissioning file
* FOCAS protocol: implement [program\_download](/connectors/shop-floor-connectors/focas) command (where “download” means loading the file into the PLC).

## What has changed in 1.0.63?

This regular maintenance release brings a set of bugfixes to improve overall stability.

#### Changed

* OPC UA: improve error message if a session cannot be started due to mismatching security mode
* Add user documentation of auto-generated [ServiceID](/data-flows/services/serviceid)

#### Fixed

* Fix [collect](/data-flows/rule-engine/data-processing-rules#collect) rule to use its own storage, not modified by rules later in the chain anymore
* Fix broken deviation tracking for service without endpoints, broken since version 1.0.53
* Auth-server: Prevent removing grant type ‘token’ from ‘admin’ user
* Admin UI: Fix displaying of error messages
* Admin-UI: Fix table bugs on volume overview page
* Admin-UI: fix metrics table sorting by date and time
* Installer: Fix preflight checks to check for all URLs needed

## What has changed in 1.0.64?

* This version has a serious bug with write endpoints, please update to version 1.0.66.

Another regular release of the Connectware brings a set of new features: Endpoints for write operations can now enable additional [buffering options](/data-flows/service-commissioning-files/resources/cybus-endpoint#buffering). Agent [registration](/data-flows/agents/registering-agents-in-connectware) has more options for specifying a password. The SQL protocol has more options for connecting to PostgreSQL databases. Additionally, a whole set of bugfixes for rule engine and service handling has been implemented, along with plenty of performance improvements in the Admin-UI.

#### Added

* Introduce [buffering options](/data-flows/service-commissioning-files/resources/cybus-endpoint#buffering) for endpoints that write to devices
* Agent registration: Allow environment variable for specifying a password on the agent, alternatively to storing a randomly generated password in the local docker volume for [agent registration](/data-flows/agents/registering-agents-in-connectware)
* Services: Add validation of JSONata expression when enabling a service, to get faster and easier problem reporting on issues with JSONata expressions
* Admin-UI: added button for sending usage metrics to portal manually
* [SQL protocol](/connectors/enterprise-connectors/sql): Add support for accessing a postgres database over a SSL connection

#### Fixed

* Services: Fixes retain property not working on Endpoints
* Services: Fix missing re-evaluation of `CYBUS_MQTT_ROOT` variable on reconfigure/update of a service
* Rule Engine: Create independent stores for each collect rule usage, so that it behaves correctly when used at different stages of a pipeline
* Admin-UI: Better displaying errors on Admin UI
* Admin-UI: Fix issue when endpoint resources on agents were sometimes not displayed
* Admin-UI: Fix overview page of service links to only show services that in fact have links
* Admin-UI: Fixing issue where the Admin UI Explorer would temporarily stop working when displaying large messages
* Fix bootstrap.sh syntax error that could cause a crash loop of system-control-server on startup

## What has changed in 1.0.65?

* This version has a serious bug with write endpoints, please update to version 1.0.66.

This next maintenance release of the Connectware brings some more user configuration options, some downloads of metrics data, new response messages also for HTTP POST requests, and plenty of bugfixes in many areas.

#### Added

* Users: Adding environment variable `CYBUS_ADMIN_USER_ENABLED` which can be switched off to disable the default admin user, see [Default Admin User](/access/user-management/users/default-admin-user) (NOTE: docker-compose.yml file change)
* Admin-UI: added download possibility for a usage metrics report
* HTTP protocol: Add response message on write endpoints also for the HTTP protocol on [POST requests](/connectors/enterprise-connectors/http-rest#publishing-data-to-a-rest-server).

#### Changed

* System-control-server: Storage location for some cache data is changed from certs volume to systemControlServerData volume. Old data is copied to new location, and also not removed from old location so going back to older Connectware version is possible.
* User docs: Improve FOCAS documentation, especially for [methods](/connectors/shop-floor-connectors/focas#focas-methods)
* Update Node.js to 14.18.1 and pkg to 5.4.1
* MQTT: Improve diagnosis of specific error condition when target host refuses connection due to keepAlive=0 parameter, which happens with newer mosquitto servers.
* Broker: Removes stunnel process from broker container (that was a proxy for the TLS connection to the auth-server) and replace it with direct connection to auth-server

#### Fixed

* Admin-UI: Fix missing mqtt topics in explorer from agent, so that Explorer now shows all topics on central and distributed protocol-mapper agents.
* Container-manager: Improve stability of microservice initialization on Kubernetes to avoid issues with VRPC connections
* Broker: Fix and improve broker startup script
* Connection: Fix unneeded persistence of connections during startup phase

## What has changed in 1.0.66?

This regular maintenance release brings a set of bugfixes to improve overall stability. In particular, one important bugfix for write endpoint connection loss is included, where the bug is affecting 1.0.64 and 1.0.65 but is fixed in this version.

#### Changed

* Installer: Use curl in favor of wget and force IPv4 lookup for wget to fix IPv6 issues
* Admin-UI: Refactor server and node pages to new code standard. Refactor container-manager display pages to new code standard, fixing table sorting and rows per page issues for these pages

#### Fixed

* All write endpoints: Fix missing subscribe of response endpoint after state change. This fixes a serious bug in version 1.0.64 and 1.0.65 concerning all write endpoints, which were not re-establishing their connection after a connection loss and re-connect.
* Fix [SetContextVars](/data-flows/rule-engine/data-processing-rules#setcontextvars) rule not working properly with context vars and rules
* Modbus: Improving stability by fixing one seldom crash due to unhandled error event

## What has changed in 1.0.67?

This next weekly maintenance release includes another set of bugfixes in Kafka, Modbus, Rule Engine, and other areas. Also, user documentation has been improved, and Beckhoff/ADS implementation has been rewritten significantly.

#### Changed

* User documentation improvements: Documenting the input/output format of read and write endpoints for Influxdb, Modbus, MQTT, SQL
* ADS re-implementation. This enables the capability of writing/reading complex data types like struct types.
* Improve startup synchronization between microservices by letting the dependent ones wait on their dependencies before continuing with startup
* OPC UA: improve error logging for MonitoredItem errors
* Kafka: Better error reporting by printing topic names in log messages.

#### Fixed

* Kafka: Fix erroneous extra properties on address object, causing errors on protocol-mapper restarts
* Fix changing env-1.0.sh content order that caused subsequent crash loop when downgrading to Connectware version 1.0.64 or older
* Modbus: general error handling improvements, in particular fixing an unhandled error event during reconnection, causing the protocol-mapper to crash and restart
* Rule Engine: Fix SetContextVars rule not working properly with context vars and rules

## What has changed in 1.0.68?

The next Connectware release brings the new feature of [password policy](/access/security/password-policy-configuration) specification, an important bugfix for mapping subscription clean-up and another one for FANUC FOCAS protocol, and user interface improvements such as the display of inter-service dependencies on the service page. Many more bugfixes and changes improve overall stability and reliability even further.

#### Added

* User password policy: Add [password policy configuration option](/access/security/password-policy-configuration). This feature makes it possible to configure password complexity policy rules in the Connectware using an environment variable called `CYBUS_AUTH_PASSWORD_POLICY_RULES`. Note: As the initial installation also sets an initial password for the default admin user, this initial password can be set by the newly implemented environment variable `CYBUS_INITIAL_ADMIN_USER_PASSWORD`. If this was forgotten and the initial password is rejected due to a stronger password policy, the initial setup will immediately terminate. (NOTE: docker-compose.yml file change)
* Admin-UI: Now show inter-service dependencies on service detail page (both: dependsOn and dependent services) and also if enabling/disabling a service will concern other services as well
* User docs: Add docs for generating [API tokens](/access/security/json-web-tokens) by the REST interface

#### Changed

* Admin-UI: adjust metrics table headings for number of messages. Update user documentation of metrics page.
* Modbus User docs: Update usage of /res /req /set in modbus docs
* Only exit protocol-mapper after several consecutive failed broker authorizations
* Further improvements in startup timing for Kubernetes and Docker Compose
* Add consistent startup message across services: Adds the message ‘Connectware service bootstrap completed’ to all of our own-implemented services.

#### Fixed

* Mapping subscription cleanup (high-severity bugfix): Bugfix for exception at subscriptions cleanup with cronTask, introduced in version 1.0.40 and apparently never being noticed. The bug surely causes erroneous double- subscription, but potentially also additional follow-up errors.
* FANUC FOCAS protocol (high-severity bugfix): Fix endpoints mix-up when connecting more than one machine.
* Broker: Show clear error message at startup on missing file permissions: If the broker container has no write permissions on the file /vernemq/etc/vm.args and the file ends up empty, the VerneMQ process shows a weird error message and is stuck in a crash-restarting-loop. With this change, the broker will still not yet start correctly, but at least show a clear error message.
* Kafka: Fix broken KafkaEndpoint stored persistence. The error on storing Kafka endpoints (since 1.0.59) is being detected since 1.0.67 but is now handled even more gracefully by just fixing this particular storage problem, causing the endpoints to load fine again in any case.
* Endpoints: Avoid unhandled promise rejection error when an endpoint reference was incorrectly written in the commissioning file
* Admin-UI: Fixed container names of core containers being displayed only partially in the container detail pages
* Admin-UI: If the default admin user is disabled, it will be no longer shown in the list of users.

## What has changed in 1.0.69?

This regular Connectware maintenance release brings a set of bugfixes in the area of service handling, exception handling on C++ libraries, systemstate protocol, and REST endpoint. Also, the user documentation has received some minor updates and overall stability has been improved.

#### Fixed

* Services (high-severity bugfix): Fix broken vrpc event listener un-registration in services, causing increasing vrpc traffic on every single disable/enable of any service.
* Catch unhandled exception error on some C++ protocols if they encounter issues so that this does not crash the protocol-mapper anymore.
* User management: Fix error on mqtt topic permissions that did not accept topics with spaces, although these are valid mqtt topics.
* User docs: Add recently added protocol names in the user documentation of connection and endpoint
* User model: Fix erroneous database transaction implementation on user creation
* Systemstate protocol: Fix systemstate signalling of initial resource
* Fix missing permissions for new REST endpoint `/api/policy/password` (read-only)
* Admin-UI: Fixing an irrelevant error display about the `internal` connection in the connection page

## What has changed in 1.0.70?

This next maintenance release includes another set of bugfixes in the Admin UI, in service life cycle management, and various other areas. Also, with some regular component updates and bugfixes the overall stability and performance has been improved.

#### Changed

* Upgrade node-opcua from 2.50.0 to version 2.62.7

#### Fixed

* Admin-UI: Fixed issue on Admin UI where Connection page would never finish loading if the list is empty
* Admin-UI: Now correctly hiding the `internal` connection from the list.
* Admin-UI: Technical debt reduction for “agents” page. Fixed sorting and pagination issues with UI for agents page
* OPC UA: Add log message warning and improve description for missing resourcePath property
* Services: Fix container issues after service delete, where on incomplete delete some containers might not be removed, but are removed now.
* Protocol-mapper: Increase error message verbosity on protocol-mapper batch create problems with persisted resource parameters
* Broker startup: Check for empty configuration file, and error out with a clear message if this situation occurs to avoid unnoticed startup errors
* Auth-server: Improve model implementation to use database transactions in a cleaner way, making the code much more robust and reducing technical debt.
* Auth-server database: Fix remaining roles and permissions that were left behind on the database when deleting users.
* Auth-server: Fix missing routing permission for new REST endpoint /api/policy/password

## What has changed in 1.0.71?

This regular Connectware maintenance release improves some issues with service parameters, authentication stability, Beckhoff/ADS protocol implementation, ingress routes, and user documentation clarifications.

#### Changed

* [ADS protocol](/connectors/shop-floor-connectors/ads): More stability improvements. New properties on AdsConnection to handle connection checking process: routerTcpPort, timeoutDelay. The connectionCheck can be disabled or configured in more detail. localAddress and localPort properties are now explicitly marked as required, because the implementation requires them.
* ADS user docs: Clarify endpoint MQTT topics and response messages
* Heidenhain: Clarify user docs about endpoints and response message. Also, change `write` endpoints to also return a response message.
* Sopas user docs: Clarify write endpoints and response messages
* Pfannenberg user docs: Clarify write endpoints and response messages
* Admin-UI: Technical debt reduction in deviation handling, simplifying code base.

#### Fixed

* Services (high-severity bugfix): Fix `Cybus::MqttHost` [global parameter](/data-flows/service-commissioning-files/parameters#global-pre-defined-parameters) value that was broken since version 1.0.67 because the connectware’s internal hostname for the broker (`broker`) is different from what service containers need to use (`connectware`). This change introduces a `CYBUS_MQTT_HOST_FROM_SERVICES` environment variable to configure this differently if needed. (NOTE: docker-compose.yml file change)
* Auth-server (high-severity bugfix): Increase authentication stability by using only exactly one instance of the UserModel code, decreasing occurrences of closed auth connections even more
* Ingress-controller (high-severity bugfix): Fix broken ingress routes if multiple routes should target the same container host but with different port numbers
* Ingress-controller: Fix bug causing multiple updates when there are multiple ingress routes with the same target container host.
* Admin-UI: Fixing errors on the Mapping page for services with distributed agents

## What has changed in 1.0.72?

This next maintenance release includes another set of bugfixes in the Admin UI, the auth-server performance, and user documentation. Also, the web tokens can now be used for authentication, as needed e.g. for displaying status pages without having to enter a username and password in the browser.

#### Added

* Admin-UI: When using long-lived [JSON Web Tokens](/access/security/json-web-tokens), the possibility to use this token for authentication was added, see [Browser Authentication](/access/security/json-web-tokens#browser-authentication), where the token is specified by an extra apiToken URL parameter. This authentication can be used for either Admin-UI pages, or to access service containers according to their ingress routes. Both cases can be interesting for displaying status pages without having to enter a username and password in a browser.

#### Changed

* Auth-server: Further work on optimization of authentication by adding an extra function that is optimized only for this authentication
* Admin-UI: For ADS connections, display the Ads routerTcpPort as port number (instead of the uninteresting AMS port number)
* Admin-UI: Order items in permission lists for users and roles alphabetically
* Auth-server: For custom password policy configuration, improve the handling in client registry procedure by returning a special status code (422) on unsatisfied password complexity, and adapt the remote distributed agent to respond accordingly, so that distributed agents will work with client registry and any password policy.
* OPC UA client: Improve error log message on problems with OPC UA type mismatch
* BACnet user docs: Extend docs for BACnet read/write
* FOCAS user docs: set/res endpoint documentation for the FOCAS protocol.
* SINUMERIK user docs: documentation added for set/res endpoints

#### Fixed

* Admin-UI: Fixed issue where Admin UI’s explorer page would take user to the wrong resource page in the hover-over box on some mqtt topic
* Admin-UI: Fixing issue on Admin UI where messages in the Explorer page would not appear

## What has changed in 1.0.73?

The weekly maintenance release of the Connectware includes two important high-severity bugfixes, for Mapping and for Kubernetes installations, as well as one new page in the Admin-UI for **Rule Engine Sandbox** and the new feature of MQTT topic prefixes. Additionally, many other areas received some bugfixes and stability improvements.

#### Tasks and Features

* Admin-UI: Implement **Rule Engine Sandbox** page for live evaluating Rule Engine transformation [expressions](/data-flows/rule-engine/data-processing-rules#expression)
* New Feature: The MQTT broker can be configured to add an automatic MQTT topic prefix to incoming published MQTT messages, see [Adding an MQTT Publish Prefix for Users](/access/user-management/mqtt-user-authentication/adding-an-mqtt-publish-prefix), especially suited for high-throughput installations
* Admin-UI: Feature request: Save Table View Settings
* Auth-server optimization: Optimize User.read() method for Broker auth
* User docs: Document result of using /set /res endpoints for protocol MSSQL

#### Bugs fixed

* Connection handling (high-severity bugfix): Mappings are stopping forwarding messages on certain combinations of disconnect/reconnect events
* Postgres on kubernetes (high-severity bugfix): crash loop on startup due to missing permission for chmod, related to PGDATA environment variable. This is fixed with the current Helm chart and this Connectware version
* Admin-UI: Wrong message on service deletion confirmation popup
* Admin-UI: Password should not be stored after login on the Admin UI
* Admin-UI: Error when displaying Service Details Page after installing a new service from a commissioning file
* Admin-UI: Service details were not updated when uploading a file for a catalog service
* Service validation: Mapping resources should validate rule names and properties
* OPC UA Server: Clarify property “alternate hostname” which is needed always (to be renamed soon)
* OPC UA client using events: Fix unhandled promise rejection for invalid nodeId in eventType

## What has changed in 1.0.74?

This regular bugfix release includes ones important high-severity bugfix concerning the `qos` property in endpoints, another important change for Kubernetes deployment (unrelated to deployments using Docker Compose), and a set of additional bugfix and stability improvements.

#### Tasks with minor additions

* OPC UA user docs: Clarify [documentation](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#opc-ua-subscriptions) about session, subscription, monitored item groups

#### Bugs fixed

* Endpoints (high-severity bugfix): `qos` property from commissioning file was unfortunately ignored when creating Endpoints, which is fixed now
* Kubernetes deployment (high-severity bugfix): Fix Connectware unable to start due to Postgres mountPath error. This is a breaking change for any Kubernetes Helm chart deployment. However, it does not affect deployments using Docker Compose.
* Kubernetes Admin-UI: Fix missing first letter in list of containers in Admin-UI
* OPC UA server: Rename `alternateHostname` property to `hostname` to clarify its meaning, adapting the [documentation](/connectors/servers/opc-ua-server) accordingly. The old property name is still accepted for backward compatibility, though.
* Services with Docker networks: Detect and log unintended ingress network change
* Admin-UI: Minor layout improvements in explorer page for better understanding on first look
* HTTP Client: Fix missing renewal of OAuth token that is used over longer time periods

## What has changed in 1.0.75?

Our next weekly bugfix release included some bugfix for the `setContextVars` rule in the Rule Engine, some performance improvements for large number of users, and a set of additional bugfix and stability improvements.

#### Tasks with minor additions

* Broker: Improve handling of message rate peaks (reducing potential message loss) by increasing `max_online_messages` parameter and making it available as configuration option
* User documentation: Clarify service [parameter](/data-flows/service-commissioning-files/parameters) array usage (and its limits)
* User documentation: Add missing documentation about response codes for Write operations in all protocols, in particular also for using /set /res endpoints for protocol [EtherNet/IP](/connectors/shop-floor-connectors/ethernet-ip)
* Auth-server: Improve performance for larger number of users and running services at service-manager

#### Bugs fixed

* Rule engine (high-severity bugfix for setContextVars rule): Fix erroneously failing verification of setContextVars rule whose var property needs and object, not array. Fix broken setContextVars rule where the variables could not be used in the publish topic.
* Workbench: Fix global HTTP proxy settings to be applied in workbench, too
* Kubernetes: Extend resource constraints to avoid out-of-memory kills under peak loads
* Admin-UI: Fix missing display wrapping of service cards on service catalog page
* OPC UA client with [events](/connectors/shop-floor-connectors/opc-ua/opc-ua-client#events-for-opc-ua): Fix erroneously ignored field selection from commissioning file

## What has changed in 1.0.76?

This is another weekly maintenance release with a set of bugfixes, some documentation updates, and general maintenance.

#### Tasks with minor additions

* User documentation: Update documentation for [Certificates screen](/access/security/tls-certificates)
* User documentation: Added explanation about the issue with [Docker networks](/data-flows/service-commissioning-files/resources/cybus-container#docker-networks) and alphabetical order of network names.
* MQTT Broker: Configuration changed to increase maximum-topic-depth to 20
* Debugging output: Add explicit clientIds to internal MQTT clients to improve debug output readability
* Update node.js to 14.19.0, alpine to 3.15

#### Bugs fixed

* (High-severity bugfix) Fix MQTT message duplicates that could appear after an internal disconnect/reconnect event, which has been observed seldomly but would be a problem. With this fix, no more duplicates appear.
* Admin-UI: Fix slightly confusing message on empty table on “Service Links” page
* Kubernetes: Extend resource limits to avoid out-of-memory kills under peak loads
* HTTP protocol: The HTTP connection check can now be configured in more detail, see [Connection Properties](/connectors/enterprise-connectors/http-rest#connection-properties). Also, fixed unexpected large number of server connections due to HTTP connection check, if the liveness of the connection has been proven by other activities anyway.

#### Features removed

* Pfannenberg protocol: The obsolete `pfannenberg` protocol has been removed because it was designed for some special devices which turned out to be out of use for quite some time already

## What has changed in 1.0.77?

Our next weekly maintenance release brings a newly designed user management page in the UI, some bugfix for OPC UA Server Historical Access, and a number of further improvements and bugfixes all over the product.

#### Tasks completed

* Admin-UI user management: New User and Roles Management Screen. The pages for user management, role management, and permission overview were redesigned and re-implemented. This gives a much better overview and better user experience for editing all aspects of users and roles.
* Admin-UI user management: Implement the possibility of renaming a user
* Admin-UI user management: Hide auto-generated service users and roles in the user management page by default
* Admin-UI user management: Enable editing the “Per-User MQTT prefix” (available since 1.0.73) in the user management page

#### Bugs fixed

* OPC UA Server Historical Access (high-severity bugfix): fixing missing data on Historical Access request
* Kubernetes: Change the Postgresql volume’s access mode from ReadWriteOnce to ReadWriteMany (RWX)
* Postgresql container shutdown: Fix missing SIGTERM handling to enable graceful shutdown
* doc-server shutdown: Fix missing SIGQUIT handling in doc-server to enable graceful shutdown
* ADS protocol: Specify existing limit on subscribe interval of approx. 7 minutes
* Auth-server: Minor improvements in handling of lost postgresql connection
* protocol-mapper startup: Fix potential startup failure where errors were not causing a clean restart
* Admin-UI user management: Fix error on assigning grant types in user management pages
* User with MQTT prefix: Changed authorization to check MQTT topic permission now with prefix. Note: This might break existing setups which are using “Per-User MQTT prefixes” available since 1.0.73 with very specific permissions, but does not touch any setup that was not yet using this “MQTT prefix” feature.

## What has changed in 1.0.78?

This is another weekly maintenance release with a set of bugfixes in OPC UA and Rule Engine, a new feature for HTTP [query parameters](/connectors/enterprise-connectors/http-rest#reading-data-from-a-rest-server), some documentation updates, and general maintenance.

#### Tasks completed

* HTTP protocol: Added feature to set [query parameters](/connectors/enterprise-connectors/http-rest#reading-data-from-a-rest-server) dynamically from MQTT message
* Admin-web-app shutdown: Fix missing SIGQUIT handling in admin-web-app to enable graceful shutdown of container

#### Bugs fixed

* OPC UA: Fix reconnect handling for many node subscriptions and slow servers that might cause too many requests at the server (high-severity bugfix)
* Rule engine: Fix erroneous refusal of service installation when COV rule uses string array as key
* ADS protocol: Fix error when receiving an INT64 value
* User documentation: HTTP [Connection Probing](/connectors/enterprise-connectors/http-rest#connection-probing) explanation improved

## What has changed in 1.0.79?

Note

This version 1.0.79 is affected by a bug potentially causing instabilities, hence use version 1.0.81 instead.

Our next weekly maintenance release brings a backup/restore function for the user database, an improved version check for distributed agents, several improves user interface pages, some bugfixes for MQTT and HTTP, significant user documentation updates, and improved overall stability.

#### Task completed

* Implemented new backup and restore function for user/role/permission database
* Check connectware version match between protocol-mapper agent and main connectware and refuse startup on mismatch to avoid unexpected malfunction (causing breaking change when trying to use distributed protocol-mapper agents without update)
* Admin-UI: Improve “client registry” page
* Implement system resource monitoring log messages into the container logs

#### Bugs fixed

* MQTT protocol, Mappings: Fix extra duplicated messages if there are multiple overlapping wildcard subscriptions
* HTTP protocol: Fix missing basic auth (username/password) implementation when accessing other HTTP servers

#### User documentation updates

* User docs: Explain route and [permission configuration](/access/user-management/access-permissions-for-admin-ui) when users with lesser permissions should still be able to see certain Admin-UI pages
* User docs: Update “Explorer” page after recent UI changes
* User docs: Update “user management” page after recent UI changes
* User docs: Explain the “Setting of environment” steps in a separate section
* User docs: Ensure that all sample commissioning files work out of the box

## What has changed in 1.0.80?

Note

This version 1.0.80 is affected by a bug potentially causing instabilities, hence use version 1.0.81 instead.

This next maintenance release brings significant stability improvements on Kubernetes deployments, adds a [HTTP/REST server](/connectors/servers/http-server) for POSTing data to the Connectware, makes the password policy visible when changing password, and brings a set of further bugfixes and stability improvements.

#### Task completed

* Implemented [HTTP/REST server](/connectors/servers/http-server) to PUT/POST data to the connectware. (Known issue: The Admin-UI frontend does not list a HTTP server resource in the list of “Servers” - to be fixed in the next release.)
* Admin-UI: Improved password dialog to show password policy when entering a new password
* Admin-UI: Change deviation popups to custom snackbar with link to the list of deviations
* Admin-UI: Show uptime column in container views

#### Bugs fixed

* K8s: Fixing [initial admin password](/access/user-management/users/default-admin-user) issues in Kubernetes/Helm that might be processed wrong if containing special characters. Concerns only deployments using Helm charts using the initial admin password setting: In that case, this is a BREAKING change as the password must now be given in base64 instead of plaintext.
* K8s: Fix not being able to install a service initially due to “vrpc timeout” (high-severity bugfix). Fix role permissions so that statefulset can be queried correctly from broker startup scripts. Fix VerneMQ startup scripts to ensure multi-node broker cluster is found correctly. Implement readiness probe in VerneMQ broker pods.
* HTTP protocol: Fix HTTP token renewal that did not work for write operations
* HTTP protocol: Fix connection state that was shown connected even with wrong authentication credentials
* k8s: Fix ServiceCatalog instance, avoiding vrpc timeout error
* Admin-UI: Minor fix of explorer page styling

#### User documentation updates

* User docs: Adapt documentation to clarify which features are not available on k8s but only on Docker Compose
* User docs: Improve list of Admin-UI access permissions by automating its generation
* Minor swagger docs fix: Fix client registry swagger documentation about returned timestamp

## What has changed in 1.0.81?

This maintenance release fixes a bug potentially causing a service-manager crash in high-load scenarios, hence we released just this bugfix release quickly.

#### Bugs fixed

* (High-severity bugfix) Fix crash in service-manager or other microservices due to missing sanity checking in the CPU/memory monitoring feature. The respective error message in the logs is “SyntaxError: Unexpected token { in JSON”, causing a restart of the respective container. The bug affects versions 1.0.79 and 1.0.80 but is fixed now.
* S7: Fix writing boolean value “false” which was failing

## What has changed in 1.0.82?

Our next weekly maintenance release brings a set of bugfixes in the Admin-UI, some internal updates now using Node.js 16, and overall stability improvements.

#### Bugs fixed

* Admin-UI: Add missing Cybus::Server::Http resource in server list in the frontend
* Admin-UI: Fix button on service update form to not be enabled when it should not
* K8s: Adapt service manager so that commissioning files with unavailable k8s features give a clear error message

#### Tasks completed

* Upgrade to NodeJS 16

## What has changed in 1.0.83?

Note

This version 1.0.83 is affected by a bug preventing deviation tracking after multiple service enabling, hence use version 1.0.85 instead.

This next regular release brings new features in the [Kafka](/connectors/enterprise-connectors/kafka) protocol connector, as well as an important bugfix and change about unifying the service and resource persistence. Additionally, a minor bug in the COV rule has been fixed and overall stability has been improved.

#### Tasks completed

* Kafka protocol: Implementing [Kafka consumer](/connectors/enterprise-connectors/kafka) (i.e. receiving data)

#### Bugs fixed

* Service persistence: Unifying service and resource persistence by moving this information from separate protocol-mapper volume(s) to everything in service-manager. Now all persistence information about services and resources is stored in one common place, namely in the service-manager volume and not any longer in any protocol-mapper volume. The protocol-mapper volume is now not used anymore. Upon upgrade, all change happens automatically and no action needs to be taken.
* Rule Engine: The [Change-of-Value (COV) rule](/data-flows/rule-engine/data-processing-rules#cov) in its `keys` property now also accepts integer values in addition to strings.

## What has changed in 1.0.84?

Note

This version 1.0.84 is affected by a bug preventing deviation tracking after multiple service enabling, hence use version 1.0.85 instead.

Our next maintenance release brings improvements in the Admin UI, in HTTP connections, and also some important bugfixes in Mappings and for Kubernetes deployments.

#### Tasks completed

* HttpConnection: Added option for dynamically [setting the path](/connectors/enterprise-connectors/http-rest#dynamic-path) in HTTP/REST read endpoints
* Admin-UI: Add UI for database backup and restore
* Admin-UI: Add Mqtt Publish Prefix documentation link on User Management forms
* Admin-UI: Improve dialog screen when license cannot be validated
* HTTP Server: Cleanup of remaining issues: additional content-type, timestamp, documentation clarification
* OPC UA client: Filter incoming OPC UA Events by EventType
* User docs: Clarify usage of Agents, in particular also handling of connection loss
* Auth-server performance: Optimize the MQTT subscription authorization

#### Bugs fixed

* (High-severity bugfix) Fix failing Mapping subscriptions when overlapping wildcard topics exist. This bug affects versions 1.0.79 until 1.0.83 and could lead to Mappings not receiving data if topics with wildcards exist in overlapping ways. This can only be avoided by taking into account multiple duplicate messages in that situation, as [explained here](/connectors/enterprise-connectors/mqtt#duplicates-on-overlapping-subscriptions).
* Auth-server: Fixing crash when /users/batch POST request is sent with duplicated username
* Sopas protocol: Reduce log verbosity by correctly setting non-debug log level
* Kubernetes: Fix usage metrics collection that was broken on multi-node broker cluster
* Kubernetes: Fix initial connection failures of agents, causing errors about not being able to create resources on agent

## What has changed in 1.0.85?

This next release brings a small but important bug fix that solves issues with resources deviation tracking, affecting versions 1.0.83 and 1.0.84.

#### Bugs fixed

* Fix deviation tracking that was broken on subsequent enabling of services (affecting 1.0.83, 1.0.84)

## What has changed in 1.0.86?

Note

This version 1.0.86 has the new `input buffering` feature enabled by default and for all endpoints, which can lead to changed behavior and unexpected message drop with certain Rule Engine rules (especially the `burst` rule), hence use version 1.0.87 instead where this feature is disabled by default.

Our next maintenance release brings an important bugfix in protocol-mapper for high data rates, some improvements in Rules, Mapping, and Kubernetes orchestration, and overall bugfix and stability increases.

#### Bugs fixed

* Protocol Mapper (high-severity bugfix): Fix out-of-memory exception on high data load by introducing a controlled `input buffering` behavior for [endpoints](/data-flows/service-commissioning-files/resources/cybus-endpoint#inputbuffering), [mappings](/data-flows/service-commissioning-files/resources/cybus-mapping#inputbuffering), and [nodes](/data-flows/service-commissioning-files/resources/cybus-node#inputbuffering). This change introduces new properties on those three resources, most importantly `inputBuffering.maxInputBufferSize` (default: 5000). This value describes the maximum message burst size that can be received and are waiting to be processed, before messages have to be dropped. The value is set individually on each endpoint, mapping, or node resource. If message are being dropped, there will be a warning log message `Dropped \<number> message(s) for topic … due to maxInputBufferSize \<number> exceeded`. In that case, you should increase the `maxInputBufferSize` parameter for the resource in question.
* Admin-UI / auth-server: Fix broken password change for admin user in user management page
* Rules: Fix parse rule with format ascii to also handle literal numbers
* Admin-UI: Fix button for “upload metrics” that used to work only when clicking on the home page first
* Mapping: Fix broken named wildcard handling on first level of mapping topics
* Service files: Fix missing endpoint yaml schema validation for buffering properties
* User docs: Fix / clarify needed permission settings for mqtt clients with topic prefix
* User docs: Fix minor typo in backup and restore documentation

#### Task completed

* Rules: Improve error message if the transform rule encounters a failure
* Auth-server: Implement new listUsers endpoint with pagination and readAll method to fix performance with higher number of users
* Protocol-mapper: Endpoint output buffering is now printing log messages into docker log upon dropping message during disconnect
* Kubernetes: Remove persistent volume claim that is no longer needed in protocol-mapper
* Kubernetes: Add detection of missing k8s API permissions during startup, if helm chart permissions updates were missing
* Admin-UI: Hide service’s auto generated roles in dialog when adding role to user

## What has changed in 1.0.87?

This next release brings improvements in protocol-mapper for input buffering, improvements on service management performance, general fixes on the Admin-UI, Kafka protocol and other aspects of service internals.

#### Task completed

* Protocol-mapper (high-severity bugfix): The new `input buffering` feature (introduced in version 1.0.86) is now disabled by default to ensure unchanged behavior by default, but can be (and should be) enabled for specific [endpoints](/data-flows/service-commissioning-files/resources/cybus-endpoint#inputbuffering), [mappings](/data-flows/service-commissioning-files/resources/cybus-mapping#inputbuffering), and [nodes](/data-flows/service-commissioning-files/resources/cybus-node#inputbuffering) if there is a risk of running out-of-memory due to high input data rates.
* Admin-UI: Add total number of resources in table view’s pagination label
* Admin-UI: In the service enabling dialog showing the authorizations, the topic subscriptions of mappings are now shown in a more detailed way
* User docs: For COV rule, clarify documentation as it is working for exactly one topic but not multiple topics
* User docs: Improve documentation of inter-service referencing

#### Bugs fixed

* Admin-UI: Fix error when trying to remove a MQTT publish prefix again
* Admin-UI: Fix when using the application with a minimum access role, where an error of subscription issue was displayed
* Admin-UI: On updating a service, fix previously configured parameter values to be correctly re-used even if the parameter has no default value
* Admin-UI: Fix field “Confirm password” field if the “confirm password mode” is toggled, so that the password is not unintentionally auto-filled
* Kafka: Fix headers in consumer to be rendered as a string and not erroneously as a Buffer
* Auth-Server: Fix wrong response code 400 when no username is set, so that error log messages are significantly more understandable
* Auth-server: Fix potential crash on unexpected error messages
* Installer: Detect if docker was installed via snap and fail with clear error message in this case
* Kubernetes: Fix very slow service enabling/disabling if there is a large number of users in the database
* Fix inter-service dependency problems in case the broker container has been restarted
* Fix client registry (explicit workflow) for the case using certificates with username/CSR

## What has changed in 1.0.88?

This next release brings improvements in protocol-mapper for Kafka, OPC UA Server, improvements on service management for some resource types, general fixes on the Admin-UI, Mappings now support the usage of label templates.

#### Task completed

* Add missing “topic” property to Cybus::Nodes
* Invalidate the auth-server cache after database restore.
* Support database backup+restore from older to newer versions
* User Management: On Add/Edit user add validation hints for username
* Allow wildcard templates in subscription label of Mappings
* Add requirements and prerequisites to Backup & Recovery feature
* Sort JSON fields in mappings

#### Bugs fixed

* Kafka connector better handling of edge cases on subscribe/unsubscribe
* OPC UA Server restart resource instance on protocol-mapper restart
* Improve CSR validation when registering clients
* OPC UA Server improve handling when errors occur during deployment
* Metrics submission improve behavior by showing/hiding controls based on permissions
* Improve handling of expired tokens in the Admin App

## What has changed in 1.0.89?

This next release brings several improvements to the Admin-UI, switches Connectware to use Cybus built binaries and Docker images for the MQTT Broker, improves documentation for several rules including examples that can be installed directly and many internal fixes and enhancements.

#### Task completed

* General: Connectware now uses binaries and Docker images built by Cybus for the MQTT Broker
* Admin UI: Improve metrics presentation
* Admin UI: User now gets a notification after service is created instead of being redirected to the installed service
* Admin UI: Improve schema error messages styling
* Admin UI: Clicking on a Service row on the Service Link page now takes the user to the service
* Admin UI: Added information about topics defined in the endpoint on the Endpoint page
* Auth Server: Additional verification of username against CommonName for client registration using CSR
* Documentation: Improve Transform Rule Documentation
* Documentation: Improve Filter Rule Documentation
* Documentation: Improve Stash Rule Documentation
* Documentation: Improve Collect Rule Documentation

#### Bugs fixed

* Admin UI: Mapping’s MQTT client shows error
* Admin UI: Confusing dialog when activating interdependent services
* Admin UI: Deviation Snackbar overlaps the main menu when a lot of deviations are given
* Admin-UI: While updating password, change password button is not getting enabled
* Admin-UI: Some images in service catalog depend on cybus.io - default image URL needs to be changed
* Admin UI: Browser error on viewing mapping entries
* Admin UI: Non clear error is displayed when attempting to remove token authentication method from admin user
* Admin UI: Expired tokens not removed from the browser’s local storage
* Helm Chart: Split cybus-broker-cluster-reader role permissions to avoid requesting non-default APIs
* General: Timeout error on bulk deletion of 10 or more services in the UI in K8s
* Container Manager: Creation of Cybus::File fails with “(HTTP code 404) no such container - No such image: alpine:3.15”
* Protocol Mapper: OPC UA Client Int64 and UInt64 values are represented as array on MQTT topic

## What has changed in 1.0.90?

This next release brings several improvements to the Admin UI, Backend and Infrastructure components, most significant changes include better handling of slow networks on the Admin UI, introduction of a module to better handle inter Service dependencies to avoid service enabling issues and better Broker cluster formation logic. Additionally documentation and several other improvements were done on different areas.

#### Task completed

* Admin UI: MQTT topic subscription should verify the available topic depth, otherwise the connection is silently dropped
* Admin UI: Certificates without common name (CN) don’t show anything
* Admin UI: Validate Mqtt Publish Prefix on the user management UI on whether it is allowed by current user permissions
* Admin UI: Revise Material UI theming
* Admin UI: Replace UI Webpack bundler with Parcel
* Documentation: Parse Rule provide sample commissioning file
* Documentation: SetContextVars Rule provide sample commissioning file
* Documentation: COV Rule provide sample commissioning file
* Documentation: Burst Rule provide sample commissioning file
* K8s: Add feature toggle Helm value to control Services Graphs enabling
* Protocol Mapper: support PATCH method for HTTP write endpoints
* Protocol Mapper/Auth-Server: log message if topic depth of MQTT topics exceed the configured limit
* Service Manager: introduce Services Graph to keep persisted state of inter service dependencies
* Service Manager: enable circular dependencies in Services Graph to account for edge case in services update
* Service Manager: make the service-graph bootstrap optional

#### Bugs fixed

* Admin UI: better handle unstable/slow networks scenarios
* Admin UI: Data is not flowing under explorer tab
* Admin UI: Wrong error is shown when bad client registry request is allowed to register
* Admin UI: Mapping data preview for external brokers doesn’t make sense
* Admin UI: Random VRPC timeouts might generate false-positive error
* Admin UI: Catch and display more errors on the Explorer that were previously ignored
* Container Manager: System > Status on Kubernetes does not work when there are unscheduled pods
* Documentation: fix inconsistency in number of resources
* Admin UI: Explorer non-selected custom topics vanish on page reload
* Protocol Mapper: improve error handling on MQTT protocol
* Service Manager: incorrectly identifies disabled services as removed
* Service Manager: storage for service-graph needs to handle different container run times

## What has changed in 1.0.91?

This release fixes a problem in the broker cluster management logic which could cause broker state data (for example subscriptions and retained messages) to be lost upon restarts or updates of the Kubernetes Cluster which subsequently leads to disturbed inter-service communication of Connectware. Only customers using Kubernetes were affected by this behavior.

#### Task completed

* No features were changed in relation to 1.0.90

#### Bugs fixed

* Broker: during shutdown of broker cluster nodes last node does not keep MQTT session state

## What has changed in 1.0.92?

This release includes an enhancement to the Modbus protocol that allows the user to overwrite the `unitId` configured in the Connection resource by using the new optional `unitId` property of an Endpoint.

#### Task completed

* Added support for multiple Modbus TCP UnitIDs per Connection

## What has changed in 1.0.93?

This release includes an enhancement to the HTTP protocol that allows the user to overwrite the `path` property of write endpoints.

#### Task completed

* Added support for overwriting the `path` property for HTTP write endpoints

</details>

<details>

<summary>Connectware 0.x - 1.0</summary>

## What has changed from 0.x to 1.0?

This section describes the general changes in the Cybus Connectware version 1.0.0 compared to the previous 0.x versions.

#### Services and Resources

The most important change is that everything is done in a [service](/data-flows/services) and described as [resources](/data-flows/services/service-resources-view).

* The previous distinction between service commissioning file and device commissioning file has been removed. Both files are replaced by one single [commissioning file](/data-flows/service-commissioning-files) for services, similar to AWS cloud formation files, still in the well-known yaml file format. This enables “infrastructure as code” on a whole new level.
* The new service commissioning file describes the complete system context as a set of [resources](/data-flows/services/service-resources-view). Resources can be devices, Docker containers (both customized by the customer or standard containers by Cybus), connections, data transformations, and more.
* Describing connections to devices in device commissioning files has been replaced by describing [connection resources](/data-flows/service-commissioning-files/resources/cybus-connection) inside the service commissioning files.

This change enables the following new features:

* Service life cycle can be managed and observed explicitly: A service changes states from disabled to enabling to [enabled](/data-flows/services/managing/enabling) and [vice versa](/data-flows/services/managing/disabling).
* If not all resources inside a service are available or working properly, a [deviation](/data-flows/services/deviations) for this service between expected state and actual state is shown and the service is marked as `deviated`, leading the user directly to the cause of the problem in order to fix it quickly
* Resources can reference each other not only within one commissioning file and within one service, but also across different services using the [service id](/data-flows/services/serviceid). The complete system context can hence be described by one or multiple commissioning files, whatever fits best for the application.
* When defining a container resource for the service, parameters such as port mappings can be specified with defaults from the commissioning files, but can also manually be entered when the commissioning file is [installed](/data-flows/services/managing/installing) into the Connectware
* When writing commissioning files with multiple entries, several helper functions exist to avoid code duplications in the resources’ [properties](/data-flows/service-commissioning-files/resources): `ref` uses the value from somewhere else by reference; `sub` will substitute values from somewhere else as a string replacement; `merge` will merge a set of common parameter values with additional given specific values such as concrete addresses.

#### User Interface

* Each service is displayed in the admin user interface (web interface) with an overview and detail view. In the [detail view](/data-flows/services/service-details-view), the resources that are used within this service are all shown. Every of those resources can be clicked on to jump to the details view of those resources (such as connections, containers, endpoints). Alternatively, for every resource kind there exists an overview list from which one can go to the detail view of that resource, too.
* The admin user interface includes an [Explorer](/monitoring/data-explorer) page which enables browsing through all MQTT topics by topic structure, showing the data as received from the machine endpoints or as prepared by the service mappings to semantic structures, both according to the configuration from the service commissioning file.

#### Distributed Agents

* Setup of distributed agents is much easier: Distributed systems can be set up very easily every time new machines and data sources should be connected

</details>


# What Is Connectware?

The configuration-as-code platform for connecting industrial machines to IT applications through a single Unified Namespace.

Connectivity in Connectware is organized into services. Each service is defined in a YAML service commissioning file that declares its connections, endpoints, mappings, and any optional runtime resources — containers, files, or servers — needed to reach a machine or system. When you enable a service, Connectware creates and manages those resources automatically and publishes the data on structured MQTT topics that your applications subscribe to.

## One Data Foundation for the Whole Enterprise

Factory environments run machines from different eras and vendors, each with its own protocol and data format. The result is data silos: OT systems that cannot reach IT applications without costly point-to-point integrations that are hard to scale and maintain across sites.

Connectware provides a Unified Namespace (UNS): a shared MQTT-based data layer for MES, SCADA, analytics, and AI applications. All connectivity is defined in service commissioning files that declare what to connect, what data to read, and how to route it. Connectware creates and manages the underlying connections, subscriptions, and topic routing from that definition.

<figure><img src="/files/bTWmZojKHxyb06bFTwPQ" alt="Diagram showing Connectware between shop floor devices and IT applications, providing a single Unified Namespace"><figcaption><p>Connectware sits between your shop floor and your IT applications, providing a single Unified Namespace for both</p></figcaption></figure>

## Connect, Transform, and Scale

**Connect** machines and systems using [OPC UA, Modbus/TCP, Siemens S7, Kafka, MQTT, HTTP/REST, and many more connectors](/connectors/shop-floor-connectors). Devices publish through Connectware to a structured MQTT topic hierarchy — the Unified Namespace — that applications subscribe to instead of connecting to devices directly.

**Transform** data in real time as it flows through Connectware. The [Rule Engine](/data-flows/rule-engine) filters, normalizes, enriches, and computes derived values before the data reaches downstream systems.

**Scale** across sites with GitOps. The same service commissioning file runs from a single edge device to a multi-cluster production deployment, protected by role-based access control, mTLS-encrypted communication, Single Sign-On, and Multi-Factor Authentication.

Author service commissioning files faster with the [VS Code Extension](/tools/cybus-connectware-extension-vs-code), which provides schema validation and autocompletion, and with [Cybus Connectware GPT](/tools/cybus-connectware-gpt), which generates them from natural-language prompts.

## Next Steps

* [How Connectware Works](/discover/how-connectware-works): a walkthrough of Connectware's data model, from YAML configuration to live data flowing to your applications.
* [Choose Your Deployment Platform](/deployment/choose-your-deployment-platform): decide between Kubernetes and Docker for your first installation.
* [Connect Your First Machine](/discover/connect-your-first-machine): install a sample service against a simulated machine and watch live data arrive.


# How Connectware Works

Learn how Connectware turns fragmented shop floor data into a single, structured data layer for your industrial data use cases.

This page walks through how a service commissioning file becomes live data flowing from industrial devices to your applications. It covers the core concepts — services, resources, endpoints, mappings, and the Unified Namespace — and shows how the data pipeline fits together end to end.

If you have not read [What Is Connectware?](/discover/what-is-connectware) yet, start there for a platform overview.

## Core Concepts

The following terms appear throughout this page:

| Term                           | Meaning                                                                                                                     |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| **Service**                    | A packaged unit of connectivity that contains all resources needed to connect devices and route data.                       |
| **Resource**                   | A building block within a service, such as a connection, endpoint, mapping, or container.                                   |
| **Connection**                 | Defines how to reach a device: connector, address, credentials, and connector-specific settings.                            |
| **Endpoint**                   | A specific data point on a device — for example, a sensor tag, PLC register, or OPC UA node.                                |
| **Mapping**                    | Routes data from an endpoint to a Unified Namespace MQTT topic, optionally transforming it via the Rule Engine.             |
| **Unified Namespace (UNS)**    | Structured MQTT topic hierarchy that mirrors your production environment and serves as the single source of truth for data. |
| **CybusMQ**                    | Connectware's internal MQTT broker. All topic routing flows through it.                                                     |
| **Service commissioning file** | The YAML file that declares a service and all its resources — the configuration-as-code representation of your setup.       |

## Everything Starts with a Service Commissioning File

A **service commissioning file** is a YAML file that declares what to connect, what data to read, and how to route it to your applications. When you enable it as a service, Connectware creates every resource it describes. When you disable it, those resources are cleanly removed.

This is **configuration as code**. The file is the source of truth: store it in Git, review changes in pull requests, and deploy the same setup across factories.

### How Data Flows Through Connectware

The service commissioning file creates a data pipeline:

1. **Connection**: Establishes communication with a device using the specified connector.
2. **Endpoint**: Subscribes to or reads a specific data point on the device.
3. **Mapping**: Routes the data to a structured MQTT topic, applying any transformations.
4. **CybusMQ**: Connectware's internal MQTT broker.
5. **Applications**: Consumers (dashboards, MES, analytics, AI) subscribe to topics there.

This pipeline is entirely declarative: you describe what you want, and Connectware creates and manages all the underlying infrastructure.

### Example Service Commissioning File

The following example connects to an OPC UA server on a CNC milling machine and publishes its spindle speed to the Unified Namespace. The same pattern applies to any supported connector — only the connector-specific properties change (for example, Modbus register addresses instead of OPC UA node IDs).

{% code title="connect-your-first-machine.yaml" lineNumbers="true" expandable="true" %}

```yaml
description: >
  Connects to the OPC UA server on the CNC milling machine on line 1
  and publishes spindle speed via MQTT.

metadata:
  name: CNC Mill Line 1 - OPC UA
  version: 1.0.0
  provider: cybus
  homepage: https://www.cybus.io

parameters:
  opcuaHost:
    type: string
    description: OPC UA server address of the CNC mill
    default: 192.168.10.10

  opcuaPort:
    type: integer
    description: OPC UA server port
    default: 4840

resources:
  opcuaConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      connection:
        host: !ref opcuaHost
        port: !ref opcuaPort

  spindleSpeed:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: ns=2;s=SpindleSpeed

  spindleSpeedMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref spindleSpeed
          publish:
            topic: !sub 'factory/line1/cnc-mill-1/spindle-speed'
```

{% endcode %}

### Tools for Writing Service Commissioning Files

Service commissioning files are typically created with tool support rather than written from scratch. The [Cybus Connectware VS Code Extension](/tools/cybus-connectware-extension-vs-code) provides schema validation and autocompletion as you edit. [Cybus Connectware GPT](/tools/cybus-connectware-gpt) is an AI assistant that generates service commissioning files from plain-language descriptions — useful for prototyping a new device integration or scaffolding a configuration before refining it. In production, service commissioning files live in Git repositories and are deployed through CI/CD pipelines using GitOps practices.

Learn more: [Service Commissioning Files](/data-flows/service-commissioning-files)

## Building Your Service: Key Components

A service commissioning file contains several key sections that work together to connect devices, read data, and route it to consumers:

### Parameters: Reusable Templates

The `parameters` section makes a service commissioning file reusable across environments and sites. Instead of hard-coding server addresses, they are declared as parameters with default values:

{% code title="connect-your-first-machine.yaml - Parameters" overflow="wrap" lineNumbers="true" %}

```yaml
parameters:
  opcuaHost:
    type: string
    description: OPC UA server address of the CNC mill
    default: 192.168.10.10

  opcuaPort:
    type: integer
    description: OPC UA server port
    default: 4840
```

{% endcode %}

When you install a service, you can override any parameter without editing the file. The same template can connect to different machines across development, staging, and production sites.

### Connections: Reaching Devices

The `resources` section contains the building blocks of the service. A `Cybus::Connection` defines how to reach a device: the protocol, host, port, and credentials.

{% code title="connect-your-first-machine.yaml - Connection" overflow="wrap" lineNumbers="true" %}

```yaml
opcuaConnection:
  type: Cybus::Connection
  properties:
    protocol: Opcua
    connection:
      host: !ref opcuaHost
      port: !ref opcuaPort
```

{% endcode %}

The `!ref` tags resolve to the parameter values when the service is enabled. Connectware supports a wide range of industrial protocols — including OPC UA, Modbus/TCP, Siemens S7, MQTT, and HTTP/REST — each with its own connection properties, but the same configuration pattern.

Learn more: [Cybus::Connection](/data-flows/service-commissioning-files/resources/cybus-connection)

### Endpoints: Reading Data Points

A `Cybus::Endpoint` uses a connection to subscribe to or read from a specific data point on a device:

{% code title="connect-your-first-machine.yaml - Endpoint" overflow="wrap" lineNumbers="true" %}

```yaml
spindleSpeed:
  type: Cybus::Endpoint
  properties:
    protocol: Opcua
    connection: !ref opcuaConnection
    subscribe:
      nodeId: ns=2;s=SpindleSpeed
```

{% endcode %}

This endpoint subscribes to the `SpindleSpeed` node on the CNC mill's OPC UA server. Every time the node publishes a new value, Connectware receives it. Multiple endpoints can share the same connection; define one endpoint per data point.

Learn more: [Cybus::Endpoint](/data-flows/service-commissioning-files/resources/cybus-endpoint)

### Mappings: Routing to the Unified Namespace

A `Cybus::Mapping` routes data from endpoints to MQTT topics in the Unified Namespace. The topic path you define reflects the physical and logical structure of your production environment — for example, `factory/line1/cnc-mill-1/spindle-speed` — making data consistently addressable by any consumer.

{% code title="connect-your-first-machine.yaml - Mapping" overflow="wrap" lineNumbers="true" %}

```yaml
spindleSpeedMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref spindleSpeed
        publish:
          topic: !sub 'factory/line1/cnc-mill-1/spindle-speed'
```

{% endcode %}

Mappings can transform and enrich data in real time: normalize tag names, filter noise, compute derived values, or convert units. All topic routing flows through [CybusMQ](/broker/cybusmq), Connectware's internal MQTT broker.

Learn more: [Cybus::Mapping](/data-flows/service-commissioning-files/resources/cybus-mapping)

### Rule Engine: Transforming Data (Optional)

For transformations beyond simple routing, Connectware's **Rule Engine** enables conditional logic, computed values, and data filtering. Rules are defined within mappings and process messages before they reach subscribers.

{% code title="Example - Mapping with Rules" overflow="wrap" lineNumbers="true" %}

```yaml
mapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref machineRunState
        publish:
          topic: factory/line1/cnc-mill-1/run-state
        rules:
          - transform:
              expression: '$.value > 0 ? "running" : "stopped"'
```

{% endcode %}

Learn more: [Rule Engine](/data-flows/rule-engine)

## Beyond Connectivity

Once data is flowing, Connectware provides the operational layer to run, scale, and govern everything:

* **Service lifecycle**: Install, enable, update, and disable services through the Admin UI or API. When you disable a service, every resource is cleanly removed — no orphaned connections or manual cleanup required. See [Services](/data-flows/services).
* **Containerized applications**: Services can include Docker containers that process or consume UNS data — dashboards, analytics, AI inference pipelines, and more. See [Resources](/data-flows/service-commissioning-files/resources).
* **Transactional data flows**: When a consumer must confirm that a write or command succeeded, FlowSync carries the response or error back through the data flow. See [FlowSync](/data-flows/flowsync).
* **Agents**: Devices on isolated networks can be reached via lightweight agents that connect outbound to Connectware — no inbound connectivity required. See [Agents](/data-flows/agents).
* **Monitoring**: The Data Explorer and service status views let you verify live data flows and diagnose connection issues. See [Data Explorer](/monitoring/data-explorer).
* **User management**: Role-based access control, SSO, and MFA govern who can access which parts of the system. See [User Management](/access/user-management).
* **GitOps**: Service commissioning files live in Git, changes go through pull requests, and a CI/CD pipeline deploys to Connectware on merge.

## Next Steps

Now that you understand how Connectware works end to end, here are the most common next steps:

<table data-view="cards"><thead><tr><th align="center"></th><th align="center"></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Connectors</strong></td><td align="center">Browse connectors for your machines: OPC UA, Modbus, S7, and many more. Each page includes configuration examples.</td><td><a href="/files/6F1b8PMOWhgyRRkaylrt">/files/6F1b8PMOWhgyRRkaylrt</a></td><td><a href="/pages/4Ad8cZXYYeKev7ILps1e">/pages/4Ad8cZXYYeKev7ILps1e</a></td></tr><tr><td align="center"><strong>Service Commissioning Files</strong></td><td align="center">Build your own service with the complete reference covering every resource type and property.</td><td><a href="/files/JQap0TsVsV8NtZ3eb6OJ">/files/JQap0TsVsV8NtZ3eb6OJ</a></td><td><a href="/pages/UbQg7pMD0S82fqEDnYe0">/pages/UbQg7pMD0S82fqEDnYe0</a></td></tr><tr><td align="center"><strong>Monitoring</strong></td><td align="center">Use the Data Explorer and Live Data tab to verify that data flows correctly and monitor your connections.</td><td><a href="/files/Nsc34MNv8OAxOOX0WVHQ">/files/Nsc34MNv8OAxOOX0WVHQ</a></td><td><a href="/pages/0lD2MMAsH2LJbiUzlDRQ">/pages/0lD2MMAsH2LJbiUzlDRQ</a></td></tr><tr><td align="center"><strong>User Management</strong></td><td align="center">Create accounts, assign roles, and restrict access with role-based access control.</td><td><a href="/files/WGm3YxI3dVq3opNNwCCx">/files/WGm3YxI3dVq3opNNwCCx</a></td><td><a href="/pages/CNdoMnGUqQRARZehYqfv">/pages/CNdoMnGUqQRARZehYqfv</a></td></tr><tr><td align="center"><strong>Agents</strong></td><td align="center">Deploy agents to bridge isolated networks when machines cannot reach Connectware directly.</td><td><a href="/files/eV6rAxPqNrJOKXbJvb1b">/files/eV6rAxPqNrJOKXbJvb1b</a></td><td><a href="/pages/LFR2Vq44wTTNj1J3QarJ">/pages/LFR2Vq44wTTNj1J3QarJ</a></td></tr></tbody></table>


# Connect Your First Machine

Install a sample service that connects to a simulated OPC UA machine and watch live data arrive in Connectware.

See Connectware in action: you install a service from a sample service commissioning file, Connectware connects to a public OPC UA demo server that simulates a machine, and the incoming data appears in the Data Explorer. At the end, you have completed the full Connectware workflow once: from YAML configuration to live data on an MQTT topic.

You do not need any machine or hardware. The sample service connects to a publicly available OPC UA test server that publishes simulated data.

## Prerequisites

* A running Connectware installation. See [Installing Connectware](/deployment/installing-connectware).
* A user account that is allowed to install services. The [default admin user](/access/user-management/users/default-admin-user) is sufficient.
* Outbound Internet access from Connectware to the demo server `opcua.demo-this.com` on port `51210`.

## Step 1 — Download the Sample Service Commissioning File

Download the sample service commissioning file:

{% file src="/files/QaGfoR3UFtv4PhlP5ZP7" %}

The file defines the resources that make up the data pipeline:

* A `Cybus::Connection` to the demo OPC UA server.
* A `Cybus::Endpoint` that subscribes to a node publishing simulated values.
* A `Cybus::Mapping` that publishes those values to the MQTT topic `example/opcua/dataexample`.

For a walkthrough of each section in a service commissioning file, see [How Connectware Works](/discover/how-connectware-works).

## Step 2 — Log in to the Admin UI

1. Open your browser and enter the address of your Connectware instance (**https\://\<HOST-IP>**).
2. Enter your username and password and click **Sign in**.

## Step 3 — Install the Service

1. On the navigation panel, click **Services**.
2. Click **Upload Service**.
3. Click **Choose File** and select the `connect-your-first-machine.yaml` file.
4. Click **Install** to confirm the parameters and start the installation. You can keep the default parameter values.

The service is now installed but not yet enabled.

## Step 4 — Enable the Service

1. In the **Service Overview** list, click your service to open the **Service Details** view.
2. Click **Enable**.
3. In the **Authorization Required** dialog, click **Allow** to confirm the configuration changes.

Connectware now creates the connection, endpoint, and mapping, and data starts to flow.

## Step 5 — Watch the Data Arrive

Data flows through Connectware as MQTT messages organized into topics. The [Data Explorer](/monitoring/data-explorer) lets you monitor them live.

1. On the navigation panel, click **Data**.
2. In the **Available Topics** tree, select the `example/opcua/dataexample` topic.

The Data Explorer shows the simulated values arriving from the demo server every few seconds.

## Result

You installed, enabled, and verified a complete Connectware service. Every resource — the connection, the endpoint, and the mapping — was created from a single service commissioning file, and the machine data is available to any MQTT consumer through the Unified Namespace.

To remove the sample service, open its **Service Details** view, click **Disable**, and then delete the service. All resources are cleanly removed.

## Next Steps

* Connect a real device with the other [Machine Connectivity](/guides/machine-connectivity) guides or browse the [connectors](/connectors/shop-floor-connectors) for your protocols.
* Build your own service using the [service commissioning file reference](/data-flows/service-commissioning-files).
* Route and transform your data with the [Rule Engine](/data-flows/rule-engine).


# Choose Your Deployment Platform

Compare Kubernetes and Docker to pick the right platform for your Connectware installation.

Connectware runs on Kubernetes or Docker. Each platform has different strengths depending on scale, availability requirements, and where you plan to run Connectware.

* **Kubernetes** — Production workloads, high availability, and environments where you already operate Kubernetes.
* **Docker** — Protocol-mapper agent edge deployments, single-node installations, and evaluation setups.

## At a Glance

| Aspect                    | Kubernetes                                      | Docker                                                |
| ------------------------- | ----------------------------------------------- | ----------------------------------------------------- |
| **Deployment Complexity** | Higher. Requires a cluster.                     | Lower. Single-host setup.                             |
| **High Availability**     | Built-in through node redundancy.               | Not available. Single-node only.                      |
| **Scalability**           | Mix of horizontal and vertical scaling.         | Limited to vertical scaling.                          |
| **Resource Requirements** | Higher. Multi-node infrastructure.              | Lower. Single-host system.                            |
| **Best For**              | Production clusters and multi-site deployments. | Edge devices, development, single-node installations. |
| **Management Tools**      | Helm, `kubectl`, and the Kubernetes ecosystem.  | Docker Compose and the Docker CLI.                    |
| **Learning Curve**        | Steeper. Requires Kubernetes knowledge.         | Gentler. Requires Docker knowledge.                   |

## Kubernetes

Kubernetes is the recommended platform for production Connectware deployments. The cluster architecture provides node redundancy and horizontal scaling for several core components, including the CybusMQ broker, NATS, the auth server, resource status tracking, and the topic explorer. Kubernetes deployments also expose Prometheus metrics and include Prometheus Operator support for the NATS StatefulSet. Deployments integrate with existing DevOps and GitOps workflows through Helm and standard Kubernetes tooling.

For system requirements, see [System Requirements](/deployment/installing-connectware/system-requirements#kubernetes-deployment).

## Docker

Docker is the right fit for protocol-mapper agent edge deployments and single-host installations. Docker Compose keeps the whole configuration in a single `docker-compose.yml` file and starts up quickly without a cluster. It is a practical choice for industrial PCs, gateways, and evaluation environments where clustering is not needed.

For system requirements, see [System Requirements](/deployment/installing-connectware/system-requirements#docker-compose-deployment).

## Portability Between Platforms

Service commissioning files, connections, endpoints, and mappings behave identically on Kubernetes and Docker. Most services run unchanged on either platform.

Services that use platform-specific resources — `Cybus::Container`, `Cybus::Volume`, and `Cybus::IngressRoute` — are tied to the platform they were written for and cannot be moved without adjustments.

{% hint style="info" %}

## Offline Connectware installations

Offline installation is supported on both platforms. See [Offline Installation (Kubernetes)](/deployment/installing-connectware/offline-on-kubernetes) and [Offline Installation (Docker)](/deployment/installing-connectware/offline-on-docker).
{% endhint %}

## Next Steps

Once you have chosen a platform, follow the matching installation guide:

* [Installing Connectware on Kubernetes](/deployment/installing-connectware/on-kubernetes)
* [Installing Connectware on Docker](/deployment/installing-connectware/on-docker)


# Installing Connectware

Install Connectware on Docker or Kubernetes, including offline environments.

Connectware runs on Docker and Kubernetes. Before installing, verify your system meets the requirements. See [System Requirements](/deployment/installing-connectware/system-requirements).

For environments without Internet access, offline installation procedures are available for both platforms.

## On Kubernetes

{% content-ref url="/pages/6wfBzDlX8U0vXFsK4cQ1" %}
[Installing Connectware (Kubernetes)](/deployment/installing-connectware/on-kubernetes)
{% endcontent-ref %}

{% content-ref url="/pages/eFdQ4mOg1hNK8k62Q5Wl" %}
[Offline Installation (Kubernetes)](/deployment/installing-connectware/offline-on-kubernetes)
{% endcontent-ref %}

## On Docker

{% content-ref url="/pages/HcAR7FO9aNiUH1WScHh3" %}
[Installing Connectware (Docker)](/deployment/installing-connectware/on-docker)
{% endcontent-ref %}

{% content-ref url="/pages/CgKBZAnVUdHd3rRW3rTK" %}
[Offline Installation (Docker)](/deployment/installing-connectware/offline-on-docker)
{% endcontent-ref %}

## Uninstalling Connectware

{% content-ref url="/pages/KlCJ4KLxyrBjUatC8XYa" %}
[Uninstalling Connectware](/deployment/installing-connectware/uninstalling-connectware)
{% endcontent-ref %}


# System Requirements

Hardware, software, and virtual host requirements for installing and operating Connectware.

This section outlines the technical requirements for installing and operating Connectware. It covers hardware specifications, network configuration, and system dependencies for both Docker Compose and Kubernetes deployments.

The hardware requirements for Connectware depend on factors such as message rate, message size, and storage requirements. For hardware recommendations based on your specific use cases, [contact us](https://www.cybus.io/en/contact/) and we’ll recommend the appropriate hardware setup.

## Connectware Deployment Options

Connectware offers multiple deployment options using Kubernetes, Docker, or a hybrid approach. The choice depends on your specific infrastructure requirements, from enterprise-scale operations to streamlined development environments.

The following table details the features and recommended use cases for Kubernetes and Docker deployments.

|                  | **Kubernetes**                                                                                                                                                                             | **Docker**                                                                                                 |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| **Platform**     | Kubernetes using Helm orchestration                                                                                                                                                        | Docker with Docker Compose                                                                                 |
| **Environments** | Cloud, On-Premises, Hybrid                                                                                                                                                                 | On-Premises Linux (VM, Bare Metal)                                                                         |
| **Use case**     | Enterprise-grade deployment solution                                                                                                                                                       | Development and simple production                                                                          |
| **Key features** | <p>• Advanced orchestration<br>• Automated deployment management<br>• For high-demand environments<br>• Comprehensive monitoring<br>• Automated scaling<br>• Robust service management</p> | <p>• Low infrastructure requirements<br>• For development environments<br>• For basic deployment needs</p> |

## Software Requirements

* Linux operating system
* Deployment options
  * Kubernetes
  * Docker
  * Docker Compose
* Latest stable version of Chrome browser

Docker should be installed using the official setup guide <https://docs.docker.com/engine/install/ubuntu/>. Installing Docker by the package manager Snap is known to be causing issues and should be avoided.

{% hint style="warning" %}
Connectware is designed to operate on Linux systems, deployed with Docker Compose or Kubernetes. Running Connectware on Windows hosts or with different container-orchestration systems is not part of the standard version of Connectware, but may be available upon request.
{% endhint %}

## Docker Compose Deployment

Docker Compose provides a streamlined deployment option for Connectware, ideal for smaller installations or development environments. This approach simplifies setup and management while maintaining essential functionality, requiring fewer resources than a full Kubernetes implementation.

### Hardware Requirements

The hardware requirements for deploying Connectware on Docker depend on your deployment scale and your specific use cases.

#### Minimum Setup

* CPU: **64-bit x86**
* RAM: **4 GB**
* Storage: **32 GB**

### System Requirements

* Operating System: Linux (Windows hosts available upon request)

{% hint style="warning" %}
Avoid installing Docker through the **Snap package manager** due to known issues.
{% endhint %}

## Kubernetes Deployment

Kubernetes deployment offers a robust, enterprise-grade platform for Connectware, providing advanced orchestration capabilities, comprehensive monitoring, and efficient scaling. This approach is recommended for production environments with higher performance requirements or more complex integration needs.

### Supported Kubernetes Versions

Connectware officially supports the second-to-last and third-to-last minor releases of Kubernetes.

**Example:** If the latest Kubernetes release is 1.35, Connectware officially supports 1.34 and 1.33.

For information on the Kubernetes release history, see <https://kubernetes.io/releases/>.

{% hint style="warning" %}
While Connectware may run on older versions, we only provide support and testing for the versions defined above.
{% endhint %}

### Available Distributions

Kubernetes deployments for Connectware can be implemented on various Kubernetes distributions, including cloud-based and on-premise solutions.

For example:

* Red Hat OpenShift
* Amazon Elastic Kubernetes Service (EKS)
* Microsoft Azure Kubernetes Service (AKS)

### Hardware Requirements

The hardware requirements for deploying Connectware on Kubernetes depend on your deployment scale and your specific use cases. Here are some general recommendations for a minimum and a production setup.

#### Test Setup

For a basic setup with standard functionality and typical message loads, the following resources are sufficient:

For a basic configuration supporting standard functionality and typical message loads, we recommend the following setup:

* CPU: **64-bit x86**
* RAM: **4 GB**
* Storage: **60 GB**. Must support persistent storage using PersistentVolumes (PV) and PersistentVolumeClaims (PVC)

#### Production Setup

For an optimized hardware configuration that ensures sufficient resources for deploying Connectware and implementing initial use cases, we recommend the following setup:

* CPU: **12 cores**
* RAM: **15 GB**
* Storage: Must support persistent storage using PersistentVolumes (PV) and PersistentVolumeClaims (PVC)

### Kubernetes Cluster Requirements

* **StorageClass Requirements**
  * The cluster must be configured with exactly one default StorageClass that supports dynamic provisioning. Alternatively, the StorageClass can be explicitly specified via Helm values.
  * StorageClass supporting dynamic PersistentVolumes
  * Support for ReadWriteOnce (RWO) and ReadWriteMany (RWX) access modes
  * Recommended: NetApp with Trident provisioner
* **Load Balancer**
  * Must support OSI Layer-4 (TCP) connectivity
  * Example: MetalLB
* **RBAC Permissions**
  * The `connectware` [Helm chart](/cybus-helm-charts/connectware-helm-chart) installs **R**ole-**B**ased **A**ccess **C**ontrol resources, which require the following permissions for roles:
    * `get`, `list`, `watch` for `pods`
    * `get`, `list`, `watch` for `pods/log`
    * `get`, `list`, `watch` for `apps/statefulsets`
  * Your Kubernetes cluster must allow the creation of these roles.
* **Required Tools**
  * Helm version 4 for deployment management
  * kubectl for validating the cluster and application configuration, troubleshooting, and performing manual changes
  * Access to Cybus Registry (direct or via mirror)

### Performance Guidelines

* **Monitor system load**
  * At 50% load: Consider resource expansion
  * At 80% load: Strongly recommended to add resources
* **Deployment Strategy**
  * Start with test instance
  * Scale progressively through development, staging, and production

## Agent Requirements

### Minimum Agent Hardware Requirements

* CPU: **1 core**
* RAM: **4 GB**

### Agents on Kubernetes

When deploying agents using the connectware-agent Helm chart on Kubernetes, the following requirements apply:

* **StorageClass Requirements**
  * The cluster must be configured with exactly one default StorageClass that supports dynamic provisioning. Alternatively, the StorageClass can be explicitly specified via Helm values.
  * StorageClass supporting dynamic PersistentVolumes
  * Support for ReadWriteOnce (RWO) access mode
* **Required Tools**
  * Helm version 4 for deployment management
  * kubectl for validating the cluster and application configuration, troubleshooting, and performing manual changes
* **Network Access**
  * Access to Cybus Registry (direct or via mirror)
  * Standard connectivity to target Connectware installation via the following ports:

| Port       | Protocol    | Purpose                             |
| ---------- | ----------- | ----------------------------------- |
| 443        | TCP/HTTPS   | Registration, license retrieval     |
| 1883, 8883 | TCP/MQTT(S) | Data Plane                          |
| 4222       | TCP/HTTP(S) | Control Plane (mTLS)                |
| 4223       | TCP/HTTP(S) | Control Plane (username & password) |

For detailed installation instructions, see [Installing Connectware Agents using the connectware-agent Helm Chart](/data-flows/agents/agents-in-kubernetes/installing-connectware-agents-using-the-connectware-agent-helm-chart).

### Supported Kubernetes Versions for Agents

Connectware officially supports the second-to-last and third-to-last minor releases of Kubernetes.

**Example:** If the latest Kubernetes release is 1.35, Connectware officially supports 1.34 and 1.33.

For information on the Kubernetes release history, see <https://kubernetes.io/releases/>.

{% hint style="warning" %}
While Connectware may run on older versions, we only provide support and testing for the versions defined above.
{% endhint %}

## Network Requirements

Connectware's effective operation requires a network infrastructure that links business systems, manufacturing resources, and cloud systems. This ensures data security while preserving essential boundaries between network zones.

* **Enterprise domain**: Facilitates interaction with corporate databases and information systems.
* **Operational domain**: Establishes connections with factory equipment and industrial assets.
* **External domain**: Supports system updates and integration with cloud-based services.

The sections below specify the necessary port configurations to implement this integrated connectivity architecture.

### Required Inbound Ports

{% tabs %}
{% tab title="Kubernetes Inbound Ports" %}

#### Kubernetes Inbound Ports

| Port         | Protocol    | Purpose                                |
| ------------ | ----------- | -------------------------------------- |
| 443          | TCP/HTTPS   | Web interface, frontend & registration |
| 1883, 8883   | TCP/MQTT(S) | Data broker, agent connection          |
| 4841         | TCP/OPC UA  | OPC UA server (optional)               |
| 40000-40100  | TCP/HTTP(S) | Application ingress                    |
| 4222         | TCP/HTTP(S) | Control Plane (mTLS)                   |
| 4223         | TCP/HTTP(S) | Control Plane (username & password)    |
| {% endtab %} |             |                                        |

{% tab title="Docker Inbound Ports" %}

#### Docker Inbound Ports

| Port          | Protocol    | Purpose                                |
| ------------- | ----------- | -------------------------------------- |
| 22            | TCP/SSH     | Host system administration             |
| 443           | TCP/HTTPS   | Web interface, frontend & registration |
| 1883, 8883    | TCP/MQTT(S) | Data broker, agent connection          |
| 4841          | TCP/OPC UA  | OPC UA server (optional)               |
| 40000-40100   | TCP/HTTP(S) | Application ingress                    |
| 4222          | TCP/HTTP(S) | Control Plane (mTLS)                   |
| 4223          | TCP/HTTP(S) | Control Plane (username & password)    |
| {% endtab %}  |             |                                        |
| {% endtabs %} |             |                                        |

### Required Outbound Connectivity

#### Cybus Services (HTTPS/443)

Required endpoints for online functionality:

* **registry.cybus.io**
* **portal.cybus.io**
* **download.cybus.io**
* **graphql-server.cybus.io**
* **docker-auth.cybus.io**
* **repo.cybus.io** (only for Kubernetes deployments)

### Network Performance Requirements

* Minimum recommended bandwidth: 2.5 Gbps
* Higher bandwidth recommended for optimal performance

## Implementation Considerations

Beyond the technical setup, successful Connectware deployment requires strategic planning for resilience, security, and growth. This section addresses critical factors that ensure long-term operational effectiveness.

**Online vs Offline Operation**

Connectware is designed to function effectively in offline environments while offering enhanced capabilities when online. Internet connectivity is required specifically for system updates and management via the Cybus Portal, but core operational functionality remains intact without external connections.

**Network Segmentation**

Proper network segmentation is essential for operational integrity. Organizations should establish well-defined access protocols between office and production networks, implementing comprehensive security measures at zone boundaries to maintain appropriate isolation between critical system components.

**Capacity Planning and Scalability**

Proactive resource management is crucial for long-term system viability. We recommend that you regularly monitor resource utilization metrics, with particular attention to early indicators of capacity constraints. Organizations should develop strategic plans for both computational and storage expansion, while implementing appropriate redundancy and backup protocols to ensure operational continuity.

## Virtual Host Requirements

When deploying Connectware in virtualized environments, specific platform capabilities are required to ensure proper container operation and system performance.

Full Docker support including privileged containers is required to run Connectware on virtual hosts.

Sufficient platforms:

* VMware
* AWS EC2 (e.g. using t3a.large or t3a.xlarge (recommended) instances with Ubuntu 24.04)
* Azure VM
* Google Compute Engine


# Installing Connectware (Kubernetes)

Install Connectware on a Kubernetes cluster using Helm.

This guide walks you through installing Connectware on a Kubernetes cluster using Helm charts. The installation process includes configuring your Helm repository, customizing deployment settings in a `values.yaml` file, and verifying the installation.

## Prerequisites

Before installing Connectware, make sure to meet the following requirements:

* Connectware [license key](/deployment/licensing) is available.
* [Helm version 4](https://helm.sh/docs/intro/quickstart/#install-helm) is installed on your system.
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed on your system.
* A Kubernetes cluster that meets the [cluster requirements](/deployment/installing-connectware/system-requirements#kubernetes-cluster-requirements).
* A chosen Kubernetes namespace for the installation (e.g., `cybus`).
* A chosen installation name (e.g., `connectware`).

{% hint style="info" %}
Throughout this guide, command examples use variables like `${NAMESPACE}`, `${INSTALLATION_NAME}`, and `${REPO_NAME}`. Replace these with your actual values. For example, replace `${NAMESPACE}` with `cybus` if that is your chosen namespace.
{% endhint %}

## Overview of the Installation Process

To install Connectware on Kubernetes, complete the following steps:

1. [Choose a chart version](#choosing-a-chart-version).
2. [Configure a `values.yaml` file](#configuring-the-values.yaml-file).
3. [Install Connectware](#installing-connectware).
4. [Verify the installation](#verifying-the-connectware-installation).
5. [Log into Connectware for the first time](#logging-into-connectware-for-the-first-time).

## Choosing a Chart Version

When installing Connectware, you can either use the latest chart version or pin to a specific version.

When you do not specify a chart version, Helm installs the latest chart, which targets the latest Connectware release.

To install a specific version, look up your target Connectware version in the [Compatibility Matrix](/cybus-helm-charts/compatibility-matrix#connectware-helm-chart), find the matching Helm chart version, and install that version of the chart with the `--version` flag.

{% hint style="info" %}
For production environments, install a specific chart version. This gives you reproducible deployments and prevents unintended upgrades.
{% endhint %}

## Configuring the values.yaml File

The `values.yaml` file configures your Connectware deployment through Helm. Use it to customize deployment parameters, manage resources, and configure version settings.

This guide focuses on basic Kubernetes configuration and commonly used parameters.

{% hint style="info" %}
We recommend that you store the `values.yaml` file in a version control system.
{% endhint %}

### Creating a Copy of the Default values.yaml File

A Helm chart includes default configuration values. We recommend creating a copy of the default `values.yaml` file named `default-values.yaml` for reference, and a new empty `values.yaml` file for your customizations.

* Extract the default values and store them in `default-values.yaml` via the following command:

**Example**

{% code lineNumbers="true" %}

```bash
helm show values oci://repo.cybus.io/charts/connectware > default-values.yaml
```

{% endcode %}

### Creating a values.yaml File

After creating the `default-values.yaml` file, create an empty `values.yaml` file for your custom configuration.

* Create and open the file with your preferred editor via the following command. This example uses **vi**. Substitute with your preferred editor:

**Example**

{% code lineNumbers="true" %}

```bash
vi values.yaml
```

{% endcode %}

### Specifying the License Key

A valid license key is required to install Connectware.

#### Choosing a Method

You have the following methods for providing your license key. Choose the method that best fits your security and operational requirements:

* **Method 1 - Plaintext License Key**: For quick testing and development environments.
* **Method 2 - Kubernetes Secret**: For production environments where secrets should be managed separately from configuration files.

#### Method 1 - Plaintext License Key

* Add your license key directly in the `values.yaml` file. Replace `${LICENSE_KEY}` with your actual license key.

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  licenseKey: ${LICENSE_KEY}
```

{% endcode %}

#### Method 2 - Kubernetes Secret

Using this method, you manage your license key within your own workflow. You only provide Connectware with the name of a Kubernetes Secret that contains the key. This makes it suitable for production environments where security is a top concern.

When using this method, you must create at least one Secret:

* A generic Secret for the license key itself (required)
* A Docker registry Secret for pulling Connectware container images (optional, see warning below)

{% hint style="warning" %}
Unlike Method 1, the Helm chart does not automatically generate the image pull Secret when using an existing Kubernetes Secret for the license key. You must create it manually in step 2 below, unless you are using a custom registry that does not require authentication.
{% endhint %}

1. Create a generic Secret containing your license key under the key `licenseKey`. Replace `${LICENSE_KEY}` with your actual license key, `${LICENSE_SECRET_NAME}` with your chosen Secret name, and `${NAMESPACE}` with your target namespace.

{% code lineNumbers="true" %}

```bash
kubectl create secret generic ${LICENSE_SECRET_NAME} \
  --from-literal=licenseKey=${LICENSE_KEY} \
  -n ${NAMESPACE}
```

{% endcode %}

2. Optional: Create the Docker registry Secret to allow your cluster to pull Connectware container images. Replace `${REGISTRY_SECRET_NAME}` with your chosen Secret name. For the Cybus registry, use your Connectware license key as the password and `license` as the username. Skip this step only if you are using a custom registry that does not require authentication. If using a custom registry with authentication, adjust the `--docker-server`, `--docker-username`, and `--docker-password` values accordingly.

{% code lineNumbers="true" %}

```bash
kubectl create secret docker-registry ${REGISTRY_SECRET_NAME} \
  --docker-server=registry.cybus.io \
  --docker-username=license \
  --docker-password=${LICENSE_KEY} \
  -n ${NAMESPACE}
```

{% endcode %}

3. Reference the Secrets in your `values.yaml` file. Replace `${LICENSE_SECRET_NAME}` with your chosen license Secret name. If you completed step 2, also replace `${REGISTRY_SECRET_NAME}` with your chosen registry Secret name. If you skipped step 2, omit the `image.pullSecrets` section.

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  existingLicenseKeySecret: ${LICENSE_SECRET_NAME}
  image:
    pullSecrets:
      - name: ${REGISTRY_SECRET_NAME}
```

{% endcode %}

### Configuring DNS Names in Helm Values

When you are using Connectware's auto-generated TLS server certificate (`cybus_server.crt`), configure `global.ingressDNSNames` to define the hostnames Connectware includes in the certificate's Subject Alternative Names (SAN) list. External agents need these hostnames to connect to the Connectware control plane.

{% hint style="info" %}

## Providing your own TLS certificate

If you provide your own TLS server certificate, `global.ingressDNSNames` has no effect. Add the required hostnames to your certificate's SAN list directly.
{% endhint %}

* Set the `global.ingressDNSNames` list in your Helm values to include all hostnames used for Connectware access.

**Example**

If Connectware is accessible at hostname `company.io`, set the Helm value to:

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  ingressDNSNames:
    - company.io
```

{% endcode %}

#### Hostname Formats

You can include multiple hostnames in the list. The certificate includes all specified names in its SAN section.

The configuration accepts various hostname formats:

* Wildcards (e.g., `*.company.io`)
* Subdomains (e.g., `connectware.company.io`)
* Custom hostnames (e.g., `localhost`)

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  ingressDNSNames:
    - company.io
    - localhost
    - *.company.io
    - connectware.company.io
    - 192.168.100.42
```

{% endcode %}

### Specifying the NATS Streaming Server Cluster Replica Count (Optional)

Connectware uses a NATS streaming server cluster for inter-service communication on the control plane. By default, the cluster runs with three replicas.

You can configure an odd number of replicas to suit your environment:

* **Increase to five** for higher redundancy. Five replicas tolerate two simultaneous failures (N+2) instead of one (N+1).
* **Reduce to one** for lightweight test environments. A single-node setup provides no redundancy.

For production, three (the default) or five replicas are typical.

{% hint style="warning" %}

## You can only set the replica count at initial installation

The value defines the NATS cluster topology and is shared across many Connectware components, so it cannot be changed later. Do not attempt to scale the `nats` StatefulSet manually.
{% endhint %}

* In the `values.yaml` file, set the replica count via `nats.replicas`.

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
nats:
  replicas: 5
```

{% endcode %}

### Specifying the Broker Cluster Secret (Optional)

Connectware secures the internal broker cluster using a cluster secret.

{% hint style="warning" %}
Treat the broker cluster secret with the same care as a password. Store it securely and restrict access to authorized personnel only.
{% endhint %}

#### Choosing a Configuration Method

You have the following methods for configuring the broker cluster secret. Choose the method that best fits your security and operational requirements:

* **Method 1 - Auto-Generated Secret (Recommended)**: Helm generates a cryptographically secure random value at install time. No configuration required. Best for most installations.
* **Method 2 - Plaintext Secret in Helm Values**: You set the secret directly in your `values.yaml` file. Use only in non-production environments, since the value is stored unencrypted.
* **Method 3 - Existing Kubernetes Secret**: You create a Kubernetes Secret beforehand and reference it by name. Suits production environments that use external secret management systems or GitOps workflows.

#### Method 1 - Auto-Generated Secret (Recommended)

For most installations, let Helm automatically generate a secure random secret. This is the simplest and most secure approach for new deployments.

* Leave the broker cluster secret configuration empty in your `values.yaml` file. Helm generates and stores the secret automatically during installation.

{% hint style="info" %}
Helm stores the auto-generated secret in a Kubernetes Secret that persists across Helm upgrades. To retrieve it later, run `kubectl get secret -n ${NAMESPACE} -l app.kubernetes.io/name=broker-cluster-secret -o yaml`.
{% endhint %}

#### Method 2 - Plaintext Secret in Helm Values

Use this method for development environments or when you need to specify a known secret value for migration or testing purposes.

{% hint style="warning" %}
This method stores the secret in plaintext in your `values.yaml` file. Only use this in non-production environments or ensure your values file is stored securely.
{% endhint %}

* In the `values.yaml` file, specify the broker cluster secret in the Helm value `broker.clusterSecret`:

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
broker:
  clusterSecret: Uhoo:RahShie6goh4eid # example value
```

{% endcode %}

#### Method 3 - Existing Kubernetes Secret

Use this method for production environments where you manage secrets through a dedicated secret management system or GitOps workflow.

1. Create the Kubernetes Secret in the same namespace where you will install Connectware. The Secret must contain a key named `clusterSecret` with your secret value. Replace `${SECRET_NAME}` with your chosen Secret name and `${CLUSTER_SECRET}` with your actual cluster secret:

**Example**

{% code lineNumbers="true" %}

```bash
kubectl create secret generic ${SECRET_NAME} \
  --from-literal=clusterSecret="${CLUSTER_SECRET}" \
  -n ${NAMESPACE}
```

{% endcode %}

2. In the `values.yaml` file, reference the Secret name in the Helm value `broker.existingClusterSecret`:

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
broker:
  existingClusterSecret: ${SECRET_NAME}
```

{% endcode %}

{% hint style="info" %}
When using an existing Secret, Helm does not create or manage the cluster secret. You are responsible for ensuring the Secret exists before installation and for managing it throughout the lifecycle.
{% endhint %}

### Specifying the Broker Cluster Replica Count (Optional)

By default, Connectware uses three nodes for the broker cluster that moves data. You can specify a custom number of broker nodes. For example, increase the broker nodes to handle higher data loads or decrease the broker nodes for a testing environment.

* In the `values.yaml` file, specify the number of broker nodes in the Helm value `broker.replicas`.

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
broker:
  replicas: 5
```

{% endcode %}

### Specifying Which StorageClass Connectware Should Use (Optional)

A Kubernetes cluster can contain several StorageClasses. You can specify which StorageClass Connectware should use.

* In the `values.yaml` file, specify the StorageClass in the Helm value `global.persistence.storageClassName`.

**Example**

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  persistence:
    storageClassName: gp2 # example value
```

{% endcode %}

There are several configuration parameters to control the StorageClass of each volume that Connectware uses.

### Specifying CPU and Memory Resources (Optional)

By default, Connectware is configured with resource requests only, allowing it to burst and utilize available node resources when needed. To control the CPU and memory available to Connectware, set the Kubernetes `requests` and `limits` values under a component's `resources` Helm value, such as `protocolMapper.resources`.

{% hint style="warning" %}
Adjusting CPU and memory resources can impact the performance and availability of Connectware. When you customize the settings for CPU and memory resources, make sure that you monitor the performance and make adjustments if necessary.
{% endhint %}

For per-chart syntax, defaults, and examples, see [Configuring Compute Resources](/cybus-helm-charts/working-with-cybus-helm-charts/compute-resources). For guidance on measuring actual usage and right-sizing these values, see [Right-Sizing Kubernetes Resources for Connectware](/guides/operations/right-sizing-kubernetes-resources).

## Installing Connectware

After you have configured your `values.yaml` file, deploy Connectware to your Kubernetes cluster.

* Run the following command, specifying your installation name and target namespace:

**Example**

{% code lineNumbers="true" %}

```bash
helm install ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware --version ${VERSION} -f ./values.yaml -n ${NAMESPACE} --create-namespace
```

{% endcode %}

Replace `${VERSION}` with the chart version from the [Compatibility Matrix](/cybus-helm-charts/compatibility-matrix). Omit `--version` to install the latest available chart version.

**Result:** Connectware deploys to your cluster according to your kubectl configuration.

## Verifying the Connectware Installation

Monitor the Connectware installation progress to ensure everything runs smoothly and identify any potential issues.

### Monitoring the Installation Progress

The installation typically takes a few minutes. Choose one of these monitoring options:

* To monitor the current status of the installation process, enter the following command:

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

* To monitor the continuous progress of the installation process, enter the following command. This command refreshes every five seconds to reflect the current status:

{% code lineNumbers="true" %}

```bash
while true; do clear; kubectl get pods -n ${NAMESPACE}; sleep 5; done
```

{% endcode %}

* To stop monitoring the continuous progress of the installation process, press <kbd>Ctrl</kbd>+<kbd>C</kbd>.

### Pod Stages During Installation

During the Connectware installation, pods progress through these stages:

* Pending
* PodInitializing
* ContainerCreating
* Init:x/x
* Running

When pods reach `Running` status, they complete their startup process before reporting as ready. All pods must reach `Running` status with all containers ready. This is shown when the READY column displays matching numbers (e.g., `1/1`).

**Example**

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

| NAME                                   | READY | STATUS  | RESTARTS | AGE   |
| -------------------------------------- | ----- | ------- | -------- | ----- |
| admin-web-app-7cd8ccfbc5-bvnzx         | 1/1   | Running | 0        | 3h44m |
| auth-server-5b8c899958-f9nl4           | 1/1   | Running | 0        | 3m3s  |
| broker-0                               | 1/1   | Running | 0        | 3h44m |
| broker-1                               | 1/1   | Running | 0        | 2m1s  |
| connectware-ingress-7784b5f4c5-g8krn   | 1/1   | Running | 0        | 21s   |
| container-manager-558d9c4cbf-m82bz     | 1/1   | Running | 0        | 3h44m |
| ingress-controller-6bcf66495c-l5dpk    | 1/1   | Running | 0        | 18s   |
| postgresql-0                           | 1/1   | Running | 0        | 3h44m |
| protocol-mapper-67cfc6c848-qqtx9       | 1/1   | Running | 0        | 3h44m |
| service-manager-f68ccb767-cftps        | 1/1   | Running | 0        | 3h44m |
| system-control-server-58f47c69bf-plzt5 | 1/1   | Running | 0        | 3h44m |
| workbench-5c69654659-qwhgc             | 1/1   | Running | 0        | 15s   |

**Result:** When all pods show `Running` status with matching READY values, Connectware is installed and started. You can now access the [Admin UI](/access/admin-ui) for additional configuration or verification.

### Troubleshooting Pod Stages

If a pod is in a different state than expected or if it is stuck at a certain stage for more than three minutes, there might be an issue.

* To investigate the pod status, enter the following command:

{% code lineNumbers="true" %}

```bash
kubectl describe pod ${PODNAME} -n ${NAMESPACE}
```

{% endcode %}

For help on solving issues, see [Troubleshooting Connectware on Kubernetes](/cybus-helm-charts/troubleshooting-on-kubernetes).

## Logging Into Connectware for the First Time

Access the [Admin UI](/access/admin-ui) through the Kubernetes LoadBalancer Service. In your new Connectware installation, the LoadBalancer is named `connectware`. How to access the LoadBalancer depends on which LoadBalancer provider your cluster offers.

1. Check if your load balancer provider has connected to your Connectware service via the following command:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} get svc/connectware
```

{% endcode %}

2. Depending on the result, do one of the following:
   1. If your IP address or hostname is displayed in the `EXTERNAL-IP` column, you can access the Admin UI through it.
   2. If no load balancer provider is available in your cluster, you can add an external load balancer.
3. To verify that the installation was successful, enter the following command to forward the service to your local machine through kubectl:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} port-forward svc/connectware 10443:443
```

{% endcode %}

4. Access the Admin UI at `https://localhost:10443`. Connectware uses its own PKI infrastructure by default.
5. Accept the certificate warning in your browser.
6. Retrieve the initial password. During installation, Connectware generates a random password and stores it in the Kubernetes Secret `connectware-initial-password` as a double base64-encoded value. The following command retrieves and decodes it:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} get secret connectware-initial-password -o jsonpath="{.data.initialPassword}" | base64 -d | base64 -d
```

{% endcode %}

7. In the [Admin UI](/access/admin-ui), log in with username `admin` and the password retrieved in the previous step.

{% hint style="danger" %}
Immediately change the default username and password after your first login.
{% endhint %}

8. To change the username and password, see [Changing Usernames](/access/user-management/users#changing-usernames) and [Changing User Passwords](/access/user-management/users#changing-user-passwords).
9. Navigate to **System** > **Status** and verify all components show **Running** status.

**Result:** Your Connectware installation is ready to use.

For more information about LoadBalancer services, see [LoadBalancer (Kubernetes documentation)](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer).


# Installing Connectware (Docker)

Install Connectware on Docker using Docker Compose.

This guide walks you through installing Connectware on Docker using an installer script. The script automates the setup process and supports both interactive and silent installation modes. You can optionally configure Connectware to run as a systemd service for automatic startup.

{% hint style="info" %}
For environments without Internet access, see [Offline Installation](/deployment/installing-connectware/offline-on-docker).
{% endhint %}

## Prerequisites

Before installing Connectware, make sure to meet the following requirements:

* Connectware [license key](/deployment/licensing) is available.
* You have an Internet connection to download Docker images from `registry.cybus.io`.
* Docker and Docker Compose are installed and running on your host.
  * For more information on installing Docker, refer to the [Docker documentation](https://docs.docker.com/get-docker/). Docker Desktop includes Docker Compose along with Docker Engine and Docker CLI which are Compose prerequisites.
* You are familiar with Docker.

## Preparing the Installer Script

The installer script allows you to quickly install Connectware.

1. Download the installer script for the Connectware version that you want to install.
   * Download link for the installer script of the latest Connectware version: <https://download.cybus.io/latest/connectware-online-installer.sh>
   * To download the installer script for a specific Connectware version, use the following link and replace with the Connectware version: [https://download.cybus.io//connectware-online-installer.sh](https://download.cybus.io/%3CVERSION%3E/connectware-online-installer.sh)
   * For example, to download the installer script for Connectware 2.1.2, use the following link: <https://download.cybus.io/2.1.2/connectware-online-installer.sh>\
     \
     In the example below, we will use the latest version of Connectware.

{% code lineNumbers="true" %}

```bash
wget -O ./connectware-online-installer.sh https://download.cybus.io/latest/connectware-online-installer.sh
```

{% endcode %}

2. Make the script executable:

{% code lineNumbers="true" %}

```bash
chmod +x ./connectware-online-installer.sh
```

{% endcode %}

**Result:** You can now run the installer script to install Connectware.

You can run the installer in two modes:

* **Interactive mode:** Follow the prompts to configure your installation. See [Running the Installer Script](#running-the-installer-script).
* **Silent mode:** Use command-line parameters for automated deployment. See [Running the Installation in Silent Mode](#running-the-installation-in-silent-mode).

## Running the Installer Script

{% hint style="warning" %}
You can run the installer script without administrator rights in most cases. However, sudo privileges are required in two scenarios:

1. When setting up Connectware as a systemd service (recommended).
2. When installing to a directory that needs elevated permissions.

Since this guide demonstrates installing Connectware with systemd service integration, we will use sudo in the following commands.
{% endhint %}

1. Run the installer script:

{% code lineNumbers="true" %}

```bash
sudo ./connectware-online-installer.sh
```

{% endcode %}

2. The installer displays the Connectware version. Press **Enter** to confirm.
3. Enter your desired installation directory, or press **Enter** to use the default path: `/opt/connectware`
4. The installer runs preflight checks to verify all system requirements are met. If any checks fail, review the [Prerequisites](#prerequisites) section and check if your system meets all requirements.

If all requirements are met, the following output will appear:

{% code lineNumbers="true" %}

```bash
Running preflight checks.
=========================
Validating write permission to installation location /opt/connectware: [OK]
Checking whether this system has systemd: [YES]
Validating required utility installation: [OK]
Validating reachable URL for Cybus docker-registry: [OK]
Validating Docker installation: [OK]
Validating Docker Compose installation: [OK]
Validating that no former Connectware is running: [OK]
Preflight checks finished successfully!
```

{% endcode %}

5. Enter your Cybus license key when prompted. If your license key is valid, you will see a success message.

{% code lineNumbers="true" %}

```bash
Verifying license key...
Login succeeded.
```

{% endcode %}

6. Enter the ingress hostnames under which you will access Connectware. You can specify multiple values by separating them with commas. This allows you to define any hostnames, wildcard domains, and IP addresses that agents use to connect to Connectware. All values are added to the certificate's SAN field, enabling secure agent connections through any of the configured access points. You can change the hostnames later by setting the `CYBUS_INGRESS_DNS_NAMES` environment variable.

{% hint style="info" %}
If you are replacing the external Connectware CA certificate chain and manage `cybus_server.crt` manually, ensure that any DNS name with which you address Connectware or individual components is included. You can skip adding them to `CYBUS_INGRESS_DNS_NAMES`.
{% endhint %}

**Example**

{% code lineNumbers="true" %}

```bash
Ingress Hostnames [localhost]:
my.company.tld
```

{% endcode %}

7. Choose whether to run Connectware as a systemd service. Without this, you must start Connectware manually after each system restart. In this guide, press <kbd>Enter</kbd> to confirm.
8. Review the configuration summary and confirm your settings are correct. If you followed the steps in this guide, the following output will appear:

{% code lineNumbers="true" %}

```bash
Please review and confirm the following Connectware configuration:
------------------------------------------------------------------

Connectware license key:       [VALID]
Installation directory:       /opt/connectware
Autostart as systemd service: true

Accept configuration? [Y/n]
```

{% endcode %}

9. The installer downloads the Connectware container images. After download completes, it checks for old container images from previous Connectware versions that can be safely removed ("pruned") to free disk space. The installer asks for confirmation before removing any images.

{% code lineNumbers="true" %}

```bash
-----------------------------------------
Removing old Docker images
-----------------------------------------

The following Docker images are from previous Connectware versions and can be removed:

REPOSITORY                            TAG          IMAGE ID  CREATED      SIZE
registry.cybus.io/cybus/admin-web-app ***********  e561383a5 24 hours ago 21.5MB
REPOSITORY                            TAG          IMAGE ID  CREATED      SIZE
registry.cybus.io/cybus/auth-server   ***********  a65b7f32f 24 hours ago 165MB
REPOSITORY                            TAG          IMAGE ID  CREATED      SIZE
registry.cybus.io/cybus/broker        ***********  80dd0fb24 24 hours ago 56.7MB
(...)

-----------------------------------------

Should the above docker images be removed from your local computer (pruned)? [Y/n]
```

{% endcode %}

10. After confirming, the installer displays the image removal results and shows a success message with commands to manage Connectware. In our example, the following output will appear:

{% code lineNumbers="true" %}

```bash
Successfully installed Connectware!
===================================
You can find the installation directory at /opt/connectware.
In order to stop type:
systemctl stop connectware
```

{% endcode %}

## Accessing Connectware

After installation, you can access Connectware through your web browser:

1. Open your web browser.
2. Navigate to `https://localhost` or the hostname you configured during installation.
3. Log in using the default credentials:
   * **Username:** `admin`
   * **Password:** `admin`

{% hint style="warning" %}
For security reasons, change the default admin password immediately after your first login. See [Default Admin User](/access/user-management/users/default-admin-user) for more information.
{% endhint %}

### Verifying the Installation

To verify that Connectware is running correctly, use one of the following commands:

**For Docker installations**

{% code lineNumbers="true" %}

```bash
docker ps | grep connectware
```

{% endcode %}

**For systemd service installations**

{% code lineNumbers="true" %}

```bash
systemctl status connectware
```

{% endcode %}

### Managing the Connectware Service

If you installed Connectware as a systemd service, you can manage it with the following commands:

{% code lineNumbers="true" %}

```bash
# Start Connectware
systemctl start connectware

# Stop Connectware
systemctl stop connectware

# Restart Connectware
systemctl restart connectware

# Check Connectware status
systemctl status connectware

# Enable Connectware to start on boot
systemctl enable connectware

# Disable Connectware from starting on boot
systemctl disable connectware
```

{% endcode %}

## Running the Installation in Silent Mode

The installer supports an automated deployment mode that requires no manual intervention. You can activate this by using either `-s` or `--silent` when [running the installation script](#running-the-installer-script).

For silent installations, you must provide your license key through the `--license-key` parameter. By default, this method installs a basic version of Connectware to `/opt/connectware` and skips the systemd service setup.

**Example with common options**

{% code lineNumbers="true" %}

```bash
sudo ./connectware-online-installer.sh \
  -s \
  -k your-license-key-here \
  -d /opt/connectware \
  -H "my.domain.com,192.168.1.100" \
  -S
```

{% endcode %}

This example installs Connectware in silent mode `-s`, uses a specific license key `-k`, installs to `/opt/connectware` directory `-d`, configures multiple hostname entries `-H`, and sets up the systemd service `-S`.

If you need to customize your installation further, the script offers several configuration options. Run the installer with `--help` to view all available parameters.

## Updating SSL Certificates

When you need to update your SSL certificates (such as after a Let's Encrypt renewal via `certbot` or when adding self-signed certificates), follow these steps:

1. Copy the new certificates to the container:

{% code lineNumbers="true" %}

```bash
docker cp -L ${PATH_TO_KEY_FILE} ${CONNECTWARE_CONTAINER}:/connectware_certs/cybus_server.key
docker cp -L ${PATH_TO_CERT_FILE} ${CONNECTWARE_CONTAINER}:/connectware_certs/cybus_server.crt
```

{% endcode %}

2. The name of your Connectware container depends on the directory it was installed to and is rendered as `${CONNECTWARE_DIRECTORY}_connectware_1`. By default, Connectware is installed to `/opt/connectware/` which results in the container name `connectware_connectware_1`.
3. Restart the Connectware container to apply the new certificates. Replace `${CONNECTWARE_CONTAINER}` with the name of your Connectware container:

{% code lineNumbers="true" %}

```bash
docker restart ${CONNECTWARE_CONTAINER}
```

{% endcode %}


# Offline Installation (Kubernetes)

Install Connectware on a Kubernetes cluster without Internet access using Cybus Helm charts.

This guide walks you through installing Connectware on Kubernetes in environments without Internet access. When your Kubernetes cluster cannot reach external registries, you must adapt the standard installation procedure:

1. **Images:** Container images cannot be pulled directly from `registry.cybus.io`.
2. **Helm Chart:** The chart cannot be downloaded dynamically from the Cybus Helm repository.
3. **Licensing:** The Connectware license key cannot be validated online. You must use an offline license file provided by Cybus.

The examples use a local single-node Kubernetes cluster with an internal image and Helm chart registry. While this is not a likely production environment, the concept translates to large Kubernetes clusters, and mimics some infrastructure you may already have, like an OCI registry.

{% hint style="info" %}
In production environments, isolation setups vary widely. You might be working with a completely air-gapped system requiring physical transfer mediums such as a USB drive, or a corporate network where you can use a bastion host or sync images directly into an internal registry.

This guide demonstrates the entire procedure on a local cluster with a registry running on the same host. Adapt the registry address and transfer method to match your environment.
{% endhint %}

## Prerequisites

* A local system with Internet access
* Docker installed on your host system
* `kind`, `helm`, `skopeo`, and `kubectl` installed on your host system
* Connectware license key (for authenticating with the Cybus registry)
* Access to the [Cybus Portal](https://portal.cybus.io/) to download license files

{% stepper %}
{% step %}

## Download License Files

Download the license key and offline license file from the Cybus Portal. You need the license key to authenticate with the Cybus registry when downloading container images, and the offline license file to validate Connectware in environments without Internet access.

1. Go to the [Cybus Portal](https://portal.cybus.io/).
2. Sign in with your credentials.
3. Navigate to **Licenses** to view your available Connectware licenses.
4. Select your license and download both the **license key file** (`.key`) and **license file** (`.lic`).
5. Save both files in a secure location on your system.

For detailed instructions on obtaining license files, see [Acquiring License Keys](/deployment/licensing#acquiring-license-keys).
{% endstep %}

{% step %}

## Setting Up the Local Registry

Set up a local Docker registry as a standalone container and configure the `kind` cluster to trust and communicate with it. Skip this section if you already have a Kubernetes cluster and OCI registry.

1. Create the registry container:

{% code lineNumbers="true" %}

```bash
docker run -d --restart=always -p 5001:5000 --name kind-registry registry:2
```

{% endcode %}

2. Create a file named `kind-config.yaml` to configure `containerd` to use the standalone registry:

{% code title="kind-config.yaml" lineNumbers="true" %}

```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
  - |-
    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "/etc/containerd/certs.d"
nodes:
  - role: control-plane
    kubeadmConfigPatches:
      - |
        kind: InitConfiguration
        nodeRegistration:
          kubeletExtraArgs:
            node-labels: "ingress-ready=true"
```

{% endcode %}

3. Apply the cluster configuration:

{% code lineNumbers="true" %}

```bash
kind create cluster --config kind-config.yaml
```

{% endcode %}

4. Connect the `kind-registry` to the `kind` network and configure each node to route `localhost:5001` to it:

{% code lineNumbers="true" %}

```bash
# Connect the registry to the cluster network
docker network connect kind kind-registry

# Configure each node to route localhost:5001 to the registry
REGISTRY_DIR="/etc/containerd/certs.d/localhost:5001"
for node in $(kind get nodes); do
  docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
  cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
[host."http://kind-registry:5000"]
EOF
done
```

{% endcode %}

{% hint style="info" %}
The registry is now accessible from your host machine at `localhost:5001`. The Kubernetes cluster routes pod-level image pulls for `localhost:5001` directly to the `kind-registry` container.

These steps follow the official [Kind Local Registry documentation](https://kind.sigs.k8s.io/docs/user/local-registry/). If you already have a Kubernetes environment and registry configured, skip this section and substitute `localhost:5001` with your registry's URL in the steps below.
{% endhint %}
{% endstep %}

{% step %}

## Preparing the Artifacts

### Downloading the Helm Chart

Download the `connectware` Helm chart from the Cybus OCI repository as a `.tgz` package and push it to your local registry:

{% code lineNumbers="true" %}

```bash
# Download the chart
helm pull oci://repo.cybus.io/charts/connectware --version ${CHART_VERSION}

# Push to your local registry
# --plain-http is required because the local registry has no TLS certificate configured
helm push connectware-${CHART_VERSION}.tgz oci://localhost:5001/helm --plain-http
```

{% endcode %}

Replace `${CHART_VERSION}` with the `connectware` Helm chart version you want to install. See the [Compatibility Matrix](/cybus-helm-charts/compatibility-matrix#connectware-helm-chart) for the chart version that matches your target Connectware version.

Repeat this step for the `connectware-agent` Helm chart, if required.

### Downloading Container Images

Generate a list of images required by the connectware Helm chart, then copy them directly to your local registry using `skopeo`:

{% code lineNumbers="true" %}

```bash
# Generate the image list from the chart
helm template connectware ./connectware-${CHART_VERSION}.tgz | awk '/image:/ {print $2}' | sed 's/"//g' | sort | uniq > images.txt

# Copy images to the local registry
while read image; do
  image_name=$(basename $image)
  skopeo copy --src-creds "license:${LICENSE_KEY}" \
    docker://$image docker://localhost:5001/$image_name \
    --dest-tls-verify=false
done < images.txt
```

{% endcode %}

Replace `${LICENSE_KEY}` with the Connectware license key [downloaded in step 1](#download-license-files).

{% hint style="info" %}
`--dest-tls-verify=false` is used because the local registry in this example has no TLS certificate configured. In production environments with secure registries, omit this flag.
{% endhint %}
{% endstep %}

{% step %}

## Configuring the Image Registry

The `connectware` Helm chart needs to know which registry to pull its component images from. Set `global.image.registry` to your internal registry address.

If your internal registry requires authentication, first create a pull secret in the namespace where Connectware will be deployed. If it does not require authentication, skip this step.

{% code lineNumbers="true" %}

```bash
kubectl create secret docker-registry my-local-registry-secret \
  --docker-server=my.internal.registry.com \
  --docker-username=${REGISTRY_USERNAME} \
  --docker-password=${REGISTRY_PASSWORD} \
  --namespace=${NAMESPACE}
```

{% endcode %}

Replace `${REGISTRY_USERNAME}` and `${REGISTRY_PASSWORD}` with the credentials for your internal registry, and `${NAMESPACE}` with the Kubernetes namespace where you plan to install Connectware.

Then reference the registry in your `values.yaml`:

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  image:
    registry: 'localhost:5001'
    # Only required if your registry uses authentication
    # pullSecrets:
    #   - name: my-local-registry-secret
```

{% endcode %}
{% endstep %}

{% step %}

## Providing the Offline License Details

Connectware requires a license key in all installations. In an online environment, this key is validated against the Cybus Portal. For offline installations, you must also provide a pre-validated offline license file [downloaded in step 1](#download-license-files).

You can provide license details in the following ways.

### Using Direct Helm Values

Provide both your Connectware license key and the license file payload directly in your `values.yaml`:

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  licenseKey: ${LICENSE_KEY}
  licenseFile: ${LICENSE_FILE}
```

{% endcode %}

Replace `${LICENSE_KEY}` with your Connectware license key and `${LICENSE_FILE}` with the contents of the offline license file (`.lic`) downloaded in step 1.

### Using Existing Kubernetes Secrets

Store the license key and license file in Kubernetes Secrets and reference them in the Helm values. This approach is more secure than embedding credentials directly in values files and prevents secrets from being stored in version control.

{% hint style="info" %}
**Recommended for production.** Using Kubernetes Secrets separates sensitive credentials from configuration and follows Kubernetes security best practices.
{% endhint %}

1. Create the Secrets:

{% code lineNumbers="true" %}

```bash
# Store the license key
kubectl create secret generic connectware-offline-license-key \
  --from-literal=licenseKey=${LICENSE_KEY} \
  --namespace=${NAMESPACE}

# Store the offline license file saved as connectware-license.txt
# The explicit licenseFile= ensures the secret key is correctly named
kubectl create secret generic connectware-offline-license-file \
  --from-file=licenseFile=connectware-license.txt \
  --namespace=${NAMESPACE}
```

{% endcode %}

Replace `${LICENSE_KEY}` with your Connectware license key.

2. Reference the Secrets in your `values.yaml`:

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  existingLicenseKeySecret: connectware-offline-license-key
  existingLicenseFileSecret: connectware-offline-license-file
```

{% endcode %}

{% hint style="warning" %}
Define either `licenseFile` or `existingLicenseFileSecret` — not both. The same applies to `licenseKey` and `existingLicenseKeySecret`. If both are set, the Secret reference takes priority.
{% endhint %}
{% endstep %}

{% step %}

## Installing Connectware

With your registry populated and license configured, install Connectware using the Helm chart and images from your local registry. Your final `values.yaml` combines the registry configuration and license details:

{% code title="values.yaml" lineNumbers="true" %}

```yaml
global:
  # Using the offline license via Secret references
  existingLicenseKeySecret: connectware-offline-license-key
  existingLicenseFileSecret: connectware-offline-license-file

  image:
    # Internal registry configured on the cluster nodes
    registry: 'localhost:5001'
    # pullSecrets are not needed if the registry does not require authentication
    # pullSecrets:
    #   - name: my-local-registry-secret
```

{% endcode %}

Install the Helm chart from your local OCI registry:

{% code lineNumbers="true" %}

```bash
helm upgrade --install connectware oci://localhost:5001/helm/connectware \
  --version ${CHART_VERSION} \
  --namespace ${NAMESPACE} \
  --create-namespace \
  -f values.yaml
```

{% endcode %}

Connectware initializes and pulls all images from your local registry.
{% endstep %}
{% endstepper %}

## Verifying the Installation

Verify that all Connectware pods are running and pulling images from your local registry:

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

All pods should show a `Running` status. To verify that images are being pulled from your local registry, check the image URLs for all Connectware pods:

{% code lineNumbers="true" %}

```bash
kubectl get pod -n ${NAMESPACE} -l app.kubernetes.io/part-of=connectware -o jsonpath='{range .items[*]}{@.metadata.name}{": "}{@.spec.containers[0].image}{"\n"}{end}'
```

{% endcode %}

The image URLs should reference your local registry (`localhost:5001` in this example).

## Accessing Connectware

After installation, access Connectware through your web browser:

1. Determine the ingress hostname configured during installation.
2. Navigate to `https://${HOSTNAME}` in your web browser, replacing `${HOSTNAME}` with the ingress hostname.
3. Log in using the default credentials:
   * **Username:** `admin`
   * **Password:** `admin`

{% hint style="warning" %}
For security reasons, change the default admin password immediately after your first login. See [Default Admin User](/access/user-management/users/default-admin-user).
{% endhint %}

## License Validation in Offline Environments

When running Connectware in an offline environment, you may see a warning message in the system status indicating that the system cannot connect to the license validation server at `https://graphql-server.cybus.io/graphql`.

{% hint style="info" %}
This warning can be safely ignored in offline installations. The license validation has already been performed locally using the offline license file you provided. Your license will show as valid.
{% endhint %}

The license information is stored in the Kubernetes Secret and does not require Internet connectivity to function. However, you will not be able to refresh the license automatically from the Admin UI, as this feature requires Internet access.


# Offline Installation (Docker)

Install Connectware on Docker in offline environments using Docker Compose.

This guide walks you through the process of installing Connectware in offline environments using Docker Compose. The offline installation process is designed for environments where Internet access is limited, unavailable, or restricted for security reasons.

The offline installation process has two phases:

1. **Preparation phase**: Use a donor PC with Internet access to download the Docker images, the installer script, and the license files.
2. **Installation phase**: Transfer the files to the recipient PC and install Connectware without Internet connectivity.

## Prerequisites

### Donor PC Requirements

* Internet connection
* Docker installed and running
* Terminal access (Linux, macOS, or Windows with WSL)
* Connectware license key (for authenticating with the Cybus registry)
* Access to the [Cybus Portal](https://portal.cybus.io/) to download license files
* USB drive or other transfer medium for moving files

{% hint style="info" %}
Connectware does not need to be pre-installed on the donor PC. The Docker images will be pulled directly from the Cybus registry. However, if you already have Connectware installed, the existing Docker images can be reused, which will save time by skipping the pull step.
{% endhint %}

### Recipient PC Requirements

* Operating System: Linux
* Docker and Docker Compose installed and running
  * For more information on installing Docker, refer to the [Docker documentation](https://docs.docker.com/get-docker/). Docker Desktop includes Docker Compose along with Docker Engine and Docker CLI which are Compose prerequisites.
* No Internet connection required
* Sufficient disk space for Docker images (typically 5-10 GB for version 2.1.2)

## Phase 1: Preparing Files on the Donor PC

Follow these steps on a computer with Internet access to download and prepare all required files.

{% stepper %}
{% step %}

### Create a Storage Folder

* Create a dedicated folder to store all required files for the offline installation.

{% code lineNumbers="true" %}

```bash
mkdir connectware-offline
cd connectware-offline
```

{% endcode %}
{% endstep %}

{% step %}

### Determine the Connectware Version

Determine which Connectware version you need to install.

If you already have Connectware running on the donor PC, you can identify the installed version:

{% code lineNumbers="true" %}

```bash
docker images | grep registry.cybus.io/cybus
```

{% endcode %}

Look for the version number in the image tags (e.g., `2.0.0`, `2.1.0`, `2.1.2`).
{% endstep %}

{% step %}

### Authenticate with the Cybus Registry

1. Before downloading Docker images, authenticate with the Cybus registry using your license key.

{% code lineNumbers="true" %}

```bash
# Log in to the Cybus registry
# You will be prompted for your license key as the password
docker login registry.cybus.io -u license
```

{% endcode %}

2. When prompted, enter your license key (the same one you will use for installation).

**Result:** You are now authenticated and can pull Docker images from the Cybus registry.
{% endstep %}

{% step %}

### Download Docker Images

Download all required Docker images for your Connectware version. This involves pulling images from the registry and then saving them to tar files.

{% hint style="warning" %}
If you already have Connectware installed on the donor PC, the required images may already exist locally in your Docker daemon. If all required images for your target version are present, you can skip the docker pull commands and proceed directly to the docker image save commands below.
{% endhint %}

* To verify which images are already available locally, run the following command. If all required images for your target version are listed, you can skip the pull step.

{% code lineNumbers="true" %}

```bash
docker images | grep registry.cybus.io/cybus
```

{% endcode %}

* To pull the required images, run the following commands. Make sure to replace `${VERSION}` with the version you want to install.

{% hint style="warning" %}
The required images may vary between Connectware versions. The list below is for version 2.1.2 and later. For earlier versions, verify the required images by checking the installer script or consulting the release notes.
{% endhint %}

{% code lineNumbers="true" %}

```bash
# Set your Connectware version
VERSION=${VERSION}

# Pull all required images from the registry# Skip these pull commands if images already exist locally from an existing Connectware installationdocker pull registry.cybus.io/cybus/admin-web-app:${VERSION}
docker pull registry.cybus.io/cybus/auth-server:${VERSION}
docker pull registry.cybus.io/cybus/broker:${VERSION}
docker pull registry.cybus.io/cybus/container-manager:${VERSION}
docker pull registry.cybus.io/cybus/ingress-controller:${VERSION}
docker pull registry.cybus.io/cybus/ingress:${VERSION}
docker pull registry.cybus.io/cybus/nats:${VERSION}
docker pull registry.cybus.io/cybus/postgresql:${VERSION}
docker pull registry.cybus.io/cybus/protocol-mapper:${VERSION}
docker pull registry.cybus.io/cybus/resource-status-tracking:${VERSION}
docker pull registry.cybus.io/cybus/service-manager:${VERSION}
docker pull registry.cybus.io/cybus/system-control-server:${VERSION}
docker pull registry.cybus.io/cybus/topic-explorer:${VERSION}
docker pull registry.cybus.io/cybus/workbench:${VERSION}

# Save all images to tar files
docker image save -o admin-web-app_${VERSION}.tar registry.cybus.io/cybus/admin-web-app:${VERSION}
docker image save -o auth-server_${VERSION}.tar registry.cybus.io/cybus/auth-server:${VERSION}
docker image save -o broker_${VERSION}.tar registry.cybus.io/cybus/broker:${VERSION}
docker image save -o container-manager_${VERSION}.tar registry.cybus.io/cybus/container-manager:${VERSION}
docker image save -o ingress-controller_${VERSION}.tar registry.cybus.io/cybus/ingress-controller:${VERSION}
docker image save -o ingress_${VERSION}.tar registry.cybus.io/cybus/ingress:${VERSION}
docker image save -o nats_${VERSION}.tar registry.cybus.io/cybus/nats:${VERSION}
docker image save -o postgresql_${VERSION}.tar registry.cybus.io/cybus/postgresql:${VERSION}
docker image save -o protocol-mapper_${VERSION}.tar registry.cybus.io/cybus/protocol-mapper:${VERSION}
docker image save -o resource-status-tracking_${VERSION}.tar registry.cybus.io/cybus/resource-status-tracking:${VERSION}
docker image save -o service-manager_${VERSION}.tar registry.cybus.io/cybus/service-manager:${VERSION}
docker image save -o system-control-server_${VERSION}.tar registry.cybus.io/cybus/system-control-server:${VERSION}
docker image save -o topic-explorer_${VERSION}.tar registry.cybus.io/cybus/topic-explorer:${VERSION}
docker image save -o workbench_${VERSION}.tar registry.cybus.io/cybus/workbench:${VERSION}
```

{% endcode %}

**Example for version 2.1.2**

{% code lineNumbers="true" %}

```bash
VERSION=2.1.2

# Pull all required images
# Skip these pull commands if images already exist locally from an existing Connectware installation
docker pull registry.cybus.io/cybus/admin-web-app:${VERSION}
docker pull registry.cybus.io/cybus/auth-server:${VERSION}
docker pull registry.cybus.io/cybus/broker:${VERSION}
docker pull registry.cybus.io/cybus/container-manager:${VERSION}
docker pull registry.cybus.io/cybus/ingress-controller:${VERSION}
docker pull registry.cybus.io/cybus/ingress:${VERSION}
docker pull registry.cybus.io/cybus/nats:${VERSION}
docker pull registry.cybus.io/cybus/postgresql:${VERSION}
docker pull registry.cybus.io/cybus/protocol-mapper:${VERSION}
docker pull registry.cybus.io/cybus/resource-status-tracking:${VERSION}
docker pull registry.cybus.io/cybus/service-manager:${VERSION}
docker pull registry.cybus.io/cybus/system-control-server:${VERSION}
docker pull registry.cybus.io/cybus/topic-explorer:${VERSION}
docker pull registry.cybus.io/cybus/workbench:${VERSION}

# Save all images to tar files
docker image save -o admin-web-app_2.1.2.tar registry.cybus.io/cybus/admin-web-app:2.1.2
docker image save -o auth-server_2.1.2.tar registry.cybus.io/cybus/auth-server:2.1.2
docker image save -o broker_2.1.2.tar registry.cybus.io/cybus/broker:2.1.2
docker image save -o container-manager_2.1.2.tar registry.cybus.io/cybus/container-manager:2.1.2
docker image save -o ingress-controller_2.1.2.tar registry.cybus.io/cybus/ingress-controller:2.1.2
docker image save -o ingress_2.1.2.tar registry.cybus.io/cybus/ingress:2.1.2
docker image save -o nats_2.1.2.tar registry.cybus.io/cybus/nats:2.1.2
docker image save -o postgresql_2.1.2.tar registry.cybus.io/cybus/postgresql:2.1.2
docker image save -o protocol-mapper_2.1.2.tar registry.cybus.io/cybus/protocol-mapper:2.1.2
docker image save -o resource-status-tracking_2.1.2.tar registry.cybus.io/cybus/resource-status-tracking:2.1.2
docker image save -o service-manager_2.1.2.tar registry.cybus.io/cybus/service-manager:2.1.2
docker image save -o system-control-server_2.1.2.tar registry.cybus.io/cybus/system-control-server:2.1.2
docker image save -o topic-explorer_2.1.2.tar registry.cybus.io/cybus/topic-explorer:2.1.2
docker image save -o workbench_2.1.2.tar registry.cybus.io/cybus/workbench:2.1.2
```

{% endcode %}

{% hint style="info" %}
The image download process may take several minutes depending on your Internet connection speed. Each image will be pulled from the registry and then saved to a tar file. The tar files will be several hundred megabytes each.
{% endhint %}
{% endstep %}

{% step %}

### Download the Installer Script

* Download the Connectware installer script for your target version.

{% code lineNumbers="true" %}

```bash
# Download the installer script for a specific version
wget -O ./connectware-online-installer.sh https://download.cybus.io/${VERSION}/connectware-online-installer.sh

# Make the script executable
chmod +x ./connectware-online-installer.sh
```

{% endcode %}

**Example for version 2.1.2**

{% code lineNumbers="true" %}

```bash
wget -O ./connectware-online-installer.sh https://download.cybus.io/2.1.2/connectware-online-installer.sh
chmod +x ./connectware-online-installer.sh
```

{% endcode %}

{% hint style="info" %}
If you already have Connectware installed and the installer script is available at `/opt/connectware`, you can copy it from there instead of downloading it.
{% endhint %}
{% endstep %}

{% step %}

### Download License Files

1. Go to the [Cybus Portal](https://portal.cybus.io/).
2. Sign in with your credentials.
3. Navigate to **Licenses** to view your available Connectware licenses.
4. Select your license and download both the **license key file** (`.key`) and **license file** (`.lic`).
5. Save both files to your storage folder (`connectware-offline`).

For detailed instructions on obtaining license files, see [Acquiring License Keys](/deployment/licensing#acquiring-license-keys).
{% endstep %}

{% step %}

### Transfer Files to USB Drive

Copy all files from your storage folder to a USB drive or other transfer medium:

* All Docker image `.tar` files
* `connectware-online-installer.sh` script
* License key file (`.key`)
* License file (`.lic`)

**Result:** You have prepared all necessary files for offline installation. You can now proceed to the recipient PC.
{% endstep %}
{% endstepper %}

## Phase 2: Installing Connectware on the Recipient PC

Follow these steps on the offline recipient PC to install Connectware.

{% stepper %}
{% step %}

### Prepare the Installation Directory

1. Copy all files from the USB drive to a folder on the recipient PC.
2. Open a terminal and navigate to the folder containing the transferred files.

{% code lineNumbers="true" %}

```bash
cd /path/to/your/installation/folder
```

{% endcode %}
{% endstep %}

{% step %}

### Start Docker

Ensure Docker is running on the recipient PC:

{% code lineNumbers="true" %}

```bash
sudo systemctl start docker
```

{% endcode %}
{% endstep %}

{% step %}

### Load Docker Images

Load each Docker image into Docker. Replace `${VERSION}` with your Connectware version.

{% code lineNumbers="true" %}

```bash
# Replace ${VERSION} with your Connectware version
VERSION=${VERSION}

# Load all images
docker image load -i admin-web-app_${VERSION}.tar
docker image load -i auth-server_${VERSION}.tar
docker image load -i broker_${VERSION}.tar
docker image load -i container-manager_${VERSION}.tar
docker image load -i ingress-controller_${VERSION}.tar
docker image load -i ingress_${VERSION}.tar
docker image load -i nats_${VERSION}.tar
docker image load -i postgresql_${VERSION}.tar
docker image load -i protocol-mapper_${VERSION}.tar
docker image load -i resource-status-tracking_${VERSION}.tar
docker image load -i service-manager_${VERSION}.tar
docker image load -i system-control-server_${VERSION}.tar
docker image load -i topic-explorer_${VERSION}.tar
docker image load -i workbench_${VERSION}.tar
```

{% endcode %}

**Example for version 2.1.2**

{% code lineNumbers="true" %}

```bash
docker image load -i admin-web-app_2.1.2.tar
docker image load -i auth-server_2.1.2.tar
docker image load -i broker_2.1.2.tar
docker image load -i container-manager_2.1.2.tar
docker image load -i ingress-controller_2.1.2.tar
docker image load -i ingress_2.1.2.tar
docker image load -i nats_2.1.2.tar
docker image load -i postgresql_2.1.2.tar
docker image load -i protocol-mapper_2.1.2.tar
docker image load -i resource-status-tracking_2.1.2.tar
docker image load -i service-manager_2.1.2.tar
docker image load -i system-control-server_2.1.2.tar
docker image load -i topic-explorer_2.1.2.tar
docker image load -i workbench_2.1.2.tar
```

{% endcode %}

**Result:** All Docker images are now loaded and available for use.
{% endstep %}

{% step %}

### Run the Installer in Offline Mode

Run the installer script in offline mode using the `-o` flag:

{% code lineNumbers="true" %}

```bash
sudo ./connectware-online-installer.sh -o
```

{% endcode %}

The installer will prompt you for configuration options and then generate a `docker-compose.yml` file in the current directory.

{% hint style="info" %}
The `-o` flag tells the installer to run in offline mode, which skips Internet connectivity checks and uses local Docker images. The installer is still interactive and will prompt for:

* Installation directory (default: `/opt/connectware`)
* Ingress hostnames
* Whether to run as a systemd service

To run a non-interactive installation, use silent mode with additional flags:

```bash
sudo ./connectware-online-installer.sh -o -s -d /opt/connectware -H localhost -k <your-license-key>
```

{% endhint %}

{% hint style="warning" %}
The installer validates that all required Docker images are present before proceeding. If any images are missing, the installation will fail with an error listing the missing images.
{% endhint %}
{% endstep %}

{% step %}

### Configure the License

1. Open the generated `docker-compose.yml` file in a text editor:

{% code lineNumbers="true" %}

```bash
nano docker-compose.yml
```

{% endcode %}

2. Locate the `system-control-server` service section and find the `CYBUS_LICENSE_FILE` environment variable.
3. Open your license file (`.lic`) and copy its entire content.
4. Paste the license content as the value for `CYBUS_LICENSE_FILE`:

{% code lineNumbers="true" %}

```yaml
system-control-server:
  environment:
    CYBUS_LICENSE_FILE: |
      -----BEGIN LICENSE-----
      [Your license content here]
      -----END LICENSE-----
    CYBUS_REGISTRY_PASS: ${CYBUS_REGISTRY_PASS}
    NODE_ENV: production
  hostname: system-control-server
  image: registry.cybus.io/cybus/system-control-server:2.1.2
  # ... rest of the configuration
```

{% endcode %}

5. Save and close the file.

{% hint style="warning" %}
Ensure you paste the entire content of the `.lic` file, including the `-----BEGIN LICENSE-----` and `-----END LICENSE-----` markers.
{% endhint %}
{% endstep %}

{% step %}

### Start Connectware

Start Connectware using Docker Compose:

{% code lineNumbers="true" %}

```bash
docker compose up -d
```

{% endcode %}

Docker Compose will create and start all Connectware containers in the background.

**Result:** Connectware is now running on the recipient PC.
{% endstep %}
{% endstepper %}

## Accessing Connectware

After installation, you can access Connectware through your web browser:

1. Open your web browser.
2. Navigate to `https://localhost` or the hostname you configured.
3. Log in using the default credentials:
   * **Username:** `admin`
   * **Password:** `admin`

{% hint style="warning" %}
For security reasons, change the default admin password immediately after your first login. See [Default Admin User](/access/user-management/users/default-admin-user) for more information.
{% endhint %}

### Uploading the License File

If prompted to upload a license file in the [Admin UI](/access/admin-ui), follow these steps:

1. In the Admin UI, navigate to **System** > **System Status**.
2. Click the **License** tab.
3. Click **Upload License File**.
4. Select your `.lic` file and confirm the upload.

## License Validation in Offline Environments

When running Connectware in an offline environment, you may see a warning message in the [License View](/deployment/licensing#license-view) indicating that the system cannot connect to the license validation server at `https://graphql-server.cybus.io/graphql`.

{% hint style="info" %}
This warning can be safely ignored in offline installations. The license validation has already been performed locally using the license file embedded in the `docker-compose.yml` configuration. Your license will show as valid.
{% endhint %}

The license information is stored locally in the `docker-compose.yml` file and does not require Internet connectivity to function. However, you will not be able to use the **Refresh License** button in the Admin UI, as this feature requires Internet access.

## Troubleshooting

### Docker Images Not Loading

**Problem:** Error messages when loading Docker images.

**Solution:** Verify that:

* All `.tar` files were transferred completely and are not corrupted.
* You have sufficient disk space on the recipient PC.
* Docker is running with the correct permissions.

### License File Not Accepted

**Problem:** Connectware does not accept the license file.

**Solution:** Ensure that:

* You copied the entire content of the `.lic` file, including the `-----BEGIN LICENSE-----` and `-----END LICENSE-----` markers.
* The license file is valid and not expired.
* You pasted the content correctly in the `docker-compose.yml` file without extra spaces or line breaks.

### Containers Not Starting

**Problem:** Some or all containers fail to start.

**Solution:**

* Check container logs: `docker compose logs`
* Verify all images loaded successfully: `docker images | grep cybus`
* Ensure ports 80 and 443 are not in use by other applications.

### Cannot Access Connectware

**Problem:** Cannot access the Connectware Admin UI in the browser.

**Solution:**

* Verify all containers are running: `docker compose ps`
* Check if ports are accessible: `netstat -tuln | grep -E ':(80|443)'`
* Try accessing using the server's IP address instead of localhost.

## Next Steps

After successfully installing Connectware in offline mode, you can:

* [Connect your first machine](/guides/machine-connectivity)
* [Configure user management](/access/user-management)
* [Install additional services](/data-flows/services/managing/installing)


# Uninstalling Connectware

Uninstall Connectware on Docker or Kubernetes.

This page explains how to completely remove Connectware from your Docker or Kubernetes environment.

{% hint style="warning" %}
Make sure to back up any important data before proceeding with the uninstallation, as this process will permanently remove all Connectware-related data from your system.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes" %}

## Prerequisites

* [Helm version 4](https://helm.sh/docs/intro/quickstart/#install-helm) is installed on your system.
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed on your system.
* You know the name and namespace of your Connectware installation (see [Obtaining the Name, Namespace, and Version of your Connectware Installation](/cybus-helm-charts/cybus-helm-charts#obtaining-the-name-namespace-and-version-of-your-installation)).

## Uninstalling Connectware

To uninstall Connectware, use the helm uninstall command on your Connectware on Kubernetes installation:

{% code lineNumbers="true" %}

```bash
helm uninstall -n ${NAMESPACE} ${INSTALLATION_NAME}
```

{% endcode %}

Replace `${NAMESPACE}` with the namespace of your Connectware installation and `${INSTALLATION_NAME}` with the name of your Connectware installation.

## Cleaning up Leftover Resources

Some resources will intentionally not be removed, like some PersistentVolumeClaims, and potentially ConfigMaps and secrets manually created for mTLS.

If you want to completely clean up, for example for a fresh install, use this command to identify the resources:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} get all,cm,secret,pvc
```

{% endcode %}

Keep in mind that some resources are part of a standard Kubernetes namespace, for example `configmap/kube-root-ca.crt` or `service/kubernetes`. After identifying the resources for cleanup, use this command to remove them:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} delete <resource-1> <resource-2> <resource-n>
```

{% endcode %}

**Example**

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} delete persistentvolumeclaim/brokerdata-broker-0
persistentvolumeclaim/brokerdata-broker-1 configmap/cw-mtls-ca-cert
secret/cw-mtls-welder-robots
persistentvolumeclaim/postgresql-postgresql-0
persistentvolumeclaim/certs
```

{% endcode %}

{% hint style="info" %}
If you plan a fresh installation in the same location, make sure to remove `persistentvolumeclaim/postgresql-postgresql-0` and `persistentvolumeclaim/certs`.
{% endhint %}
{% endtab %}

{% tab title="Docker" %}

1. Switch to the root user and navigate to your installation directory:

{% code lineNumbers="true" %}

```bash
sudo -i
cd <installation-directory>
```

{% endcode %}

2. Stop and remove all Docker containers, networks, and volumes associated with Connectware:

{% code lineNumbers="true" %}

```bash
docker compose down -v
```

{% endcode %}

3. Navigate up one directory level and delete the installation directory:

{% code lineNumbers="true" %}

```bash
cd ..
rm -R <installation-directory>
```

{% endcode %}

If you have installed Connectware via systemd, proceed with the next steps.

4. systemd installations only: Disable the Connectware service.

{% code lineNumbers="true" %}

```bash
systemctl disable connectware
```

{% endcode %}

5. Remove the service file:

{% code lineNumbers="true" %}

```bash
rm /etc/systemd/system/connectware.service
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Upgrading Connectware

Upgrade Connectware on Docker or Kubernetes.

This chapter explains how to upgrade your existing Connectware installation to the latest version, covering both Docker and Kubernetes environments. You'll learn about version compatibility, backup procedures, and how to safely migrate your configuration and data.

{% hint style="warning" %}

## Downgrading to previous Connectware versions is not supported

{% endhint %}

Before you upgrade, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine whether your upgrade requires intermediate steps:

{% content-ref url="/pages/QJZdRVp6C6sJi2MtpM9q" %}
[Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths)
{% endcontent-ref %}

For detailed instructions on each upgrade step, refer to:

{% content-ref url="/pages/1PgJqI7on1UkEdefHsU6" %}
[Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes)
{% endcontent-ref %}

{% content-ref url="/pages/RmR9szIiZ3vxYeYzl2Hj" %}
[Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker)
{% endcontent-ref %}


# Connectware Upgrade Paths

Determine which upgrade path applies to your Connectware installation.

This page is the single source of truth for Connectware upgrade paths. Before you upgrade Connectware, use this page to determine whether you can upgrade directly to your target version or whether you must upgrade through one or more mandatory versions first.

{% hint style="warning" %}

## Downgrading to previous Connectware versions is not supported

{% endhint %}

## How Upgrade Paths Work

Most Connectware upgrades are regular upgrades: you follow [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker) or [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes) without additional steps.

However, some Connectware versions are mandatory versions in the upgrade path. A mandatory version changes Connectware in a way that later versions build on, for example, a new broker data format or a changed installation procedure. You cannot skip a mandatory version. If one or more mandatory versions lie between your current version and your target version, you must upgrade to each mandatory version in ascending order before you upgrade to your target version.

In addition, some versions come with upgrade steps that apply only to specific setups. These versions are not mandatory versions, so you do not need to upgrade to them separately. However, if the steps apply to your setup, you must complete them when you upgrade to that version or higher.

New installations do not require an upgrade path. If you install Connectware for the first time, install the latest version directly. For more information, see [Installing Connectware](/deployment/installing-connectware).

## Determining Your Upgrade Path

1. Identify your current Connectware version and your target version.
2. In the [version-specific upgrade steps table](#version-specific-upgrade-steps), note every version that lies between your current version and your target version and that is either mandatory for your platform or comes with steps that apply to your setup.
3. Upgrade to each noted mandatory version in ascending order. For each mandatory version, follow the linked upgrade guide.
4. Upgrade to your target version by following the regular upgrade guide for [Docker](/deployment/upgrading-connectware/on-docker) or [Kubernetes](/deployment/upgrading-connectware/on-kubernetes). Complete the setup-specific steps of the versions that your upgrade passes.

If no mandatory version lies between your current version and your target version, upgrade directly to your target version.

## Version-Specific Upgrade Steps

The following table lists all versions that come with upgrade steps. The **Mandatory** column tells you how to treat each version:

* **Yes:** The version is a stop on the upgrade path. You must upgrade to it before you continue to your target version.
* **For specific setups:** The version does not require a stop, but its steps are mandatory if they apply to your setup. Complete them when you upgrade to that version or higher.
* **No:** The steps are optional and never block an upgrade.

| Version | Mandatory                | What Changes                                                                                                                                                     | Upgrade Guides                                                                                                                                                 |
| ------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1.7.0   | Yes (Docker, Kubernetes) | The broker data format changes. Broker data volumes of earlier versions are not compatible with Connectware 1.7.0 and newer.                                     | [Docker](/deployment/upgrading-connectware/on-docker/to-1-7-0-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-1-7-0-on-kubernetes) |
| 2.0.0   | Yes (Docker, Kubernetes) | Major release with mandatory migration steps, including TLS changes and new network, hardware, and storage requirements.                                         | [Docker](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes) |
| 2.0.1   | Yes (Docker, Kubernetes) | The Data Explorer requires a new topic structure. If your services use `CYBUS_MQTT_ROOT`, you must run a migration script after the upgrade.                     | [Docker](/deployment/upgrading-connectware/on-docker/to-2-0-1-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-0-1-on-kubernetes) |
| 2.0.2   | Yes (Docker, Kubernetes) | HTTP connections receive new configuration options. You must disable and re-enable services that use HTTP connections after the upgrade.                         | [Docker](/deployment/upgrading-connectware/on-docker/to-2-0-2-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-0-2-on-kubernetes) |
| 2.0.5   | Yes (Docker, Kubernetes) | The CybusMQ data format changes. You must delete the broker data volumes before the upgrade, which removes all persisted broker data.                            | [Docker](/deployment/upgrading-connectware/on-docker/to-2-0-5-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-0-5-on-kubernetes) |
| 2.0.6   | Yes (Kubernetes)         | You must update the auth-server deployment to the 2.0.6 image before you run the Helm upgrade. This version fixes the Systemstate functionality on agents.       | [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-0-6-on-kubernetes)                                                                           |
| 2.1.0   | No                       | The `resourceStates` bucket is no longer used. Optional: Delete the bucket to free disk space.                                                                   | [Docker](/deployment/upgrading-connectware/on-docker/to-2-1-0-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-1-0-on-kubernetes) |
| 2.4.0   | For specific setups      | The OPC UA Server receives the `caFile` property. If you run OPC UA Server services with a custom PKI, add `caFile` to the affected service commissioning files. | [Docker](/deployment/upgrading-connectware/on-docker/to-2-4-0-on-docker), [Kubernetes](/deployment/upgrading-connectware/on-kubernetes/to-2-4-0-on-kubernetes) |

{% hint style="info" %}
Connectware 1.11.0 is no longer part of the upgrade path. If you are on Connectware 1.7.0 or higher, skip 1.11.0 and upgrade directly to 2.0.0.
{% endhint %}

## Upgrade Path Quick Reference

The following table shows the complete upgrade path for each starting version. After the last mandatory version, upgrade to your target version by following the regular upgrade guide for [Docker](/deployment/upgrading-connectware/on-docker) or [Kubernetes](/deployment/upgrading-connectware/on-kubernetes).

| Your Current Version          | Docker Upgrade Path                                    | Kubernetes Upgrade Path                                        |
| ----------------------------- | ------------------------------------------------------ | -------------------------------------------------------------- |
| 1.5.0 to 1.6.2                | 1.7.0 → 2.0.0 → 2.0.1 → 2.0.2 → 2.0.5 → target version | 1.7.0 → 2.0.0 → 2.0.1 → 2.0.2 → 2.0.5 → 2.0.6 → target version |
| 1.7.0 or higher (below 2.0.0) | 2.0.0 → 2.0.1 → 2.0.2 → 2.0.5 → target version         | 2.0.0 → 2.0.1 → 2.0.2 → 2.0.5 → 2.0.6 → target version         |
| 2.0.0                         | 2.0.1 → 2.0.2 → 2.0.5 → target version                 | 2.0.1 → 2.0.2 → 2.0.5 → 2.0.6 → target version                 |
| 2.0.1                         | 2.0.2 → 2.0.5 → target version                         | 2.0.2 → 2.0.5 → 2.0.6 → target version                         |
| 2.0.2 to 2.0.4                | 2.0.5 → target version                                 | 2.0.5 → 2.0.6 → target version                                 |
| 2.0.5                         | target version                                         | 2.0.6 → target version                                         |
| 2.0.6 or higher               | target version                                         | target version                                                 |

## Helm Chart Upgrades (Kubernetes)

Starting with chart version 3.0.0, the Cybus Helm charts are versioned independently of Connectware. Upgrading the Helm chart does not change your Connectware version and does not affect the upgrade paths on this page.

* For the chart upgrade procedure, see [Upgrading connectware and connectware-agent Helm Charts to 3.0.0](/deployment/upgrading-connectware/on-kubernetes/helm-charts-to-3-0-0).
* To check which chart versions work with which Connectware versions, see the [compatibility matrix](/cybus-helm-charts/compatibility-matrix).


# Backing Up the Connectware Database

Create and restore a logical backup of the Connectware PostgreSQL database on Kubernetes and Docker.

Connectware stores its configuration, users, and service state in a PostgreSQL database. This page shows how to create, verify, and restore a database backup on both Kubernetes and Docker.

Run this procedure before upgrading Connectware, before applying destructive maintenance, or on a regular schedule.

## Prerequisites

* Sufficient local disk space to hold the SQL dump. The database is usually small, but depending on how you use Connectware it can grow to multiple gigabytes.
* The PostgreSQL container is running and ready.

{% tabs %}
{% tab title="Kubernetes" %}

* `kubectl` access to the namespace in which Connectware is installed.
* The `postgresql-0` pod is `Running` and `Ready`.
  {% endtab %}

{% tab title="Docker" %}

* Shell access to the host running the Docker Composition.
* The PostgreSQL container is up. If your Docker Composition lives in `/opt/connectware`, the container is named `connectware-postgresql-1` by default. The container prefix matches the folder name of your Docker Composition, so if you installed elsewhere the name is `<folder-name>-postgresql-1`.
  {% endtab %}
  {% endtabs %}

## Creating a Backup

Dump the `cybus_connectware` database to a local file using the command for your platform.

{% hint style="warning" %}
Any changes made to Connectware after you create a backup are lost when you restore that backup. Create the backup as close as possible to the moment you need it — for example, immediately before an upgrade.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes" %}
Replace `${NAMESPACE}` with your Connectware namespace.

{% code lineNumbers="true" %}

```bash
kubectl exec -n ${NAMESPACE} postgresql-0 -- \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}
{% endtab %}

{% tab title="Docker" %}
If you are not sure which container hosts PostgreSQL, list the candidates:

{% code lineNumbers="true" %}

```bash
docker container ls -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=postgresql"
```

{% endcode %}

If more than one container is shown, identify the correct one by its prefix — it matches the folder name of your Docker Composition. For example, an install in `/opt/connectware` yields `connectware-postgresql-1`.

Replace `${CONTAINER_NAME}` with the name from the `NAMES` column.

{% code lineNumbers="true" %}

```bash
docker exec ${CONTAINER_NAME} \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}
{% endtab %}
{% endtabs %}

The resulting `connectware_database.sql` file contains a full logical backup with `DROP IF EXISTS` statements for a clean restore.

{% hint style="warning" %}
Store the backup in a secure location outside the host or cluster. The dump contains sensitive data such as user records and encrypted secrets.
{% endhint %}

### Verifying the Backup

Confirm that the dump file is non-empty and ends with `-- PostgreSQL database dump complete`. The verification command is the same on both platforms:

{% code lineNumbers="true" %}

```bash
tail -n 3 connectware_database.sql
```

{% endcode %}

If the file is empty or the closing line is missing, the backup did not complete. Investigate the PostgreSQL container logs and retry.

## Restoring a Backup

{% hint style="warning" %}
Restoring overwrites the current database contents. Only restore into an installation that is ready to accept a full replacement, for example a freshly provisioned PostgreSQL volume.
{% endhint %}

Pipe the dump back into `psql` inside the PostgreSQL container, then restart the Connectware workloads so all services pick up the restored state.

{% tabs %}
{% tab title="Kubernetes" %}

1. Wait for the `postgresql-0` pod to become ready.
2. Pipe the dump back into `psql`:

{% code lineNumbers="true" %}

```bash
cat connectware_database.sql | kubectl exec -n ${NAMESPACE} postgresql-0 \
  -i -- psql -U cybus-admin -d cybus_connectware
```

{% endcode %}

3. Restart the Connectware workloads so all services pick up the restored state:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} rollout restart deployment,statefulset \
  -l app.kubernetes.io/part-of=connectware
```

{% endcode %}
{% endtab %}

{% tab title="Docker" %}

1. Wait for the PostgreSQL container to be running.
2. Pipe the dump back into `psql`. Replace `${CONTAINER_NAME}` with the PostgreSQL container name.

{% code lineNumbers="true" %}

```bash
cat connectware_database.sql | docker exec -i ${CONTAINER_NAME} \
  psql -U cybus-admin -d cybus_connectware
```

{% endcode %}

3. Restart Connectware so all services pick up the restored state. Run this from your Connectware installation directory (by default `/opt/connectware`):

{% code lineNumbers="true" %}

```bash
docker compose down && docker compose up -d
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Verifying the Restore

Wait for all containers or pods to return to a running and ready state, then sign in to the [Admin UI](/access/admin-ui) and confirm that your services and users are present.

## Scheduling Regular Backups

The backup and verify commands run on demand. To automate backups, wrap the `pg_dump` invocation in a scheduler appropriate for your platform — for example a Kubernetes `CronJob` on Kubernetes, or `cron` / `systemd` timers on the Docker host — and ship the resulting SQL file to offsite storage.


# Upgrading Connectware (Kubernetes)

Upgrade Connectware on a Kubernetes cluster using Helm.

{% hint style="warning" %}

## Check your upgrade path

Some Connectware versions require intermediate upgrade steps. Before you upgrade, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine the upgrade path for your current version.
{% endhint %}

{% hint style="warning" %}

## Connectware currently does not support hitless upgrades

You may experience a service degradation during upgrading. Make sure to take an appropriate maintenance window into account when upgrading.
{% endhint %}

{% hint style="warning" %}

## Downgrading to previous Connectware versions is not supported

{% endhint %}

## Prerequisites

Before upgrading Connectware, make sure that you meet the following prerequisites:

* [Helm version 4](https://helm.sh/docs/intro/quickstart/#install-helm) is installed on your system.
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed on your system.
* The following information is available:
  * Local name of your Connectware Helm repository.
  * Name, namespace, and version of your Connectware installation.
  * Connectware version number that you want to upgrade to.
  * Helm values that are stored in the `values.yaml` file.

{% hint style="info" %}
Throughout this guide, command examples use variables like `${TARGET_VERSION}`, `${NAMESPACE}`, `${INSTALLATION_NAME}`, `${REPO_NAME}`, and `${CURRENT_VERSION}`. Replace these with your actual values.
{% endhint %}

### Reviewing the Connectware Changelog

Before you upgrade to a new Connectware version, we recommend that you read the changelog to find out about new features, bug fixes, and changes of the Connectware version that you want to upgrade to.

* To open the Connectware changelog, click [here](/changelog).

### Reviewing the Readme File

Before you upgrade to a new Connectware version, read the readme file of the Connectware version that you want to upgrade to for additional upgrade instructions.

* To open the readme file, enter the following command:

{% code lineNumbers="true" %}

```bash
helm show readme oci://repo.cybus.io/charts/connectware --version ${TARGET_VERSION}
```

{% endcode %}

### Comparing Helm Configurations Between Connectware Versions

With a new Connectware version, there might be changes to the default Helm configuration values. We recommend that you compare the default Helms values of your current Connectware version with the default Helm values of your target Connectware version.

* To display the new default values, enter the following command:

{% code lineNumbers="true" %}

```bash
helm show values oci://repo.cybus.io/charts/connectware --version ${TARGET_VERSION}
```

{% endcode %}

* To display which Connectware default values have changed between your current version and your target version, enter the following command:

{% code lineNumbers="true" %}

```bash
diff <(helm show values oci://repo.cybus.io/charts/connectware --version ${CURRENT_VERSION}) <(helm show values oci://repo.cybus.io/charts/connectware --version ${TARGET_VERSION})
```

{% endcode %}

**Example**

{% code lineNumbers="true" %}

```bash
diff <(helm show values oci://repo.cybus.io/charts/connectware --version 3.0.0) <(helm show values oci://repo.cybus.io/charts/connectware --version 3.0.1)
83c83
<     tag: 3.0.0
---
>     tag: 3.0.1
```

{% endcode %}

In this example, only the image version has changed. However, if any of the Helm value changes are relevant to your setup, make the appropriate changes.

* To override default Helm values, add the custom Helm value to your local values.yaml file.

### Adjusting Helm Values

When you have reviewed the necessary information, adjust your configuration in your values.yaml file. Not every upgrade requires adjustments.

If you specified which image tag of Connectware to use by setting the Helm value `global.image.tag` you will need to update this to `${TARGET_VERSION}`.

### Verifying Your Backups

Make sure that you store backups of your setup. This allows you to restore a previous state if necessary.

Your backups must consist of the following files:

* All Kubernetes PersistentVolumes that Connectware uses
* Your Connectware database
* Your values.yaml file
* All service commissioning files

Depending on your local infrastructure, it may be necessary to back up additional files.

## Starting the Connectware Upgrade

Once you have all the information that you need to upgrade your Connectware, you can start the upgrade process. The following sections will guide you through monitoring the upgrade, as well as what to do on failed upgrades.

* To upgrade Connectware, enter the following command:

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware --version ${TARGET_VERSION} -f <values.yaml>
```

{% endcode %}

**Optional:** You can use the `--atomic --timeout 10m` command line switch, which will cause Helm to wait for the result of your upgrade and perform a rollback when it fails. We recommend setting the timeout value to at least 10 minutes, but because the time it takes to complete an upgrade strongly depends on your infrastructure and configuration you might have to increase it further.

**Result:** The newly generated workload definitions are applied to your Kubernetes cluster and your Connectware pods are replaced.

## Verifying the Connectware Upgrade

You can monitor the Connectware upgrade progress to verify that everything runs smoothly, to know when the installation is successful, or to investigate potential issues.

### Monitoring the Connectware Upgrade

The Connectware upgrade can take a few minutes. To monitor the upgrade process, do one of the following:

* To monitor the current status of the upgrade process, enter the following command:

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

* To monitor the continuous progress of the upgrade process, enter the following command:

{% code lineNumbers="true" %}

```bash
while [ true ]; do clear; kubectl get pods -n ${NAMESPACE}; sleep 5; done
```

{% endcode %}

* To stop monitoring the continuous progress of the upgrade process, press <kbd>Ctrl</kbd>+<kbd>C</kbd>.

### Pod Stages During the Connectware Upgrade

During the Connectware upgrade, the pods go through the following stages:

* Terminating
* Pending
* PodInitializing
* ContainerCreating
* Init:x/x
* Running

When pods reach the STATUS Running, they go through their individual startup before reporting as Ready. To be fully functional, all pods must reach the STATUS Running and report all their containers as ready. This is indicated by them showing the same number on both sides of the / in the column READY.

**Example**

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

| NAME                                   | READY | STATUS  | RESTARTS | AGE   |
| -------------------------------------- | ----- | ------- | -------- | ----- |
| admin-web-app-7cd8ccfbc5-bvnzx         | 1/1   | Running | 0        | 3h44m |
| auth-server-5b8c899958-f9nl4           | 1/1   | Running | 0        | 3m3s  |
| broker-0                               | 1/1   | Running | 0        | 3h44m |
| broker-1                               | 1/1   | Running | 0        | 2m1s  |
| connectware-ingress-7784b5f4c5-g8krn   | 1/1   | Running | 0        | 21s   |
| container-manager-558d9c4cbf-m82bz     | 1/1   | Running | 0        | 3h44m |
| doc-server-55c77d4d4c-nwq5f            | 1/1   | Running | 0        | 3h44m |
| ingress-controller-6bcf66495c-l5dpk    | 1/1   | Running | 0        | 18s   |
| postgresql-0                           | 1/1   | Running | 0        | 3h44m |
| protocol-mapper-67cfc6c848-qqtx9       | 1/1   | Running | 0        | 3h44m |
| service-manager-f68ccb767-cftps        | 1/1   | Running | 0        | 3h44m |
| system-control-server-58f47c69bf-plzt5 | 1/1   | Running | 0        | 3h44m |
| workbench-5c69654659-qwhgc             | 1/1   | Running | 0        | 15s   |

At this point Connectware is upgraded and started. You can now make additional configurations or verify the upgrade status in the Admin UI.

### Troubleshooting Pod Stages

If a pod is in another state than expected or if it is stuck at a certain stage for more than three minutes, there might be an issue.

* To investigate the pod status, enter the following command:

{% code lineNumbers="true" %}

```bash
kubectl describe pod <podname> -n ${NAMESPACE}
```

{% endcode %}

For help on solving issues, see [Troubleshooting Connectware on Kubernetes](/cybus-helm-charts/troubleshooting-on-kubernetes).

### Rolling Back the Helm Upgrade

If the Helm upgrade fails, and it is not possible to immediately identify and fix the problem, you can roll back Helm upgrades using the `helm rollback` command.

To perform the rollback you need to know the current REVISION of your installation. Use the command `helm list -n ${NAMESPACE}`, and note down the value for REVISION displayed in the row of your Connectware installation. In the next section you will use this value and decrement one to restore the previous REVISION. For example, if the REVISION displayed is 8, you will use 7 in the `helm rollback` command:

{% code lineNumbers="true" %}

```bash
helm rollback --wait -n ${NAMESPACE} ${INSTALLATION_NAME} <REVISION - 1>
```

{% endcode %}

{% hint style="info" %}
This will roll back your Helm upgrade and start your previous version of Connectware. It is possible that you will need to perform a restore of Connectware, if there were modifications made by the attempted upgrade.
{% endhint %}


# Upgrading Connectware Helm Charts to 3.0.0

How to upgrade your connectware and connectware-agent Helm charts from version 2.1.0 or later to version 3.0.0.

{% hint style="info" %}
Chart 3.0.0 marks the first release of the Cybus Helm charts as a standalone update, separate from a Connectware release. The 3.0.0 Helm chart upgrade only affects the chart; your Connectware version is unchanged.
{% endhint %}

Chart versioning and Connectware versioning are now decoupled. This means that improvements to the Cybus Helm chart can be released independently of Connectware releases. The [compatibility matrix](/cybus-helm-charts/compatibility-matrix) shows which chart versions work with which Connectware versions. This makes it easy to plan upgrades for each type on its own schedule.

For a full list of new features and improvements in this release, see the [changelog](/changelog).

## Switching to an OCI Registry

Starting with chart 3.0.0, charts are distributed via an [OCI registry](https://helm.sh/docs/topics/registries/) instead of a [Helm chart repository](https://helm.sh/docs/topics/chart_repository/).

Each chart version is now pulled directly by its exact version tag from an OCI registry, similar to how container images are handled. You do not have to manage a registered repo or run `helm repo update` before installing a new version anymore.

Especially for offline installations, this is a significant simplification: charts and container images can now be mirrored to the same registry, removing the need to host the chart separately. Use `oci://repo.cybus.io` as the registry. Make sure any proxies or network access rules allow traffic to that address.

Helm version 4 is required.

## Before You Begin

Chart 3.0.0 restructures the `values.yaml` file for both the `connectware` chart and the `connectware-agent` chart. Many keys are renamed, several components have been moved from `global.*` into top-level blocks, and resource defaults have been reduced for most components.

This guide is split into two parts so that you can follow only the parts that apply to your installation:

* **Part A**: changes to the `connectware` chart `values.yaml` file.
* **Part B**: changes to the `connectware-agent` chart `values.yaml` file. Applies whether the agent chart runs standalone or as a subchart of the `connectware` chart.

Make sure to read the entire guide before you start. Some changes, such as security context overrides and protocol-mapper agent migration, require careful hand-merging to avoid stripping defaults or orphaning agents.

### Prerequisites

* A working installation of one or both of the following:
  * `connectware` Helm chart versions 2.1.0 to 2.4.0
  * `connectware-agent` Helm chart versions 2.1.0 to 2.4.0
* Chart 2.1.0 is the minimum supported starting point. If you are on an older version, [upgrade to 2.1.0](/deployment/upgrading-connectware/on-kubernetes/to-2-1-0-on-kubernetes) first.
* Access to your current `values.yaml` file or files.
* Backups of your [Connectware database](/deployment/upgrading-connectware/backing-up-the-connectware-database), Persistent Volumes, `values.yaml` file or files, and all service commissioning files.
* [Helm version 4](https://helm.sh/docs/intro/quickstart/#install-helm) is installed on your system.
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed on your system.
* You know the name and namespace of your installations. See [Obtaining the Name, Namespace, and Version of Your Installation](/cybus-helm-charts/working-with-cybus-helm-charts#obtaining-the-name-namespace-and-version-of-your-installation).
* Access to OCI registry `oci://repo.cybus.io`, or the Helm charts [copied locally](/cybus-helm-charts/working-with-cybus-helm-charts/registries-and-pull-secrets#using-a-custom-registry).
* Kubernetes version >= 1.25: These new chart versions will not deploy on Kubernetes lower than 1.25.

{% hint style="info" %}

## A note on quoting strings

YAML interprets certain unquoted values as numbers, booleans, or dates. To avoid accidental type coercion, wrap string values in single or double quotes whenever they contain digits, punctuation, or look like a boolean. The examples in this guide follow this convention.
{% endhint %}

## AI-Assisted Migration

You can migrate your `values.yaml` file using AI or manually. If you prefer the manual approach, skip this section and follow [Part A](#part-a-connectware-chart-migration) and [Part B](#part-b-connectware-agent-chart-migration) instead. If you use the AI approach, it handles the key renames and structural moves in your `values.yaml` file. However, you still need to perform additional manual actions, as described below.

<details>

<summary><strong>1. Migrating the values.yaml File</strong></summary>

Download the skill below and run it with a [tool supporting the Agent Skills format](https://agentskills.io/clients) against your existing `values.yaml` file to automate the key renames and moves. The better the model's reasoning, the more reliable the output.

{% hint style="warning" %}
Always review the output before applying it.
{% endhint %}

{% file src="/files/L4Ek8LBTw3K0FSVQqdYp" %}

The skill covers `values.yaml` key changes; work through the items in the next step for everything else.

</details>

<details>

<summary><strong>2. Before Running helm upgrade</strong></summary>

* **Recreate the image pull secret if you used a different value for `global.registryUser` than `license`.** Create a pull secret manually and reference it through `global.image.pullSecrets`, or pods will fail with `ImagePullBackOff`. See [A1. License Values Changes](#a1.-license-values-changes).
* **Verify customized security contexts after migration.** Overrides replace chart defaults and do not merge — the migrated output may be missing defaults. See [A3. Security Contexts](#a3.-security-contexts) and [B3. Security Contexts](#b3.-security-contexts).
* **Decide whether to keep the previous resource defaults.** If your `values.yaml` does not set resource requests and limits, the new lower defaults apply after the upgrade. See [A8. Resources Moved to Per-Component](#a8.-resources-moved-to-per-component) and [B7. Resource Defaults](#b7.-resource-defaults).
* **Set `authServer.replicas: 1` if you want the old single-replica behavior.** The default changed from `1` to `2`. See [A10. Auth-Server Default Replicas](#a10.-auth-server-default-replicas).
* **Detect cluster resource renames for `connectware-agent` installations with affected names.** If your release is named `connectware`, or combined release-plus-agent names exceed 52 characters, run `helm diff upgrade` first. See [B8. Cluster Resource Name Changes](#b8.-cluster-resource-name-changes).
* **Re-add TCP ports for `Cybus::IngressRoute` resources.** The ingress LoadBalancer Service no longer exposes ports `40000` to `40009` by default. If you have `Cybus::IngressRoute` resources of type `tcp`, add their `connectwarePort` to `connectwareIngress.service.ports` or they become unreachable. See [A13. Ingress Service Ports for TCP IngressRoutes](#a13.-ingress-service-ports-for-tcp-ingressroutes).
* **Review the Container Manager RBAC change if your cluster restricts RBAC manifests.** The chart replaces the `pod-manager` Role with a `connectware-${INSTALLATION_NAME}-pod-reader` Role that only grants `get`, `list`, and `watch` on `pods` and `pods/log`, and binds a dedicated ServiceAccount instead of the namespace `default` ServiceAccount. If your cluster requires approval for changes to Roles, RoleBindings, or ServiceAccounts, share the diff with the team that approves RBAC manifests before running `helm upgrade`.

</details>

<details>

<summary><strong>3. Running helm upgrade</strong></summary>

Follow the [Upgrade Procedure](#upgrade-procedure) to run `helm upgrade`. Then continue to the next step for post-upgrade actions.

</details>

<details>

<summary><strong>4. After Running helm upgrade</strong></summary>

None of these items require changes to `values.yaml`.

* **Update external selectors that reference the `app` label.** The label changed from `app=<component>` to `app.kubernetes.io/name=<component>`. See [A12. Workload Label Rename](#a12.-workload-label-rename).
* **Update references to the renamed ingress Deployment.** The Deployment `connectware` is now `connectware-ingress`. See [A7. Components Moved Out of global](#a7.-components-moved-out-of-global).
* **Re-register migrated protocol-mapper agents.** Connectware treats agents migrated from the `connectware` chart as new entities. See [Post-Upgrade Actions](#post-upgrade-actions).
* **Review resource usage and set production limits.** See [Post-Upgrade Actions](#post-upgrade-actions).

</details>

## Upgrade Procedure

The procedure is divided into the following parts:

* **Part A — Connectware Chart Migration**: Update the `connectware` chart `values.yaml` file to match the new chart schema.
* **Part B — Connectware-Agent Chart Migration**: Update the `connectware-agent` chart `values.yaml` file. Applies to both standalone and subchart deployments.
* **Running the Upgrade**: Apply the updated values using `helm upgrade`.
* **Post-Upgrade Actions**: Re-register protocol-mapper agents and review resource requests.

{% hint style="warning" %}
As part of this upgrade, you will need to fully stop Connectware and any standalone `connectware-agent` releases, since some of the changes cannot be done in a rolling restart.
{% endhint %}

<details>

<summary><strong>Overview of Mandatory Migration Steps</strong></summary>

`connectware` chart steps:

1. [**License Keys**](#a1.-license-values-changes)
2. [**Image Version**](#a2.-image-version)
3. [**Security Contexts**](#a3.-security-contexts)
4. [**Storage to Persistence**](#a4.-storage-to-persistence)
5. [**User Management to Authentication**](#a5.-user-management-to-authentication)
6. [**Other Global Value Changes**](#a6.-other-global-value-changes)
7. [**Components Moved Out of global**](#a7.-components-moved-out-of-global)
8. [**Resources Moved to Per-Component**](#a8.-resources-moved-to-per-component)
9. [**CybusMQ Broker Value Changes**](#a9.-cybusmq-broker-value-changes)
10. [**Auth-Server Default Replicas**](#a10.-auth-server-default-replicas)
11. [**Reserved MFA Environment Variables**](#a11.-reserved-mfa-environment-variables)
12. [**Workload Label Rename**](#a12.-workload-label-rename)
13. [**Ingress Service Ports for TCP IngressRoutes**](#a13.-ingress-service-ports-for-tcp-ingressroutes)
14. [**NATS Metrics Path Change**](#a14.-nats-metrics-path-change)

`connectware-agent` chart steps:

1. [**Protocol-Mapper Agents Structure**](#b1.-protocol-mapper-agents-structure)
2. [**Image Version**](#b2.-image-version)
3. [**Security Contexts**](#b3.-security-contexts)
4. [**Storage to Persistence**](#b4.-storage-to-persistence)
5. [**TLS CA Configuration Renames**](#b5.-tls-ca-configuration-renames)
6. [**Reserved Environment Variables**](#b6.-reserved-environment-variables)
7. [**Resource Defaults**](#b7.-resource-defaults)
8. [**Cluster Resource Name Changes**](#b8.-cluster-resource-name-changes)

</details>

## Part A: Connectware Chart Migration

Apply the following changes to your `connectware` chart `values.yaml` file. If you only want to update the `connectware-agent` chart standalone, skip to [Part B](#part-b-connectware-agent-chart-migration).

### A1. License Values Changes

#### Why the Change?

Normalizing value names and capitalization to avoid future confusion.

#### What You Need to Do

<details>

<summary><strong>Updating the License Values</strong></summary>

* Delete `global.registryUser`. If you authenticated against the image registry with a custom user, create a pull secret manually and reference it via `global.image.pullSecrets`. See [Configuring Registries and Pull Secrets](/cybus-helm-charts/working-with-cybus-helm-charts/registries-and-pull-secrets).
* Rename `global.licensekey` to `global.licenseKey` (capital K).
* If `global.licenseFile` is set to `online`, change it to `""` (empty string) or remove it. Real license file bodies used for offline installations remain unchanged. If you do not have this key in your `values.yaml`, you do not need to add it.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  registryUser: license
  licensekey: xxxxxxxxxx
  licenseFile: online
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  licenseKey: 'xxxxxxxxxx'
  licenseFile: ''
```

{% endcode %}

</details>

### A2. Image Version

#### Why the Change?

The value controls the container image tag used, not necessarily a version. It is now aligned with the Kubernetes convention.

#### What You Need to Do

<details>

<summary><strong>Renaming the Image Key</strong></summary>

* Rename `global.image.version` to `global.image.tag`.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  image:
    version: 2.3.0
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  image:
    tag: '2.3.0'
```

{% endcode %}

</details>

### A3. Security Contexts

#### Why the Change?

Security context values now use `Override` suffixes to signal that they replace the chart defaults rather than merge with them.

We renamed `securityContext` to `podSecurityContextOverride`, to be consistent and explicit in the naming.

{% hint style="warning" %}

## Override values replace defaults, they do not merge

A partial override strips any default it does not redeclare. If you customized a security context, your migrated output must include both the new 3.0.0 defaults and your customizations, merged by hand.
{% endhint %}

The same rename applies to per-agent security contexts in the `connectware-agent` chart. See [B3. Security Contexts](#b3.-security-contexts).

#### Key Changes

<details>

<summary><strong>1. Pod and Container Security Context Renames</strong></summary>

Both keys are available as a global default under `global.*` and as a per-component override. The per-component value takes precedence over the global one.

* `securityContext` → `podSecurityContextOverride`
* `containerSecurityContext` → `containerSecurityContextOverride`

This applies to `global.*` and every component.

</details>

<details>

<summary><strong>2. Chart 3.0.0 Defaults to Merge Into Your Override</strong></summary>

For your reference, these are the default security contexts our Helm charts apply. If you have customized a security context, merge your customization with these defaults and set them in the respective `podSecurityContextOverride` or `containerSecurityContextOverride`. You will find examples in the next steps. If you never customized a security context, delete any security context block from your `values.yaml` file and the defaults will apply.

**Default pod security context**

{% code lineNumbers="true" %}

```yaml
runAsNonRoot: true
seccompProfile:
  type: RuntimeDefault
fsGroup: 1000
```

{% endcode %}

**Default container security context**

{% code lineNumbers="true" %}

```yaml
allowPrivilegeEscalation: false
capabilities:
  drop:
    - ALL
```

{% endcode %}

</details>

<details>

<summary><strong>3. Merge Example (Pod Security Context)</strong></summary>

This example adds `runAsUser: 1000` on top of the defaults.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  securityContext:
    runAsUser: 1000
```

{% endcode %}

**After (defaults merged with your value)**

{% code lineNumbers="true" %}

```yaml
global:
  podSecurityContextOverride:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
    fsGroup: 1000
    runAsUser: 1000
```

{% endcode %}

</details>

<details>

<summary><strong>4. Merge Example (Container Security Context)</strong></summary>

This example sets the container to run as a specific user ID (`runAsUser: 1000`) on top of the defaults.

**Before**

{% code lineNumbers="true" %}

```yaml
broker:
  containerSecurityContext:
    runAsUser: 1000
```

{% endcode %}

**After (defaults merged with your value)**

{% code lineNumbers="true" %}

```yaml
broker:
  containerSecurityContextOverride:
    allowPrivilegeEscalation: false
    capabilities:
      drop:
        - ALL
    runAsUser: 1000
```

{% endcode %}

</details>

<details>

<summary><strong>5. Dropping Exact-Default Blocks</strong></summary>

The former defaults and the 3.0.0 defaults listed above are identical. If your source security context block matches them exactly, drop the block entirely instead of emitting an override. The 3.0.0 defaults already cover it.

</details>

### A4. Storage to Persistence

#### Why the Change?

The `storage` key was renamed to `persistence` across the chart, and several storage-related keys were adjusted to use uppercase initialisms. This aligns the naming with common Kubernetes conventions and keeps it consistent across the chart.

The same rename applies to per-agent storage in the `connectware-agent` chart. See [B4. Storage to Persistence](#b4.-storage-to-persistence).

#### What You Need to Do

<details>

<summary><strong>Renaming Storage Keys</strong></summary>

| Old                                                                              | New                                        |
| -------------------------------------------------------------------------------- | ------------------------------------------ |
| `global.storage`                                                                 | `global.persistence`                       |
| `<component>.storage` (broker, nats, postgresql, systemControlServer, workbench) | `<component>.persistence`                  |
| `postgresql.persistence.preprovisionedNfs`                                       | `postgresql.persistence.preprovisionedNFS` |

Inner keys (`size`, `storageClassName`, `data`, `log`, `accessMode`) are unchanged.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  storage:
    storageClassName: 'standard'
    certs:
      storageClassName: 'standard'
  postgresql:
    storage:
      size: 50Gi
      storageClassName: 'ssd'
      preprovisionedNfs:
        enabled: false
        server: ''
        path: /nfs_data/postgresql
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  persistence:
    storageClassName: 'standard'
    certs:
      storageClassName: 'standard'
postgresql:
  persistence:
    size: 50Gi
    storageClassName: 'ssd'
    preprovisionedNFS:
      enabled: false
      server: ''
      path: /nfs_data/postgresql
```

{% endcode %}

</details>

### A5. User Management to Authentication

#### Why the Change?

The user management section is not different from the authentication section, so to simplify, they have been merged. The admin user password format was also simplified from base64 to plain text, which follows a common theme: literal Helm values take plain-text values. Base64 encoding is not a security measure to keep values secret. For more secure operations, use Helm values which take references to existing Kubernetes Secrets, in this case `global.authentication.adminUser.existingSecret`. The initial admin password has no effect during an upgrade, since it will never override an existing admin user.

The `mTLS` configuration block was removed a few versions back, since mTLS is now always enabled. If you still have it in your `values.yaml`, now is a good chance to remove it.

#### What You Need to Do

<details>

<summary><strong>Migrating Authentication Values</strong></summary>

* Rename `global.userManagement.adminUser` to `global.authentication.adminUser`.
* Change `adminUser.enabled` from the string `"true"` or `"false"` to the boolean `true` or `false`.
* Change `adminUser.initialPassword` from base64 or the sentinel `"automatic"` to plain text. Decode any base64 value. Replace `"automatic"` with an empty string `""` to auto-generate a password.
* Rename `global.userManagement.passwordPolicyRules` to `global.authentication.passwordPolicyRules`.
* Delete `global.authentication.mTLS` if present. mTLS has been auto-enabled for several Connectware versions and the value no longer has any effect.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  userManagement:
    adminUser:
      enabled: 'true'
      initialPassword: Y2hhbmdlbWU=
    passwordPolicyRules: 'default'
  authentication:
    mTLS:
      enabled: false
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    adminUser:
      enabled: true
      initialPassword: 'changeme'
    passwordPolicyRules: 'default'
```

{% endcode %}

</details>

### A6. Other Global Value Changes

#### Why the Change?

Some global values are no longer needed, the MetalLB address pool configuration moved to the ingress service annotations, and the ingress DNS names key was renamed to use the uppercase initialism.

#### What You Need to Do

<details>

<summary><strong>Removing, Replacing, and Renaming Global Values</strong></summary>

* Delete `global.setImmutableLabels`. Labels on immutable objects are now always set.
* If you use MetalLB, replace `global.loadBalancer.metalLB.addressPoolName` with an annotation on `connectwareIngress.service.annotations` as explained in the [MetalLB documentation](https://metallb.io/usage/#requesting-specific-ips). You can then remove the `global.loadBalancer` section.
* Rename `global.ingressDnsNames` to `global.ingressDNSNames` (uppercase DNS).

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  setImmutableLabels: true
  loadBalancer:
    metalLB:
      addressPoolName: my-pool
  ingressDnsNames:
    - connectware.example.com
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  ingressDNSNames:
    - connectware.example.com
connectwareIngress:
  service:
    annotations:
      metallb.universe.tf/address-pool: my-pool
```

{% endcode %}

</details>

### A7. Components Moved Out of global

#### Why the Change?

Component configuration blocks were lifted out of `global.*` to their own top-level keys to follow Helm best practices and avoid confusion with subcharts being introduced into the `connectware` chart.

The "connectware" Deployment used the `global.ingress` section. The name of the Deployment and the name of the section were confusing, so they were both renamed. The Deployment is now named "connectware-ingress" and uses the matching Helm value section `connectwareIngress`. This conveys more clearly that this is an ingress proxy for Connectware, and has nothing to do with a Kubernetes Ingress. Instead it is exposed using a `LoadBalancer` Service by default.

#### What You Need to Do

<details>

<summary><strong>Moving Component Blocks to the Top Level</strong></summary>

Move every `global.<component>` block to the top-level `<component>` key. Use the mapping below.

| Old                             | New                      |
| ------------------------------- | ------------------------ |
| `global.adminWebApp`            | `adminWebApp`            |
| `global.authServer`             | `authServer`             |
| `global.broker`                 | `broker`                 |
| `global.containerManager`       | `containerManager`       |
| `global.ingress`                | `connectwareIngress`     |
| `global.ingressController`      | `ingressController`      |
| `global.nats`                   | `nats`                   |
| `global.postgresql`             | `postgresql`             |
| `global.protocolMapper`         | `protocolMapper`         |
| `global.resourceStatusTracking` | `resourceStatusTracking` |
| `global.serviceManager`         | `serviceManager`         |
| `global.systemControlServer`    | `systemControlServer`    |
| `global.topicExplorer`          | `topicExplorer`          |
| `global.workbench`              | `workbench`              |

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  ingress:
    service:
      annotations:
        service.beta.kubernetes.io/load-balancer-scheme: 'internet-facing'
  broker:
    replicaCount: 3
  postgresql:
    storage:
      storageClassName: block-storage
  nats:
    replicas: 3
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
connectwareIngress:
  service:
    annotations:
      service.beta.kubernetes.io/load-balancer-scheme: 'internet-facing'
broker:
  replicas: 3
postgresql:
  persistence:
    storageClassName: block-storage
nats:
  replicas: 3
```

{% endcode %}

</details>

### A8. Resources Moved to Per-Component

#### Why the Change?

The `global.podResources.*` block has been removed. Resource limits and requests are now configured directly on each component. Default requests have also been reduced for most components.

{% hint style="warning" %}
If your current `values.yaml` file does not set `global.podResources`, your workloads will receive the new, lower default requests after the upgrade. Set the old values explicitly if your workload requires them.
{% endhint %}

#### What You Need to Do

<details>

<summary><strong>1. Moving Resources to Each Component</strong></summary>

Drop `global.podResources.*` and put `resources:` directly on each component. Watch the alias keys: `connectware`, `controlServer`, `database`, and `distributedProtocolMapper` do not match their target component names.

| Old Path                                        | New Path                                                                                                                                          |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `global.podResources.<component>`               | `<component>.resources`                                                                                                                           |
| `global.podResources.connectware`               | `connectwareIngress.resources`                                                                                                                    |
| `global.podResources.controlServer`             | `systemControlServer.resources`                                                                                                                   |
| `global.podResources.database`                  | `postgresql.resources`                                                                                                                            |
| `global.podResources.distributedProtocolMapper` | `connectwareAgent.protocolMapperAgentDefaults.resources`. See also [B1. Protocol-Mapper Agents Structure](#b1.-protocol-mapper-agents-structure). |

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  podResources:
    broker:
      limits:
        cpu: 2000m
        memory: 3000Mi
      requests:
        cpu: 2000m
        memory: 3000Mi
    connectware:
      limits:
        cpu: 1500m
        memory: 750Mi
      requests:
        cpu: 1000m
        memory: 500Mi
    database:
      limits:
        cpu: 2000m
        memory: 2000Mi
      requests:
        cpu: 2000m
        memory: 2000Mi
    distributedProtocolMapper:
      requests:
        cpu: 2000m
        memory: 2000Mi
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
broker:
  resources:
    limits:
      cpu: 2000m
      memory: 3000Mi
    requests:
      cpu: 2000m
      memory: 3000Mi
connectwareIngress:
  resources:
    limits:
      cpu: 1500m
      memory: 750Mi
    requests:
      cpu: 1000m
      memory: 500Mi
postgresql:
  resources:
    limits:
      cpu: 2000m
      memory: 2000Mi
    requests:
      cpu: 2000m
      memory: 2000Mi
connectwareAgent:
  protocolMapperAgentDefaults:
    resources:
      requests:
        cpu: 2000m
        memory: 2000Mi
```

{% endcode %}

</details>

<details>

<summary><strong>2. Default Request Changes</strong></summary>

The table below lists the default CPU and memory requests for each component in chart 2.4.0 and chart 3.0.0.

Most components have lower defaults in chart 3.0.0. However, lower defaults do not mean Connectware requires fewer resources. The chart reduces defaults to make it easier to get started on smaller clusters. Use actual resource consumption data to set values that match your workload before going to production.

Chart 3.0.0 also removes default limits. Running without limits is not recommended, since it allows workloads to starve others on the same cluster. See the [Kubernetes documentation on resource requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for guidance on setting appropriate values. If you are unsure where to start, see [Right-Sizing Kubernetes Resources for Connectware](/guides/operations/right-sizing-kubernetes-resources).

| Component                | Old (cpu/mem)  | New (cpu/mem)  |
| ------------------------ | -------------- | -------------- |
| `adminWebApp`            | 100m / 50Mi    | 50m / 50Mi     |
| `authServer`             | 1500m / 1000Mi | 1000m / 500Mi  |
| `broker`                 | 2000m / 3000Mi | 600m / 1000Mi  |
| `connectwareIngress`     | 1000m / 500Mi  | 400m / 250Mi   |
| `containerManager`       | 250m / 200Mi   | 150m / 200Mi   |
| `ingressController`      | 100m / 100Mi   | 150m / 100Mi   |
| `nats`                   | 2000m / 2000Mi | 500m / 750Mi   |
| `postgresql`             | 2000m / 2000Mi | 500m / 750Mi   |
| `protocolMapper`         | 2000m / 2000Mi | 1000m / 1000Mi |
| `resourceStatusTracking` | 1000m / 1000Mi | 250m / 500Mi   |
| `serviceManager`         | 1000m / 1000Mi | 1000m / 500Mi  |
| `systemControlServer`    | 200m / 200Mi   | 300m / 200Mi   |
| `topicExplorer`          | 200m / 750Mi   | 200m / 500Mi   |
| `workbench`              | 200m / 400Mi   | 150m / 200Mi   |

</details>

### A9. CybusMQ Broker Value Changes

#### Why the Change?

Beyond the storage rename covered in [A4](#a4.-storage-to-persistence) and the top-level move covered in [A7](#a7.-components-moved-out-of-global), several CybusMQ broker keys were renamed or retyped.

#### What You Need to Do

<details>

<summary><strong>Updating CybusMQ Broker Values</strong></summary>

* Rename `replicaCount` to `replicas`.
* Rename `messageQueueSize` to `onlineMessageQueueSize`.
* Convert `allowRegisterDuringClusterFormation`, `allowPublishDuringClusterFormation`, `allowSubscribeDuringClusterFormation`, and `allowUnsubscribeDuringClusterFormation` from the strings `"on"` or `"off"` to the booleans `true` or `false`.
* Replace the `clusterSecret` placeholder `<defineAnySecret>` with a real value or an empty string `""` to auto-generate. This upgrade requires completely stopping your cluster, which means it is possible to change the secret, as well as the approach to configuring it.

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  broker:
    replicaCount: 3
    clusterSecret: <defineAnySecret>
    messageQueueSize: 10000
    allowRegisterDuringClusterFormation: 'on'
    allowPublishDuringClusterFormation: 'on'
    allowSubscribeDuringClusterFormation: 'on'
    allowUnsubscribeDuringClusterFormation: 'off'
    storage:
      size: 40Gi
      storageClassName: 'ssd'
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
broker:
  replicas: 3
  clusterSecret: ''
  onlineMessageQueueSize: 10000
  allowRegisterDuringClusterFormation: true
  allowPublishDuringClusterFormation: true
  allowSubscribeDuringClusterFormation: true
  allowUnsubscribeDuringClusterFormation: false
  persistence:
    size: 40Gi
    storageClassName: 'ssd'
```

{% endcode %}

</details>

### A10. Auth-Server Default Replicas

#### Why the Change?

The default for `authServer.replicas` changed from `1` to `2` to improve availability.

#### What You Need to Do

<details>

<summary><strong>Setting the Old Replica Count</strong></summary>

If your `values.yaml` file does not set `authServer.replicas`, the new default applies after the upgrade. To keep the old behavior, set the replica count explicitly:

{% code lineNumbers="true" %}

```yaml
authServer:
  replicas: 1
```

{% endcode %}

</details>

### A11. Reserved MFA Environment Variables

#### Why the Change?

Chart 3.0.0 introduces dedicated Helm values for the MFA issuer and label: `global.authentication.mfa.issuer` and `global.authentication.mfa.label`. Because the chart now sets these on the auth-server itself, the matching environment variables `CYBUS_MFA_ISSUER` and `CYBUS_MFA_LABEL` are reserved and stripped from any `authServer.env` list. Setting them via `env` no longer has any effect.

#### What You Need to Do

<details>

<summary><strong>Migrating MFA Environment Variables to Helm Values</strong></summary>

If you previously set `CYBUS_MFA_ISSUER` or `CYBUS_MFA_LABEL` through `authServer.env`, remove them from the `env` list and set the equivalent Helm values instead.

| Environment Variable | Helm Value                         |
| -------------------- | ---------------------------------- |
| `CYBUS_MFA_ISSUER`   | `global.authentication.mfa.issuer` |
| `CYBUS_MFA_LABEL`    | `global.authentication.mfa.label`  |

**Before**

{% code lineNumbers="true" %}

```yaml
authServer:
  env:
    - name: CYBUS_MFA_ISSUER
      value: 'Acme Corp'
    - name: CYBUS_MFA_LABEL
      value: 'Connectware'
    - name: SOME_OTHER_ENV
      value: '5'
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    mfa:
      issuer: 'Acme Corp'
      label: 'Connectware'
authServer:
  env:
    - name: SOME_OTHER_ENV
      value: '5'
```

{% endcode %}

</details>

### A12. Workload Label Rename

#### Why the Change?

Workloads created by the `connectware` chart no longer carry the short `app=<component>` label. The chart now uses the standard Kubernetes recommended label `app.kubernetes.io/name=<component>` instead. This aligns the chart with [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) and matches what the `connectware-agent` chart already uses.

#### What You Need to Do

<details>

<summary><strong>Updating External Workload Selectors</strong></summary>

No changes to your `values.yaml` file are required. The upgrade works without action.

If you have external tooling that selects Connectware workloads through the old label, update the selector. Common examples:

* `kubectl` commands using `-l app=<component>`.
* Scripts, CI pipelines, or operators that filter pods, services, or other resources by `app=<component>`.
* `NetworkPolicy`, `PodMonitor`, `ServiceMonitor`, or other resources whose `selector` or `podSelector` matches `app=<component>`.
* Monitoring or logging configurations that group workloads by the `app` label.

Replace the selector with `app.kubernetes.io/name=<component>`. For example:

**Before**

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE} -l app=broker
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE} -l app.kubernetes.io/name=broker
```

{% endcode %}

</details>

### A13. Ingress Service Ports for TCP IngressRoutes

#### Why the Change?

The `connectware` LoadBalancer Service is now fully configurable through `connectwareIngress.service.ports`. The new default port list only contains the core Connectware ports. The ports `40000` to `40009`, which were previously exposed for [`Cybus::IngressRoute`](/data-flows/service-commissioning-files/resources/cybus-ingressroute) TCP resources, are no longer exposed unless you add them.

#### What You Need to Do

<details>

<summary><strong>Adding TCP Ports for IngressRoutes</strong></summary>

If you do not use `Cybus::IngressRoute` resources of type `tcp`, no action is required.

If you do, add an entry to `connectwareIngress.service.ports` for every `connectwarePort` your TCP IngressRoutes use. Ports between `40000` and `40100` are valid.

{% code lineNumbers="true" %}

```yaml
connectwareIngress:
  service:
    ports:
      - name: 'generic-tcp-40001'
        port: 40001
        targetPort: 40001
      - name: 'generic-tcp-40002'
        port: 40002
        targetPort: 40002
```

{% endcode %}

{% hint style="warning" %}
The list under `connectwareIngress.service.ports` fully replaces the default Service ports. When adding entries, keep the default Connectware ports from the chart's `values.yaml` and append your TCP ports, otherwise the Admin UI, MQTT, and other core entry points become unreachable.
{% endhint %}

</details>

### A14. NATS Metrics Path Change

#### Why the Change?

The intermediate `prometheus` block under NATS metrics is gone. The exporter sidecar configuration (`enabled`, `resources`) and the `ServiceMonitor` configuration now live directly under `nats.metrics`.

#### What You Need to Do

<details>

<summary><strong>Moving NATS Metrics Keys</strong></summary>

If you configured NATS metrics, move every key from `global.nats.metrics.prometheus.*` up one level to `nats.metrics.*`. The `global.nats` → `nats` move from [A7. Components Moved Out of global](#a7.-components-moved-out-of-global) applies here as well.

| Old                                               | New                             |
| ------------------------------------------------- | ------------------------------- |
| `global.nats.metrics.prometheus.enabled`          | `nats.metrics.enabled`          |
| `global.nats.metrics.prometheus.resources`        | `nats.metrics.resources`        |
| `global.nats.metrics.prometheus.serviceMonitor.*` | `nats.metrics.serviceMonitor.*` |

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  nats:
    metrics:
      prometheus:
        enabled: true
        resources:
          requests:
            cpu: 100m
            memory: 300Mi
        serviceMonitor:
          enabled: true
          labels:
            release: prometheus
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
nats:
  metrics:
    enabled: true
    resources:
      requests:
        cpu: 100m
        memory: 300Mi
    serviceMonitor:
      enabled: true
      labels:
        release: prometheus
```

{% endcode %}

</details>

## Part B: Connectware-Agent Chart Migration

Chart 3.0.0 removes built-in agent orchestration from the `connectware` chart and replaces it with the `connectware-agent` chart, embedded as a subchart. The following steps cover both migrating agents from the old `connectware` chart and updating existing subchart installations.

{% hint style="warning" %}
After the upgrade, you must re-register any agents that were scheduled with the `connectware` chart. See [Post-Upgrade Actions](#post-upgrade-actions).
{% endhint %}

Apply the following changes to your `connectware-agent` or `connectware` chart values. Not all sections apply to both deployment modes. Check the table below before working through them. Sections with mode-specific examples use **Standalone** and **Subchart** tabs:

| Section                                                                       | Standalone   | Subchart     |
| ----------------------------------------------------------------------------- | ------------ | ------------ |
| [B1. Protocol-Mapper Agents Structure](#b1.-protocol-mapper-agents-structure) | No changes   | **Required** |
| [B2. Image Version](#b2.-image-version)                                       | **Required** | No changes   |
| [B3. Security Contexts](#b3.-security-contexts)                               | **Required** | **Required** |
| [B4. Storage to Persistence](#b4.-storage-to-persistence)                     | No changes   | **Required** |
| [B5. TLS CA Configuration Renames](#b5.-tls-ca-configuration-renames)         | **Required** | **Required** |
| [B6. Reserved Environment Variables](#b6.-reserved-environment-variables)     | **Required** | **Required** |
| [B7. Resource Defaults](#b7.-resource-defaults)                               | **Required** | **Required** |
| [B8. Cluster Resource Name Changes](#b8.-cluster-resource-name-changes)       | **Required** | **Required** |

* **Standalone**: `connectware-agent` installed as its own Helm release, keys are at the root of its `values.yaml`. See [Installing Connectware Agents Using the Connectware-Agent Helm Chart](/data-flows/agents/agents-in-kubernetes/installing-connectware-agents-using-the-connectware-agent-helm-chart).
* **Subchart**: `connectware-agent` embedded in the `connectware` chart, keys are nested under `connectwareAgent.*`. See [Deploying Agents with Your Connectware Installation](/data-flows/agents/agents-in-kubernetes/deploying-agents-with-your-connectware-installation).

### B1. Protocol-Mapper Agents Structure

#### Why the Change?

Chart 3.0.0 replaces the built-in agent templates under `global.protocolMapperAgents` with the `connectware-agent` subchart. Subchart users now configure agents through `connectwareAgent.*` instead of `global.*`, and gain access to the `protocolMapperAgentDefaults` mechanism that standalone `connectware-agent` Helm chart already uses.

Standalone `connectware-agent` users are not affected by this restructuring. The per-key renames in [B2](#b2.-image-version) through [B6](#b6.-reserved-environment-variables) still apply, but the overall `protocolMapperAgents` / `protocolMapperAgentDefaults` layout is unchanged.

#### What You Need to Do

This section applies to subchart users only. Move `global.protocolMapperAgents` to `connectwareAgent.protocolMapperAgents`. The `connectwareAgent.protocolMapperAgentDefaults` block is now available for values shared across agents.

{% hint style="warning" %}
Connectware treats migrated agents as new entities after the upgrade. After the Helm upgrade completes, you must de-register the old agents and register the new ones. See [Post-Upgrade Actions](#post-upgrade-actions).
{% endhint %}

#### Promoting Shared Values to protocolMapperAgentDefaults

Optional but recommended when you have multiple agents. Override precedence is: schema defaults, then `protocolMapperAgentDefaults`, then per-agent entry. Each agent entry then only needs its `name` plus its overrides. For full semantics, see [Configuration Principles for the connectware-agent Helm Chart](/cybus-helm-charts/connectware-agent-helm-chart#configuration-principles-for-the-connectware-agent-helm-chart).

A subset of keys also inherits from the parent `connectware` chart's `global.*` values when not set on the agent or its defaults. This applies to security contexts, image values other than `image.name`, `podPriorityClassName`, `nodeSelector`, and `tolerations`. The effective precedence in that case is: schema defaults, then inherited `global.*` values from the `connectware` chart, then `protocolMapperAgentDefaults`, then per-agent entry.

To promote shared values:

1. Identify values that are identical across every agent, such as `env`, `connectwareHost`, `tls.ca`, `mTLS.enabled`, `persistence.storageClassName`, and `resources`.
2. Move those values into `protocolMapperAgentDefaults`.
3. Leave only the per-agent overrides plus `name` in each `protocolMapperAgents` entry.

Some keys are always agent-specific and have no default counterpart: `name`, `mTLS.keyPair`, and `existingAgentPasswordSecret`. Keep them on the agent entry.

#### Simple Example (Two Agents, Shared env)

**Before**

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: bender-robots
      storageSize: 50Mi
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
    - name: welder-robots
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
```

{% endcode %}

**After (shared env promoted)**

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgentDefaults:
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
  protocolMapperAgents:
    - name: bender-robots
      persistence:
        size: 50Mi
    - name: welder-robots
```

{% endcode %}

#### Advanced Example (Shared CA, Security Context, and Storage Class)

Agents share `env`, `tls.ca.cert`, `storageClassName`, and `containerSecurityContext`, but differ in `storageSize`.

**Before**

{% code lineNumbers="true" expandable="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      storageSize: 40Mi
      storageClassName: nfs-client
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
      tls:
        ca:
          cert: |
            -----BEGIN CERTIFICATE-----
            MIIFpT...
            -----END CERTIFICATE-----
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
    - name: bender-robots
      storageSize: 50Mi
      storageClassName: nfs-client
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
      tls:
        ca:
          cert: |
            -----BEGIN CERTIFICATE-----
            MIIFpT...
            -----END CERTIFICATE-----
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
```

{% endcode %}

**After**

{% code lineNumbers="true" expandable="true" %}

```yaml
connectwareAgent:
  protocolMapperAgentDefaults:
    persistence:
      storageClassName: nfs-client
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
    tls:
      ca:
        certChain: |
          -----BEGIN CERTIFICATE-----
          MIIFpT...
          -----END CERTIFICATE-----
  protocolMapperAgents:
    - name: welder-robots
      persistence:
        size: 40Mi
    - name: bender-robots
      persistence:
        size: 50Mi
```

{% endcode %}

In this example, `containerSecurityContext` matches the 3.0.0 default, so the block was dropped entirely. If your block had only partially overridden the default, you would merge it by hand as described in [B3. Security Contexts](#b3.-security-contexts).

### B2. Image Version

#### Why the Change?

The value controls the container image tag used, not necessarily a version. It is now aligned with the Kubernetes convention, matching the rename in [A2. Image Version](#a2.-image-version).

#### What You Need to Do

This section applies to **standalone** `connectware-agent` users only. Subchart users were previously unable to control image settings for agents. They can now use the values provided by the `connectware-agent` subchart, or let the chart fall back on the global `connectware` chart image tag in `global.image.tag` , which is already covered by [A2. Image Version](#a2.-image-version).

<details>

<summary><strong>Renaming the Image Key</strong></summary>

* Rename `image.version` to `image.tag`.

**Before**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    image:
      version: 2.3.1
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    image:
      tag: 2.3.1
```

{% endcode %}

</details>

### B3. Security Contexts

#### Why the Change?

Per-agent security context keys were renamed to use `Override` suffixes, matching the convention introduced in [A3. Security Contexts](#a3.-security-contexts).

{% hint style="warning" %}

## Override values replace defaults, they do not merge

A partial override strips any default it does not redeclare. If you customized a per-agent security context, your migrated output must include both the new 3.0.0 defaults (listed in [A3](#a3.-security-contexts)) and your customizations, merged by hand.
{% endhint %}

#### What You Need to Do

Per agent, in each entry under `protocolMapperAgents`:

* `securityContext` → `podSecurityContextOverride`
* `containerSecurityContext` → `containerSecurityContextOverride`

You can also use the `protocolMapperAgentDefaults.podSecurityContextOverride` and `protocolMapperAgentDefaults.containerSecurityContextOverride` block to set security context for all agents.

If your source security context block exactly matches the 3.0.0 defaults from [A3](#a3.-security-contexts), drop the block instead of emitting an override.

{% tabs %}
{% tab title="Standalone" %}
**Before**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
      runAsUser: 1000
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    containerSecurityContextOverride:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
          - ALL
      runAsUser: 1000
```

{% endcode %}
{% endtab %}

{% tab title="Subchart" %}
**Before**

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      containerSecurityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        runAsUser: 1000
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgents:
    - name: welder-robots
      containerSecurityContextOverride:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        runAsUser: 1000
```

{% endcode %}
{% endtab %}
{% endtabs %}

### B4. Storage to Persistence

#### Why the Change?

Per-agent storage keys of the `connectware` chart were folded into a `persistence` block by migrating to the `connectware-agent` chart as a subchart, matching the rename in [A4. Storage to Persistence](#a4.-storage-to-persistence). You can also use the `connectwareAgent.protocolMapperAgentDefaults.persistence` block to set persistence for all agents.

#### What You Need to Do

Per agent, in each entry under `protocolMapperAgents`:

| Old                | New                            |
| ------------------ | ------------------------------ |
| `storageSize`      | `persistence.size`             |
| `storageClassName` | `persistence.storageClassName` |

{% tabs %}
{% tab title="Standalone" %}
No changes are required when upgrading a standalone `connectware-agent` installation.
{% endtab %}

{% tab title="Subchart" %}
**Before**

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      storageSize: 50Mi
      storageClassName: nfs-client
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgents:
    - name: welder-robots
      persistence:
        size: 50Mi
        storageClassName: nfs-client
```

{% endcode %}
{% endtab %}
{% endtabs %}

### B5. TLS CA Configuration Renames

#### Why the Change?

The key holding the CA certificate body was renamed to reflect that it accepts a full certificate chain. The legacy `mTLS.caChain.*` path is also gone — previously it was kept for backwards compatibility and is now removed. Move all CA configuration under `tls.ca.*`.

#### What You Need to Do

Per agent, in each entry under `protocolMapperAgents`, and in `protocolMapperAgentDefaults` if you use it:

| Old                              | New                        |
| -------------------------------- | -------------------------- |
| `tls.ca.cert`                    | `tls.ca.certChain`         |
| `mTLS.caChain.cert`              | `tls.ca.certChain`         |
| `mTLS.caChain.existingConfigMap` | `tls.ca.existingConfigMap` |

{% tabs %}
{% tab title="Standalone" %}
**Before**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    mTLS:
      caChain:
        cert: |
          -----BEGIN CERTIFICATE-----
          MIIFpT...
          -----END CERTIFICATE-----
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    tls:
      ca:
        certChain: |
          -----BEGIN CERTIFICATE-----
          MIIFpT...
          -----END CERTIFICATE-----
```

{% endcode %}
{% endtab %}

{% tab title="Subchart" %}
**Before**

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      mTLS:
        caChain:
          cert: |
            -----BEGIN CERTIFICATE-----
            MIIFpT...
            -----END CERTIFICATE-----
```

{% endcode %}

**After**

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgents:
    - name: welder-robots
      tls:
        ca:
          certChain: |
            -----BEGIN CERTIFICATE-----
            MIIFpT...
            -----END CERTIFICATE-----
```

{% endcode %}
{% endtab %}
{% endtabs %}

### B6. Reserved Environment Variables

#### Why the Change?

Chart 3.0.0 strips a fixed set of environment variables from any user-supplied `env` list before they reach the agent pod. These names are reserved for the chart to set internally, so that agent identity, connectivity, and security cannot be silently misconfigured. Previously, user overrides could be applied or ignored; now they are always filtered. Use the Helm values we provide if you previously set one of these environment variables.

#### What You Need to Do

Remove the following names from every `env` list, including each entry under `protocolMapperAgents` and `protocolMapperAgentDefaults` if you use it:

* `CYBUS_AGENT_MODE`
* `CYBUS_AGENT_NAME`
* `CYBUS_HOSTNAME_INGRESS`
* `CYBUS_PROTOCOL_MAPPER_PASSWORD`
* `CYBUS_USE_MUTUAL_TLS`
* Any name starting with `CYBUS_DATAPLANE_`
* Any name starting with `CYBUS_STREAMSERVER_`

Custom variables you set through `env` are unaffected. Only the names above and the two prefixes are filtered.

<details>

<summary><strong>Helm Values to Use Instead</strong></summary>

The following table shows how to control these environment variables with the `connectware-agent` Helm chart.

| Environment Variable             | Helm Value                                                                                                                                                                                       |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CYBUS_AGENT_MODE`               | Always set to "distributed", do not set manually                                                                                                                                                 |
| `CYBUS_AGENT_NAME`               | `protocolMapperAgents[*].name`                                                                                                                                                                   |
| `CYBUS_HOSTNAME_INGRESS`         | `protocolMapperAgents[*].connectwareHost` or `protocolMapperAgentDefaults.connectwareHost`                                                                                                       |
| `CYBUS_PROTOCOL_MAPPER_PASSWORD` | Read from key `agentPassword` in the existing Kubernetes Secret configured in `protocolMapperAgents[*].existingAgentPasswordSecret` or `protocolMapperAgentDefaults.existingAgentPasswordSecret` |
| `CYBUS_USE_MUTUAL_TLS`           | `protocolMapperAgents[*].mTLS.enabled`                                                                                                                                                           |
| `CYBUS_DATAPLANE_HOST`           | `protocolMapperAgents[*].dataPlane.host`, `protocolMapperAgentDefaults.dataPlane.host`, `protocolMapperAgents[*].connectwareHost` or `protocolMapperAgentDefaults.connectwareHost`               |
| `CYBUS_DATAPLANE_PORT`           | Computed or overridden with `protocolMapperAgents[*].dataPlane.port` or `protocolMapperAgentDefaults.dataPlane.port`                                                                             |
| `CYBUS_DATAPLANE_SCHEME`         | Computed, do not set manually                                                                                                                                                                    |
| `CYBUS_DATAPLANE_USE_TLS`        | Computed or overridden with `protocolMapperAgents[*].dataPlane.tls` or `protocolMapperAgentDefaults.dataPlane.tls`                                                                               |
| `CYBUS_STREAMSERVER_HOST`        | `protocolMapperAgents[*].streamServer.host`, `protocolMapperAgentDefaults.streamServer.host`, `protocolMapperAgents[*].connectwareHost` or `protocolMapperAgentDefaults.connectwareHost`         |
| `CYBUS_STREAMSERVER_PORT`        | Computed or overridden with `protocolMapperAgents[*].streamServer.port` or `protocolMapperAgentDefaults.streamServer.port`                                                                       |
| `CYBUS_STREAMSERVER_SCHEME`      | Computed, do not set manually                                                                                                                                                                    |

</details>

{% tabs %}
{% tab title="Standalone" %}
**Before**

Reserved name `CYBUS_AGENT_MODE` listed alongside a custom variable:

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    env:
      - name: CYBUS_AGENT_MODE
        value: 'distributed'
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
```

{% endcode %}

**After**

Reserved name removed, custom variable kept:

{% code lineNumbers="true" %}

```yaml
protocolMapperAgents:
  - name: welder-robots
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
```

{% endcode %}
{% endtab %}

{% tab title="Subchart" %}
**Before**

Reserved name `CYBUS_AGENT_MODE` listed alongside a custom variable:

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      env:
        - name: CYBUS_AGENT_MODE
          value: 'distributed'
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
```

{% endcode %}

**After**

Reserved name removed, custom variable kept:

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgents:
    - name: welder-robots
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
```

{% endcode %}
{% endtab %}
{% endtabs %}

### B7. Resource Defaults

#### Why the Change?

Chart 3.0.0 halves the default CPU and memory requests and removes the default limits for protocol-mapper agents, matching the change made for `connectware` chart components in [A8. Resources Moved to Per-Component](#a8.-resources-moved-to-per-component). Additionally, for agents orchestrated using the `connectware` chart, the compute resource requests and limits need to be moved to the Helm values provided by the `connectware-agent` chart.

| Resource Field    | Old (chart 2.x) | New (chart 3.0.0) |
| ----------------- | --------------- | ----------------- |
| `requests.cpu`    | `2000m`         | `1000m`           |
| `requests.memory` | `2000Mi`        | `1000Mi`          |
| `limits.cpu`      | `2000m`         | not set           |
| `limits.memory`   | `2000Mi`        | not set           |

The same reasoning applies as in [A8. Resources Moved to Per-Component](#a8.-resources-moved-to-per-component): lower defaults do not reflect lower resource requirements, and running without limits in production is not recommended.

{% hint style="warning" %}
This affects both standalone and subchart deployments. If your `values.yaml` file does not set agent resources, your agents will receive the new, lower default requests and no default limits after the upgrade. Set the old values explicitly if your workloads require them.
{% endhint %}

#### What You Need to Do

If you set per-agent or `protocolMapperAgentDefaults` resources directly in **standalone** mode, your values carry over unchanged.

Subchart users only: if you previously set `global.podResources.distributedProtocolMapper` in the `connectware` chart, migrate it to `connectwareAgent.protocolMapperAgentDefaults.resources` as described in [A8. Resources Moved to Per-Component](#a8.-resources-moved-to-per-component).

If you relied on the chart-level defaults, decide whether to keep the previous values or adopt the new defaults. To keep the previous behavior, set the old chart 2.x defaults explicitly on each agent or on `protocolMapperAgentDefaults`.

{% tabs %}
{% tab title="Standalone" %}
**Before**

`values.yaml` contained a default of `2000m` / `2000Mi` for both requests and limits.

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  resources:
    requests:
      cpu: 2000m
      memory: 2000Mi
    limits:
      cpu: 2000m
      memory: 2000Mi
```

{% endcode %}

**After**

Set the previous values explicitly if you relied on these compute resource defaults:

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  resources:
    requests:
      cpu: 2000m
      memory: 2000Mi
    limits:
      cpu: 2000m
      memory: 2000Mi
```

{% endcode %}
{% endtab %}

{% tab title="Subchart" %}
**Before**

`values.yaml` of the `connectware` chart had compute resources in the `global.podResources.distributedProtocolMapper` block.

{% code lineNumbers="true" %}

```yaml
global:
  podResources:
    distributedProtocolMapper:
      requests:
        cpu: 2000m
        memory: 2000Mi
      limits:
        cpu: 2000m
        memory: 2000Mi
```

{% endcode %}

**After**

Move any values you set to `connectwareAgent.protocolMapperAgentDefaults.resources` and set the previous default values explicitly if you relied on these compute resources:

{% code lineNumbers="true" %}

```yaml
connectwareAgent:
  protocolMapperAgentDefaults:
    resources:
      requests:
        cpu: 2000m
        memory: 2000Mi
      limits:
        cpu: 2000m
        memory: 2000Mi
```

{% endcode %}
{% endtab %}
{% endtabs %}

### B8. Cluster Resource Name Changes

#### Why the Change?

Chart 3.0.0 replaces the helper that builds Kubernetes resource names for protocol-mapper agents. Most installations are unaffected, but a few naming patterns produce a different result on upgrade.

The patterns that produce a different name in chart 3.0.0:

* **The release name `connectware`.** The duplicated prefix `connectware-connectware-agent-<agent>` collapses to `connectware-agent-<agent>`. Affects every agent under that release. If you have used the name `connectware` for a `connectware-agent` chart installation, set the `fullNameOverride` Helm value to `connectware-connectware-agent`.
* **Long combined release-plus-agent names.** The new helper truncates the combined name at 52 characters with a fixed split between chart and agent name, instead of the old 63-character single truncation. Names that previously hit the old limit truncate differently.

{% hint style="warning" %}

## StatefulSet selectors are immutable in Kubernetes

If any of the patterns above apply to your installation, `helm upgrade` fails on the rename and the existing PersistentVolumeClaims are orphaned. Detect this before upgrading.
{% endhint %}

If none of these patterns apply to your release name or agent names, you do not need to take any action for this section. Continue to [Running the Upgrade](#running-the-upgrade).

#### Detecting Renames Before You Upgrade

Use the [helm-diff plugin](https://github.com/databus23/helm-diff) to compare the rendered output of the new chart version against the cluster state before applying the upgrade.

{% code lineNumbers="true" %}

```bash
helm plugin install https://github.com/databus23/helm-diff
helm diff upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware-agent --version 3.0.0 -f <values.yaml>
```

{% endcode %}

Substitute the following placeholders:

* `${NAMESPACE}`: the namespace of the installation.
* `${INSTALLATION_NAME}`: the name of the Helm release.
* `<values.yaml>`: the path to the migrated `values.yaml` file.

If the diff shows a StatefulSet, Service, or PersistentVolumeClaim renaming for any agent, stop and contact support before continuing. Resolving the rename requires deleting the old resources by hand, recreating them under the new name, and migrating data from the orphaned PVCs.

## Complete Before-and-After Examples

Use these as a reference for the overall output shape.

### Connectware Chart

<details>

<summary><strong>Before (chart 2.1.0 values)</strong></summary>

{% code title="values.yaml (2.1.0)" lineNumbers="true" expandable="true" %}

```yaml
global:
  licensekey: xxxxxxxxxx
  image:
    registry: registry.cybus.io/cybus/
    pullSecrets:
      - name: my-pull-secret
    pullPolicy: Always
    version: 2.3.0

  userManagement:
    adminUser:
      initialPassword: Y2hhbmdlbWU=

  ingress:
    service:
      annotations:
        service.beta.kubernetes.io/load-balancer-scheme: 'internet-facing'

  ingressDnsNames:
    - connectware.example.com

  authServer:
    replicas: 1

  broker:
    clusterSecret: xxxxxxxxxxxxxxxxx
    replicaCount: 3

  postgresql:
    storage:
      storageClassName: block-storage

  nats:
    replicas: 3
```

{% endcode %}

</details>

<details>

<summary><strong>After (chart 3.0.0 values)</strong></summary>

{% code title="values.yaml (3.0.0)" lineNumbers="true" expandable="true" %}

```yaml
global:
  licenseKey: 'xxxxxxxxxx'
  image:
    registry: registry.cybus.io/cybus/
    pullSecrets:
      - name: my-pull-secret
    pullPolicy: Always
    tag: '2.3.0'

  authentication:
    adminUser:
      initialPassword: 'changeme'

  ingressDNSNames:
    - connectware.example.com

authServer:
  replicas: 1

connectwareIngress:
  service:
    annotations:
      service.beta.kubernetes.io/load-balancer-scheme: 'internet-facing'

broker:
  clusterSecret: 'xxxxxxxxxxxxxxxxx'
  replicas: 3

postgresql:
  persistence:
    storageClassName: block-storage

nats:
  replicas: 3
```

{% endcode %}

</details>

### Connectware-Agent Chart

{% tabs %}
{% tab title="Standalone" %}
**Before (chart 2.1.0 values)**

{% code title="values.yaml (2.1.0)" lineNumbers="true" expandable="true" %}

```yaml
protocolMapperAgents:
  - name: bender-robots
    storageSize: 50Mi
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
  - name: welder-robots
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
```

{% endcode %}

**After (chart 3.0.0 values)**

{% code title="values.yaml (3.0.0)" lineNumbers="true" expandable="true" %}

```yaml
protocolMapperAgentDefaults:
  env:
    - name: CYBUS_TRUST_ALL_CERTS
      value: 'true'
protocolMapperAgents:
  - name: bender-robots
    persistence:
      size: 50Mi
  - name: welder-robots
```

{% endcode %}
{% endtab %}

{% tab title="Subchart" %}
**Before (chart 2.1.0 values)**

{% code title="values.yaml (2.1.0)" lineNumbers="true" expandable="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: bender-robots
      storageSize: 50Mi
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
    - name: welder-robots
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
```

{% endcode %}

**After (chart 3.0.0 values)**

{% code title="values.yaml (3.0.0)" lineNumbers="true" expandable="true" %}

```yaml
connectwareAgent:
  protocolMapperAgentDefaults:
    env:
      - name: CYBUS_TRUST_ALL_CERTS
        value: 'true'
  protocolMapperAgents:
    - name: bender-robots
      persistence:
        size: 50Mi
    - name: welder-robots
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Running the Upgrade

After migrating your `values.yaml` file or files, run the Helm upgrade.

### Verifying Your Backups

Make sure you have backups of the following before running the upgrade:

* All Kubernetes PersistentVolumes that Connectware uses
* Your Connectware database. See [Backing Up the Connectware Database](/deployment/upgrading-connectware/backing-up-the-connectware-database).
* Your `values.yaml` file or files
* All service commissioning files

### Running the Helm Upgrade

Follow the steps for the chart you are upgrading.

{% tabs %}
{% tab title="connectware chart" %}
Some changes in this release cannot be applied through a rolling restart, so you must fully stop Connectware before running the upgrade.

**1. Shutting Down Connectware**

Delete all workload controllers:

{% code lineNumbers="true" %}

```bash
kubectl delete -n ${NAMESPACE} sts,deploy -l app.kubernetes.io/part-of=connectware
```

{% endcode %}

**2. Running the Helm Upgrade**

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware --version 3.0.0 -f <values.yaml>
```

{% endcode %}
{% endtab %}

{% tab title="connectware-agent chart" %}
This applies to standalone deployments only. If you run the agent chart as a subchart of the `connectware` chart, the `connectware` chart upgrade already covers it.

Chart 3.0.0 includes changes that cannot be applied through a rolling restart, so you must fully stop the agents before upgrading. PersistentVolumeClaims are not deleted with their StatefulSets, so agent data is preserved.

**1. Shutting Down the Agents**

Delete the agent StatefulSets:

{% code lineNumbers="true" %}

```bash
kubectl delete -n ${NAMESPACE} sts -l app.kubernetes.io/instance=${INSTALLATION_NAME}
```

{% endcode %}

**2. Running the Helm Upgrade**

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware-agent --version 3.0.0 -f <values.yaml>
```

{% endcode %}
{% endtab %}
{% endtabs %}

Substitute the following placeholders:

* `${NAMESPACE}`: the namespace of the installation.
* `${INSTALLATION_NAME}`: the name of the Helm release.
* `<values.yaml>`: the path to the migrated `values.yaml` file.

### Monitoring the Upgrade

Monitor pod status while the upgrade runs.

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

Each pod passes through the following stages: `Terminating`, `Pending`, `PodInitializing`, `ContainerCreating`, `Init:x/x`, and finally `Running`. The upgrade is complete when all pods report `Running` and show the same number on both sides of the slash in the `READY` column.

See [Verifying the Connectware Upgrade](/deployment/upgrading-connectware/on-kubernetes#verifying-the-connectware-upgrade) for additional details on how to monitor the upgrade.

## Post-Upgrade Actions

Two tasks remain before your deployment is fully operational: re-registering migrated agents and reviewing resource usage.

<details>

<summary><strong>Re-Registering Protocol-Mapper Agents</strong></summary>

This applies if you moved agents from `global.protocolMapperAgents` to `connectwareAgent.protocolMapperAgents` in [B1](#b1.-protocol-mapper-agents-structure).

After the Helm upgrade, Connectware still holds the old agent identities — one user entry in [Users View](/access/user-management/users#users-view) and one entry in the [Agents View](/data-flows/agents/agents-view) per agent. The new agent pods start up with fresh credentials and attempt to register, but the old entries block them. You must clean up the old entries first, then authorize the new registrations.

Repeat the following steps for each migrated agent:

1. In the Admin UI, [delete the user](/access/user-management/users#deleting-users) whose name matches the agent. This clears the old credentials so the new agent can register under the same name.
2. In the [Agents View](/data-flows/agents/agents-view), select the old agent and click **Delete** to remove it from the list.
3. The agent pod registers automatically after the old entries are removed. In the Admin UI, open the [Client Registry](/access/client-registry) and authorize the pending registration for each agent. Check the agent name and pairing ID to confirm you are authorizing the correct agent.
4. Confirm each agent comes back online in **System** > **System Status** > **Agents**.

</details>

<details>

<summary><strong>Reviewing Resource Requests</strong></summary>

If you did not set explicit resource values in [A8](#a8.-resources-moved-to-per-component) or [B7](#b7.-resource-defaults), your workloads now run with the chart 3.0.0 defaults: reduced CPU and memory requests with no limits set. Monitor resource usage and set explicit values on affected components if you observe throttling or eviction.

</details>


# Upgrading Connectware to 2.4.0 (Kubernetes)

How to upgrade Connectware to version 2.4.0 on Kubernetes.

Connectware 2.4.0 adds the `caFile` property to the OPC UA Server, refreshes the Admin UI, and updates Node.js versions across Connectware services. For a complete list of changes, see the [2.4.0 changelog](https://docs.cybus.io/deployment/upgrading-connectware/on-kubernetes/pages/WQsCXfI86SHyPaoQB37K#connectware-2.4.0).

{% hint style="warning" %}

## Check your upgrade path

The steps in this guide apply to specific setups. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which upgrades and steps apply to your installation.
{% endhint %}

{% stepper %}
{% step %}

## Upgrading Connectware to 2.4.0

Follow the instructions in [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes) to upgrade to version 2.4.0.
{% endstep %}

{% step %}

## OPC UA Server with Custom PKI: Add caFile

This step applies if you are running OPC UA Server services with a **custom PKI** — that is, you have configured your own `certificateFile` and `privateKeyFile` signed by your organization's CA. If you do not use the OPC UA Server, skip this step.

Previously, the only way to provide your CA certificate to the OPC UA Server was to manually place it in `/app/.config/node-opcua-default-nodejs` inside the container. Connectware 2.4.0 introduces the `caFile` property as the recommended way to provide the CA certificate to the OPC UA Server.

To migrate, add `caFile` to the `properties` of your OPC UA Server resource in each affected service commissioning file, pointing to the path of your CA certificate inside the container:

{% code lineNumbers="true" %}

```yaml
resources:
  opcuaServer:
    type: Cybus::Server::Opcua
    properties:
      protocol: OpcuaServer
      certificateFile: /path/to/server.crt
      privateKeyFile: /path/to/server.key
      caFile: /path/to/ca.crt
```

{% endcode %}

For more information, see [CA Certificate](/connectors/servers/opc-ua-server#ca-certificate).
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.1.0 (Kubernetes)

How to upgrade Connectware to version 2.1.0 on Kubernetes.

Connectware 2.1.0 introduces support for the Siemens SIMATIC S7+ protocol and OPC UA complex data types. It also reintroduces service-level tracking for the Systemstate protocol, offering improved performance. Furthermore, it provides significant enhancements to resource deviation tracking and OPC UA reliability. For a complete list of changes, see the [2.1.0 changelog](https://docs.cybus.io/deployment/upgrading-connectware/on-kubernetes/pages/WQsCXfI86SHyPaoQB37K#what-has-changed-in-2.1.0).

{% hint style="warning" %}

## Check your upgrade path

The steps in this guide apply to specific setups. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which upgrades and steps apply to your installation.
{% endhint %}

{% stepper %}
{% step %}

## Upgrading Connectware to 2.1.0

Follow the instructions in [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes) to upgrade to version 2.1.0.
{% endstep %}

{% step %}

## Optional: Cleaning Up Disk Space After Upgrading to 2.1.0

As part of the Systemstate improvements in 2.1.0, the `resourceStates` NATS bucket is no longer used. If you want to save disk space, you can delete this bucket.

* To clean up disk space, run the following:

{% hint style="info" %}
Replace `${NAMESPACE}` with your Connectware namespace (e.g., `cybus`).
{% endhint %}

{% code lineNumbers="true" %}

```bash
kubectl debug -it \
  -n ${NAMESPACE} $(kubectl get pod -n ${NAMESPACE} -lapp=system-control-server -o name) \
 --image=registry.cybus.io/cybus/connectware-toolkit:1.4.0 \
 --target=system-control-server --profile general \
 -- bash -c 'source /proc/1/root/connectware_certs/env-1.0.sh && nats -s nats:4222 --user cybus_auth --password $CYBUS_NATS_AUTH_PASSWORD --tlscert=/proc/1/root/connectware_certs/cybus_client.crt --tlskey=/proc/1/root/connectware_certs/cybus_client.key --tlsca=/proc/1/root/connectware_certs/cybus_combined_ca.crt kv del resourceStates -f'
```

{% endcode %}
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.0.6 (Kubernetes)

How to upgrade Connectware to version 2.0.6 on Kubernetes.

Connectware 2.0.6 fixes an issue with Systemstate functionality on agents.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Upgrading Procedure

{% hint style="warning" %}
If your installation is older than 2.0.5, first complete the [upgrade to 2.0.5](/deployment/upgrading-connectware/on-kubernetes/to-2-0-5-on-kubernetes) before upgrading to 2.0.6.
{% endhint %}

1. Update the existing 2.0.5 deployment of the auth-server to use the 2.0.6 image and wait until the process is complete:

{% code lineNumbers="true" %}

```bash
kubectl patch -n ${NAMESPACE} deployment auth-server -p "{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"auth-server\",\"image\":\"registry.cybus.io/cybus/auth-server:2.0.6\"}]}}}}"
```

{% endcode %}

To verify that the auth-server is fully initialized, check for the `Connectware service bootstrap completed` log line in each auth-server container after its restart.

2. Download and install Connectware 2.0.6. For more information, see [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes).
3. If your agents are managed by separate Helm installations, upgrade those agents to version 2.0.6 as well. For more information, see [Upgrading the connectware-agent Helm Chart](/data-flows/agents/agents-in-kubernetes/upgrading-the-connectware-agent-helm-chart).


# Upgrading Connectware to 2.0.5 (Kubernetes)

How to upgrade Connectware to version 2.0.5 on Kubernetes.

Connectware 2.0.5 brings significant improvements to OPC UA reliability and CybusMQ performance, reducing message loss and improving system stability under load. For more information, see [What has changed in 2.0.5](/changelog#what-has-changed-in-205).

This upgrade requires you to delete the data volumes that store the metadata of CybusMQ.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Important Notes

This upgrade will delete all persisted data of the Connectware broker. This includes client sessions, subscriptions, and retained data. If your configuration relies on any type of data persisted by the broker, make sure to properly initialize your applications after the upgrade.

If you rely on persisted data, create a backup or snapshot of the broker data volumes. This allows you to roll back in case of complications.

## Upgrading Procedure

{% hint style="warning" %}
If your installation is older than 2.0.2, first complete the [upgrade to 2.0.2](/deployment/upgrading-connectware/on-kubernetes/to-2-0-2-on-kubernetes) before upgrading to 2.0.5.
{% endhint %}

1. Scale down the broker cluster to zero replicas to stop all broker pods. For more information, see [Scaling the Broker Down to Zero](/cybus-helm-charts/connectware-helm-chart/scaling-connectware-components-horizontally#scaling-the-broker-down-to-zero).
2. Delete the broker data volume of Connectware. For more information, see [Deleting Broker Data Volumes on Kubernetes](/broker/cybusmq/operations/deleting-broker-data-volumes#deleting-broker-data-volumes-on-kubernetes).
3. Download and install Connectware 2.0.5. For more information, see [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes).

Once all pods are up and running again and no new deviations appear in Connectware, the upgrade has been successful.


# Upgrading Connectware to 2.0.2 (Kubernetes)

How to upgrade Connectware to version 2.0.2 on Kubernetes.

Connectware 2.0.2 introduces new configuration options for HTTP connections.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Upgrading Procedure

1. Upgrade Connectware to 2.0.2 by following the instructions in [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes).
2. Apply the new HTTP connection options to existing services. To do so, [disable](/data-flows/services/managing/disabling) and re-[enable](/data-flows/services/managing/enabling) each affected service after upgrading.

For more information about the new HTTP connection options, see [What has changed in 2.0.2](https://docs.cybus.io/deployment/upgrading-connectware/on-kubernetes/pages/WQsCXfI86SHyPaoQB37K#what-has-changed-in-2.0.2).


# Upgrading Connectware to 2.0.1 (Kubernetes)

How to upgrade Connectware to version 2.0.1 on Kubernetes.

Connectware 2.0.1 introduces enhancements to the [Data Explorer](/monitoring/data-explorer).

{% hint style="warning" %}
If you are using services configured with `CYBUS_MQTT_ROOT`, you must run a migration script after installing Connectware 2.0.1 to ensure full Data Explorer compatibility.

If you are not using `CYBUS_MQTT_ROOT`, you can [upgrade](#upgrading-procedure) as usual — just note the additional [hardware requirements](#hardware-requirements).
{% endhint %}

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Hardware Requirements

Connectware 2.0.1 adds a new microservice for MQTT topic exploration. As a result, Connectware requires the following **additional resources**:

* 400m CPU (0.4 CPU)
* 1500 MiB of memory

On Kubernetes, this service runs with two replicas by default, effectively doubling the resource usage compared to Docker, but providing redundancy. Ensure your cluster has sufficient spare capacity before upgrading.

{% hint style="warning" %}
As with any deployment, we recommend monitoring system performance and adjusting resources as needed.
{% endhint %}

## Upgrading Procedure

{% hint style="warning" %}
If your installation is older than 2.0.0, first complete the [upgrade to 2.0.0](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes) before upgrading to 2.0.1.
{% endhint %}

{% stepper %}
{% step %}

### Upgrading Connectware to 2.0.1

* Update your Helm chart values and deploy Connectware 2.0.1. For more information, see [Upgrading Connectware (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes).

**Result:** Connectware is upgraded to 2.0.1.

{% hint style="warning" %}
If you are using services configured with `CYBUS_MQTT_ROOT`, continue with [step 2](#migrating-services-with-cybus_mqtt_root-configuration).

If you are not using `CYBUS_MQTT_ROOT`, your Connectware upgrade to 2.0.1 is complete. Just note the additional [hardware requirements](#hardware-requirements).
{% endhint %}
{% endstep %}

{% step %}

### Migrating Services with `CYBUS_MQTT_ROOT` Configuration

If you are using services configured with `CYBUS_MQTT_ROOT`, you must run a migration script after installing Connectware 2.0.1 to ensure full Data Explorer compatibility.

1. Set the shell variable `${NAMESPACE}` to the Kubernetes namespace in which your Connectware is installed.
2. Run the migration script. This is required if you have services using `CYBUS_MQTT_ROOT`.

{% code lineNumbers="true" %}

```bash
kubectl debug -it \
  -n ${NAMESPACE} $(kubectl get pod -n ${NAMESPACE} -lapp=system-control-server -o name) \
 --image=registry.cybus.io/cybus/connectware-toolkit:1.3.0 \
 --target=system-control-server --profile general \
 -- bash -c 'cw-db-migrate-2_0_1'
```

{% endcode %}

3. Verify that the script ran without errors.
4. Restart the `topic-explorer` Deployment:

{% code lineNumbers="true" %}

```bash
kubectl rollout restart -n ${NAMESPACE} deployment topic-explorer
```

{% endcode %}

**Result:** The migration script updates the database with new column values. You do not need to reinstall your services.
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.0.0 (Kubernetes)

How to upgrade Connectware to version 2.0.0 on Kubernetes.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Before You Begin

Upgrading to Connectware 2.0.0 introduces significant improvements in performance, scalability, and reliability. However, these changes also come with updated requirements for versions, networking, hardware, and storage.

This guide outlines the prerequisites and known limitations you must consider to ensure a smooth and successful upgrade.

{% hint style="warning" %}
Before starting the upgrade, read the entire guide. Some steps require developer work or preparation before the upgrade process begins.
{% endhint %}

{% hint style="warning" %}
Upgrading to Connectware 2.0.0 requires reinstalling all services. The main benefit of upgrading instead of performing a fresh installation is that it preserves the user database, including Multi-Factor Authentication. If you do not rely heavily on these features, a fresh installation may be the better option.

Even with a fresh installation, you will still need to follow this upgrade guide to update configuration parameters and adapt to the behavioral changes introduced in Connectware 2.0. However, you can skip the multi-step upgrade process itself.

If you are considering a fresh installation, we strongly recommend consulting with the Cybus Customer Support beforehand to confirm whether this is the right approach for your setup.
{% endhint %}

### Connectware Version Requirements

To be able to upgrade to Connectware 2.0.0, your Connectware version must be 1.7.0 or above.

If your Connectware installation is below 1.7.0, make sure that you have followed [Upgrading Connectware to 1.7.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-1-7-0-on-kubernetes) before upgrading to 2.0.0.

### Network Requirements

#### Why the Change?

With Connectware 2.0.0, some internal components have been updated to improve communication and performance. As a result, the network configuration has changed:

* **Added**: TCP/4222 and TCP/4223
* **Removed**: TCP/1884 and TCP/8884

#### What You Need to Do

<details>

<summary><strong>Updating the Network Ports</strong></summary>

Verify that your firewalls and security rules are updated to allow the new ports (TCP/4222 and TCP/4223) and to remove dependencies on the deprecated ones (TCP/1884 and TCP/8884).

This ensures uninterrupted connectivity between your agents and Connectware.

</details>

### Hardware Requirements

#### Why the Change?

Connectware 2.0.0 makes increased use of its PostgreSQL database and adds some components. When planning this upgrade, ensure your infrastructure can accommodate the enhanced resource requirements. This upgrade requires additional computing power.

#### What You Need to Do

<details>

<summary><strong>Updating the Hardware Setup</strong></summary>

We recommend adding the following resources to your hardware setup:

* **12** CPU cores
* **11** GB of memory
* **52** Gi of storage

However, these are general guidelines. Check what your specific system needs and make adjustments accordingly. If you were using the `control-plane-broker` option, you can offset these additional requirements with the resources it used, since it is being removed in this upgrade.

</details>

### Storage Requirements

#### Why the Change?

We have added two new components to Connectware:

* A streaming server called NATS
* A service called resource-status-tracking

Alongside other improvements, these additions enable Connectware to scale effectively for much larger deployments.

In addition, the latest versions of PostgreSQL and auth-server require updated Kubernetes resource requests and limits to maintain stability and performance under heavier workloads.

#### What You Need to Do

<details>

<summary><strong>Adjusting Kubernetes Resource Requests and Limits for Core Microservices</strong></summary>

The microservices `postgresql`, `auth-server`, `nats`, and `resource-status-tracking` now have new or revised Kubernetes resource requests and limits. Make sure to adapt the default values to match your deployment needs.

We recommend beginning with the defaults, monitoring performance metrics, and fine-tuning resource allocations as needed.

* To adjust the default values, update the corresponding values in the `global.podResources` Helm value context.

**Example**

```yaml
global:
  podResources:
    nats:
      limits:
        cpu: 2000m
        memory: 2000Mi
      requests:
        cpu: 2000m
        memory: 2000Mi
    resourceStatusTracking:
      limits:
        cpu: 1000m
        memory: 1000Mi
      requests:
        cpu: 1000m
        memory: 1000Mi
    database:
      limits:
        cpu: 2000m
        memory: 2000Mi
      requests:
        cpu: 2000m
        memory: 2000Mi
    authServer:
      limits:
        cpu: 1500m
        memory: 1000Mi
      requests:
        cpu: 1500m
        memory: 1000Mi
```

</details>

### Known Limitations

1. **Adding Certificates Through Admin UI Not Supported**

* You cannot add certificates to Connectware's CA bundle via the Admin UI.
* Instead, modify the `cybus_ca.crt` file directly on the `certs` volume.

2. **Backup via Admin UI Not Supported**

* The backup functionality through Admin UI is not supported.
* Instead, create backups of the database by running a `pg_dump` command on the `postgresql-0` pod.

{% code title="Example" lineNumbers="true" %}

```bash
kubectl exec -n ${NAMESPACE} postgresql-0 -- \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}

## Upgrade Procedure

Follow this procedure to upgrade your Connectware installation to version 2.0.0. The steps are divided into two parts:

* **Mandatory Upgrade Steps**: Required for all installations to ensure a smooth and stable upgrade.
* **Feature-Specific Upgrade Steps**: Only needed if you use certain features, so they remain compatible with Connectware 2.0.0.

Expand the following sections for an overview of all upgrade steps.

<details>

<summary><strong>Mandatory Upgrade Steps</strong></summary>

These steps apply to every Connectware installation upgrading to Connectware 2.0.0. For a detailed guide, see [Mandatory Upgrade Steps](#mandatory-upgrade-steps).

{% hint style="warning" %}
Depending on your setup, you may also need to perform additional Conditional Steps.
{% endhint %}

1. [**TLS Changes**](#id-1.-tls-changes): Default behavior on certificate validation has been adjusted.
2. [**Update Helm Values**](#id-2.-update-helm-values): Remove obsolete Helm values and adjust for changed and new values.
3. [**Preparing the Connectware Helm Upgrade**](#id-3.-preparing-the-connectware-helm-upgrade): Prepare removal of control-plane-broker and remove PostgreSQL StatefulSet.
4. [**Upgrading to Connectware 2.0.0**](#id-4.-upgrading-to-connectware-2.0.0): Download and install Connectware 2.0.0.
5. [**Enabling Agents in the Connectware Helm Chart**](#id-5.-enabling-agents-in-the-connectware-helm-chart): After upgrading Connectware, you need to go back to your agents to enable their TLS connections.
6. [**Updating Helm Values for the Connectware Agent Helm Chart**](#id-6.-updating-helm-values-for-the-connectware-agent-helm-chart): Update your agent configuration to comply with the updated Helm value configuration.
7. [**Upgrading Agents for the Connectware Agent Helm Chart**](#id-7.-upgrading-agents-for-the-connectware-agent-helm-chart): Upgrade your agents with the `connectware-agent` Helm chart.
8. [**Reinstalling Services**](#id-8.-reinstalling-services): This upgrade changes where your services are stored. You will need to reinstall any services after the upgrade.

</details>

<details>

<summary><strong>Feature-Specific Upgrade Steps</strong></summary>

Only follow these if you use the related features, so they continue working after the upgrade.

1. [**Roles and Permissions**](#id-1.-permissions-and-roles): New permissions were added to Connectware. Verify your custom roles, if they require updates.
2. [**Custom Connectors**](#id-2.-custom-connectors): Update your customer connector configurations to meet new requirements.
3. [**Systemstate Protocol**](#id-3.-systemstate-protocol): Update your Systemstate protocol configurations to meet new requirements.
4. [**Log Monitoring**](#id-4.-log-monitoring): Some logging strings are changed. If you use log monitoring, you may need to update it.
5. [**Heidenhain Agents**](#id-5.-heidenhain-agents-windows): Upgrade your Heidenhain agents.
6. [**Auto-Generated MQTT Topics of Resources**](#id-6.-auto-generated-mqtt-topics-of-resources): Topic generation no longer includes resource-specific properties. Update your service commissioning files if you relied on old patterns.
7. [**Auto-Generated MQTT Users**](#id-7.-auto-generated-mqtt-users): The behavior of how MQTT users are auto-generated has changed. You may need to update your service commissioning file if you relied on auto-generated MQTT users.

</details>

## Mandatory Upgrade Steps

These steps are required to upgrade your Connectware installation to Connectware 2.0.0.

### 1. TLS Changes

#### Why the Change?

To enhance security by default, Connectware agents now verify TLS certificate chains automatically. This ensures that all components communicate over a valid trust chain, while still giving you the option to keep the old behavior by explicitly disabling TLS verification.

#### Key Changes

<details>

<summary><strong>1. Introducing the cybus_combined_ca.crt</strong></summary>

Connectware maintains two separate CA chains:

* External certificates validated by `cybus_ca.crt`.
* Internal certificates validated by `shared_yearly_ca.crt`.

Which CA an agent requires depends on the hostname through which it connects to Connectware. For example, through the Connectware ingress, or directly to the Control Streaming Server (NATS) through the internal network.

To simplify configuration, we introduced `cybus_combined_ca.crt`, a bundle containing both chains, so agents can use a single file without needing to distinguish between internal and external CA certificates.

</details>

<details>

<summary><strong>2. Certificate Chain Verification in Agents</strong></summary>

Agents now enforce TLS chain validation by default. Each agent requires access to `cybus_combined_ca.crt`, available on the `certs` volume.

* To revert to the previous behavior (skipping verification), set the environment variable `CYBUS_TRUST_ALL_CERTS` to `true`. Note that it has been renamed from `TRUST_ALL_CERTS`.

</details>

<details>

<summary><strong>3. Configuring Certificate Hostnames</strong></summary>

The default Connectware-generated CA includes the hostnames `localhost` and `connectware`.

* To add more hostnames, configure the Helm value `global.ingressDNSNames`.

</details>

<details>

<summary><strong>4. Renewal of Certificate Chains</strong></summary>

With 2.0.0, the internal CA chain is replaced:

* Certificate Authority renamed from `CybusCA` to `CybusInternalCA`.
* The hostname `nats` is added as a Subject Alternate Name (SAN) to `shared_yearly_server.crt`.

The built-in default external CA certificate chain is also replaced.

* The hostname `connectware` is added as a SAN to `cybus_server.crt`.

If you rely on monitoring, custom setups, or modified certificates, adapt your configuration accordingly.

</details>

<details>

<summary><strong>5. Replacing CA Certificate Chain</strong></summary>

To replace Connectware’s default external chain with your enterprise-managed CA:

* Replace `cybus_ca.crt` with your enterprise CA certificate.
* Ensure `cybus_server.crt` and `cybus_server.key` form a valid key pair, signed by the CA in `cybus_ca.crt`.

Do not replace the internal CA (`shared_yearly_ca.crt`).

After replacement:

1. Restart the `system-control-server` deployment to rebuild and synchronize the combined CA bundle (`cybus_combined_ca.crt`):

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} rollout restart deployment system-control-server
```

{% endcode %}

2. Restart all Connectware services.

</details>

### 2. Update Helm Values

#### Why the Change?

Some changes to Connectware or the Helm chart prompt changes to Helm values, which you need to adapt your `values.yaml` file to:

* The optional control-plane-broker is removed from Connectware.
* All parameters to tune the inter-service communication have been removed.

#### Obsolete Helm Values

<details>

<summary><strong>Removing Obsolete Helm Values</strong></summary>

Some [Helm values](/reference/helm-chart-reference) are obsolete and have been removed. Remove the following Helm values from your `values.yaml` file for the `connectware` Helm chart:

* `global.rpcTimeout`
* `global.adminWebApp.rpcTimeout`
* `global.containerManager.rpcTimeout`
* `global.protocolMapper.rpcTimeout`
* `global.systemControlServer.rpcTimeout`
* `global.serviceManager.rpcTimeout`
* `global.serviceManager.storage`
* `global.controlPlaneBroker`
* `global.protocolMapperAgents[*].controlPlane`
* `global.serviceManager.useServicesGraph`

</details>

#### New Helm Values

<details>

<summary><strong>1. Ingress DNS Name Configuration</strong></summary>

With the changes TLS behavior in Connectware, it has become essential to add the DNS names under which Connectware is addressed, for example by agents.

If you are replacing Connectware's default PKI, you can, and likely have managed this yourself by providing a valid `cybus_server.crt` containing all Subject Alternate Names (SANs) used within your setup.

If you are using Connectware's default PKI, you can use the new Helm value `global.ingressDNSNames`, which is a list of names that will be added to the default `cybus_server.crt`.

#### Hostname Formats

You can include multiple hostnames in the list. The certificate will include all specified names in its SAN section.

The configuration accepts various hostname formats:

* Wildcards (e.g., `*.company.io`)
* Subdomains (e.g., `connectware.company.io`)
* Custom hostnames (e.g., `localhost`)
* IP Addresses (e.g. 192.168.100.42)

**Example**

{% code lineNumbers="true" %}

```yaml
global:
    ingressDNSNames:
        - company.io
        - localhost
        - *.company.io
        - connectware.company.io
        - 192.168.100.42
```

{% endcode %}

</details>

<details>

<summary><strong>2. Proxy Configuration</strong></summary>

Connectware's proxy configuration has been improved with version 2.0. Accompanying this, we added Helm values to configure proxy usage. This means that you cannot configure proxy usage directly through environment variables. If you have been doing this in the past, transfer your configuration to these new Helm values:

| **New Helm Value**            | **Type** | **Default Values** | **Purpose**                                                                                           |
| ----------------------------- | -------- | ------------------ | ----------------------------------------------------------------------------------------------------- |
| `global.proxy.url`            | string   | \<none>            | Address of the HTTP proxy server to be used                                                           |
| `global.proxy.exceptions`     | array    | \<none>            | List of hosts, for which the proxy is ignored                                                         |
| `global.proxy.existingSecret` | string   | \<none>            | Name of a Kubernetes Secret which contains the proxy configuration as the keys 'url' and 'exceptions' |

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  proxy:
    url: proxy.mycompany.tld
    exceptions:
      - my-server.mycompany.tld
      - my-internal-service.mycompany.tld
```

{% endcode %}

**Example with existing secret**

Create your secret using your preferred method, in this example we will use a `kubectl create` command:

{% code lineNumbers="true" %}

```bash
kubectl create secret -n ${NAMESPACE} generic my-connectware-proxy-config \
 --from-literal="url=http://myproxy.company.tld" \
 --from-literal="exceptions=http://myserver1.company.tld,https://myserver2.company.tld"
```

{% endcode %}

{% code lineNumbers="true" %}

```yaml
global:
  proxy:
    existingSecret: my-connectware-proxy-config
```

{% endcode %}

</details>

<details>

<summary><strong>3. NATS Configuration</strong></summary>

Connectware 2.0.0 introduces NATS as the stream server, primarily used for inter-service communication. The key configuration parameter is `global.nats.replicas`, which defines the cluster size. Typical values are `3` or `5`, with `3` as the default. Increasing this to `5` raises the redundancy level from N+1 to N+2.

{% hint style="warning" %}
The replicas value is critical for the NATS cluster configuration and is shared across multiple Connectware components.

This value can only be set during the initial installation of Connectware and cannot be modified later. Scaling operations on the `nats` StatefulSet must not be performed.
{% endhint %}

The following configuration values are available for the NATS streaming server:

| **New Helm Value**                                        | **Type** | **Default Values**                                                                                                                                           | **Purpose**                                                                                  |
| --------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| `global.nats.replicas`                                    | integer  | 3                                                                                                                                                            | The number of NATS replicas                                                                  |
| `global.nats.podAntiAffinity`                             | string   | soft                                                                                                                                                         | The podAntiAffinity behavior for NATS (one of `none`, `soft`, `hard`)                        |
| `global.nats.podAntiAffinityTopologyKey`                  | string   | kubernetes.io/hostname                                                                                                                                       | The podAntiAffinityTopologyKey for NATS (one of `none`, `soft`, `hard`)                      |
| `global.nats.labels`                                      | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to NATS resources                                       |
| `global.nats.annotations`                                 | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to NATS resources                                  |
| `global.nats.podLabels`                                   | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to NATS pod resources                                   |
| `global.nats.podAnnotations`                              | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to NATS pod resources                              |
| `global.nats.service.labels`                              | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to NATS service resources                               |
| `global.nats.service.annotations`                         | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to NATS service resources                          |
| `global.podResources.nats.resources`                      | array    | For a list of all default values, see [default-values.yaml](/deployment/installing-connectware/on-kubernetes#creating-a-copy-of-the-default-valuesyaml-file) | Kubernetes compute resource requirements and limits                                          |
| `global.nats.env`                                         | array    | \<none>                                                                                                                                                      | Array containing environment variables as name and value pairs to be applied to NATS service |
| `global.nats.metrics.prometheus.enabled`                  | boolean  | false                                                                                                                                                        | Enable Prometheus exporter for NATS                                                          |
| `global.nats.metrics.prometheus.resources`                | array    | For a list of all default values, see [default-values.yaml](/deployment/installing-connectware/on-kubernetes#creating-a-copy-of-the-default-valuesyaml-file) | Kubernetes compute resource requirements and limits                                          |
| `global.nats.metrics.prometheus.serviceMonitor.enabled`   | boolean  | false                                                                                                                                                        | Enable Prometheus Operator ServiceMonitor for NATS                                           |
| `global.nats.metrics.prometheus.serviceMonitor.namespace` | string   | \<none>                                                                                                                                                      | Namespace for the Prometheus ServiceMonitor                                                  |
| `global.nats.metrics.prometheus.serviceMonitor.labels`    | object   | \<none>                                                                                                                                                      | Labels for the Prometheus ServiceMonitor                                                     |
| `global.nats.storage.size`                                | string   | 16Gi                                                                                                                                                         | Define the size of the NATS JetStream volume                                                 |
| `global.nats.storage.storageClassName`                    | string   | \<none>                                                                                                                                                      | Define a Kubernetes StorageClass that will be used for the NATS JetStream volume             |
| `global.nats.containerSecurityContext`                    | array    | For a list of all default values, see [default-values.yaml](/deployment/installing-connectware/on-kubernetes#creating-a-copy-of-the-default-valuesyaml-file) | Set a container SecurityContext as defined by Kubernetes API                                 |

</details>

<details>

<summary><strong>4. Resource-Status-Tracking Configuration</strong></summary>

In addition to the new stream server, Connectware introduces a second new component called `resource-status-tracking`. This component allows you to monitor the status of resources created through service commissioning files and enables you to detect deviations in service behavior.

The following configuration values are available for `resource-status-tracking`:

| **New Helm Value**                                         | **Type** | **Default Values**                                                                                                                                           | **Purpose**                                                                                                    |
| ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `global.resourceStatusTracking.replicas`                   | integer  | 2                                                                                                                                                            | The number of resource-status-tracking replicas                                                                |
| `global.resourceStatusTracking.podAntiAffinity`            | string   | soft                                                                                                                                                         | The podAntiAffinity behavior for resourceStatusTracking (one of "none", "soft", "hard")                        |
| `global.resourceStatusTracking.podAntiAffinityTopologyKey` | string   | kubernetes.io/hostname                                                                                                                                       | The podAntiAffinityTopologyKey for resourceStatusTracking (one of "none", "soft", "hard")                      |
| `global.resourceStatusTracking.labels`                     | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to resourceStatusTracking resources                                       |
| `global.resourceStatusTracking.annotations`                | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to resourceStatusTracking resources                                  |
| `global.resourceStatusTracking.podLabels`                  | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to resourceStatusTracking pod resources                                   |
| `global.resourceStatusTracking.podAnnotations`             | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to resourceStatusTracking pod resources                              |
| `global.resourceStatusTracking.service.labels`             | object   | \<none>                                                                                                                                                      | A set of labels that will be applied to resourceStatusTracking service resources                               |
| `global.podResources.resourceStatusTracking.resources`     | array    | For a list of all default values, see [default-values.yaml](/deployment/installing-connectware/on-kubernetes#creating-a-copy-of-the-default-valuesyaml-file) | Kubernetes compute resource requirements and limits                                                            |
| `global.resourceStatusTracking.service.annotations`        | object   | \<none>                                                                                                                                                      | A set of annotations that will be applied to resourceStatusTracking service resources                          |
| `global.resourceStatusTracking.env`                        | array    | \<none>                                                                                                                                                      | Array containing environment variables as name and value pairs to be applied to resourceStatusTracking service |
| `global.resourceStatusTracking.containerSecurityContext`   | array    | For a list of all default values, see [default-values.yaml](/deployment/installing-connectware/on-kubernetes#creating-a-copy-of-the-default-valuesyaml-file) | Set a container SecurityContext as defined by Kubernetes API                                                   |

</details>

<details>

<summary><strong>5. PostgreSQL Storage Size</strong></summary>

In previous releases, the storage volume of the PostgreSQL component was fixed at 1 Gi. With Connectware 2.0.0, the reliance on PostgreSQL has increased, resulting in a new default storage size of 5 Gi. This parameter is now configurable.

We recommend to allocate at least 5 Gi. For larger deployments, storage sizes of 20 Gi or more may be appropriate.

You can configure the storage size via the `global.postgresql.storage.size` Helm value:

{% code lineNumbers="true" %}

```yaml
global:
  postgresql:
    storage:
      size: 10Gi
```

{% endcode %}

</details>

<details>

<summary><strong>6. Enabling MQTTS for Protocol-Mapper Agents</strong></summary>

A new Helm value is available to configure whether a protocol-mapper agent establishes its data plane connection to the Connectware MQTT broker using TLS.

| **New Helm Value**                             | **Type** | **Default Values** | **Purpose**                                                 |
| ---------------------------------------------- | -------- | ------------------ | ----------------------------------------------------------- |
| `global.protocolMapperAgents[*].dataPlane.tls` | boolean  | false              | Enable TLS encryption for agent's MQTT data plan connection |

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      dataPlane:
        tls: true
```

{% endcode %}

</details>

<details>

<summary><strong>7. Disabling Agents During the Connectware Upgrade</strong></summary>

{% hint style="warning" %}
This step prepares agents orchestrated with the `connectware` Helm chart for disabling during the upgrade. Agents orchestrated by other methods must be shut down separately, as described in [7. Shutting Down Protocol-Mapper Agents](#id-4.-upgrading-to-connectware-2.0.0).
{% endhint %}

To prevent agents from requiring re-registration after the upgrade, you must disable them during the installation. Once the upgrade is complete, you will re-enable the agents, update their configuration, and provide them with a valid CA certificate.

* To disable the agents defined in your Connectware Helm chart, set the Helm value `global.protocolMapperAgents` and all related values within this context to disabled. You can do this either by commenting out each line with a `#` or by temporarily removing them from the file.

</details>

### 3. Preparing the Connectware Helm Upgrade

#### Why the Change?

Connectware 2.0.0 introduces architectural improvements that require you to remove or adjust certain resources before running the Helm upgrade. This ensures a clean and successful upgrade process.

#### What You Need to Do

<details>

<summary><strong>1. Removing the Control-Plane-Broker</strong></summary>

The `control-plane-broker` is deprecated and its associated StatefulSet is no longer used. It will not be started anymore after the upgrade.

* No action is required in your Helm installation.
* Optional: Remove `global.controlPlaneBroker` from the `connectware` chart and `controlPlaneBrokerEnabled` from the `connectware-agent` chart.
* The `brokerdata-control-plane-broker-*` and `brokerlog-control-plane-broker-*` PersistentVolumeClaims are not removed automatically. Delete them manually if you want to reclaim the storage.

</details>

<details>

<summary><strong>2. Backing Up Your PostgreSQL Database</strong></summary>

With Connectware 2.0.0, Connectware uses a new major version of PostgreSQL. You need to delete your `postgresql` volume before upgrading Connectware (this is covered later in this upgrade guide). This requires you to create a backup of your database and restore this after the upgrade.

{% hint style="warning" %}
Any modifications done to Connectware after the following database backup will be lost after the Connectware 2.0.0 upgrade. We recommend to create the backup right before upgrading to Connectware 2.0.0.
{% endhint %}

1. To create a backup of your database, run the following command.

{% code lineNumbers="true" %}

```bash
kubectl exec -n ${NAMESPACE} postgresql-0 -- \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}

2. Make sure the backup is successful, then store the database file in a secure location.

</details>

<details>

<summary><strong>3. Service-Manager Volume Backup &#x26; Removal</strong></summary>

The `service-manager` PersistentVolumeClaim (PVC) is deprecated and will be removed automatically during the upgrade to 2.0.0.

Depending on your ReclaimPolicy, this may or may not mean that the volume is being deleted too. If it is not automatically deleted, you will have to manually delete the volume previously associated with the `service-manager` PersistentVolumeClaim to free up the disk space.

The former contents will in the future be stored in the PostgreSQL database, but will not be automatically migrated. You will need to reinstall any services you used before. See [Reinstalling Services](#12-reinstalling-services).

If you do not have your services stored outside of Connectware, make sure to export your services, or create a backup of your `service-manager` volume before upgrading.

</details>

### 4. Upgrading to Connectware 2.0.0

{% hint style="warning" %}
Make sure all prior steps are completed before proceeding with the Helm upgrade.
{% endhint %}

<details>

<summary><strong>1. Updating Helm Repository Cache</strong></summary>

Before performing the upgrade, update the Helm repository cache to ensure the latest Connectware chart version is available.

* Run the following command:

{% code lineNumbers="true" %}

```bash
helm repo update
```

{% endcode %}

</details>

<details>

<summary><strong>2. Reviewing the Connectware Changelog</strong></summary>

Before upgrading to Connectware 2.0.0, review the [changelog](/changelog#what-has-changed-in-200) to familiarize yourself with new features, bug fixes, and other changes introduced in Connectware 2.0.0.

</details>

<details>

<summary><strong>3. Reviewing the Readme File</strong></summary>

Before upgrading to Connectware 2.0.0, review the readme file. The readme may contain important version-specific upgrade instructions.

* To open the readme file, run the following command:

{% code lineNumbers="true" %}

```bash
helm show readme ${REPO_NAME}/connectware --version <2.0.0>
```

{% endcode %}

</details>

<details>

<summary><strong>4. Comparing Helm Configurations between Connectware Versions</strong></summary>

With a new Connectware version, there might be changes to the default Helm configuration values. We recommend that you compare the default Helms values of your current Connectware version with the default Helm values of your target Connectware version.

* To display the new default values, enter the following command:

{% code lineNumbers="true" %}

```bash
helm show values ${REPO_NAME}/connectware --version <2.0.0>
```

{% endcode %}

* To display which Connectware default values have changed between your current version and your target version, enter the following command:

{% code lineNumbers="true" %}

```yaml
diff <(helm show values ${REPO_NAME}/connectware --version <current-version>) <(helm show values ${REPO_NAME}/connectware --version <2.0.0>
```

{% endcode %}

**Example**

{% code lineNumbers="true" %}

```yaml
diff <(helm show values cybus/connectware --version 1.1.0) <(helm show values cybus/connectware --version 1.1.1)
83c83
<     version: 1.1.0
---
>     version: 1.1.1
```

{% endcode %}

In this example, only the image version has changed. However, if any of the Helm value changes are relevant to your setup, make the appropriate changes.

* To override default Helm values, add the custom Helm value to your local `values.yaml` file.

</details>

<details>

<summary><strong>5. Adjusting Helm Values</strong></summary>

When you have reviewed the necessary information, adjust your configuration in your `values.yaml` file. Not every upgrade requires adjustments.

If you specified which image version of Connectware to use by setting the Helm value `global.image.version` you will need to update this to `<target-version>`. Unless you have a specific reason to use a specific image version, we recommend not setting the Helm value.

</details>

<details>

<summary><strong>6. Verifying your Backups</strong></summary>

Make sure that you store backups of your setup. This allows you to restore a previous state if necessary.

Your backups must consist of the following files:

* All Kubernetes PersistentVolumes that Connectware uses
* Your Connectware database
* Your `values.yaml` file
* All service commissioning files

Depending on your local infrastructure, it may be necessary to back up additional files.

</details>

<details>

<summary><strong>7. Shutting Down Protocol-Mapper Agents</strong></summary>

{% hint style="warning" %}
In this step, you need to shut down any agents currently connected to your Connectware instance that are **not** managed by the `connectware` chart. Agents orchestrated through the `connectware` chart have already been prepared for shutdown as part of [7. Disabling Agents During the Connectware Upgrade](#id-2.-update-helm-values).
{% endhint %}

Before running the `helm upgrade` command, you must stop all connected agents. Agents which remain up during this upgrade run the risk of having to go through the agent registration process again.

* **Docker Run**: To stop agents which were started using `docker run`, use the `docker stop` command. If you are not aware of the name these containers use, run the `docker ps` command to find out.
* **Docker Compose**: If your agents are running in Docker Compose, use the `docker compose down` command to stop them.
* **Agent Helm Chart**: You can shut down agents that have been installed via the `connectware-agent` Helm chart using this command:

{% code lineNumbers="true" %}

```bash
kubectl get -n ${NAMESPACE} sts -lapp.kubernetes.io/component=protocol-mapper-agent -o name | xargs -I % kubectl scale -n ${NAMESPACE} % --replicas 0
```

{% endcode %}

</details>

<details>

<summary><strong>8. Removing the PostgreSQL StatefulSet</strong></summary>

* Before running the `helm upgrade` command, you must remove the `postgresql` StatefulSet:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} delete sts postgresql
```

{% endcode %}

</details>

<details>

<summary><strong>9. Initial Connectware Upgrade</strong></summary>

You can now start the first of two upgrade processes. This first upgrade run applies the new Connectware 2.0.0 workloads and prepares the system for the required database migration.

* To upgrade Connectware, enter the following command:

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} ${REPO_NAME}/connectware --version <2.0.0> -f <values.yaml>
```

{% endcode %}

**Result:** The newly generated workload definitions are applied to your Kubernetes cluster and your Connectware pods are replaced.

</details>

<details>

<summary><strong>10. Shutting Down Connectware</strong></summary>

* Wait for the `system-control-server` deployment to contain a ready pod, then shut down Connectware to restore your PostgreSQL database:

{% code lineNumbers="true" %}

```bash
kubectl get -n ${NAMESPACE} deploy,sts -lapp.kubernetes.io/part-of=connectware -o name | xargs -I % kubectl scale -n ${NAMESPACE} % --replicas 0
```

{% endcode %}

</details>

<details>

<summary><strong>11. Restoring the PostgreSQL Database</strong></summary>

1. Note down the Persistent Volume name for your `postgresql-postgresql-0` PersistentVolumeClaim. You will need this name later to make sure the volume is not recycled.

{% code lineNumbers="true" %}

```bash
kubectl get -n ${NAMESPACE} pvc -o jsonpath='{.spec.volumeName}{"\n"}' postgresql-postgresql-0
```

{% endcode %}

2. Remove the `postgresql-postgresql-0` PersistentVolumeClaim:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} delete pvc postgresql-postgresql-0
```

{% endcode %}

3. Remove the PostgreSQL PersistentVolume. You can skip this step if the volume has been automatically deleted through a reclaim policy, or if you are sure a new volume will be used. If the same volume is reused for postgresql, the upgrade will fail.

{% code lineNumbers="true" %}

```bash
kubectl delete pv [persistent-volume-name-from-previous-step]
```

{% endcode %}

4. Start PostgreSQL:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} scale sts postgresql --replicas=1
```

{% endcode %}

5. Restore your PostgreSQL Database. Wait for the postgresql-0 pod to become ready, then run:

{% code lineNumbers="true" %}

```bash
cat connectware_database.sql | kubectl exec -n ${NAMESPACE} postgresql-0 \
  -i -- psql -U cybus-admin -d cybus_connectware
```

{% endcode %}

</details>

<details>

<summary><strong>12. Final Connectware Upgrade after Database Restore</strong></summary>

You can start the final upgrade process. This upgrade finalizes the process by starting Connectware with the restored PostgreSQL database.

* To upgrade Connectware, enter the following command:

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} ${REPO_NAME}/connectware --version <2.0.0> -f <values.yaml>
```

{% endcode %}

**Optional:** You can use the `--atomic --timeout 10m` command line switch, which will cause Helm to wait for the result of your upgrade and perform a rollback when it fails. We recommend setting the timeout value to at least 10 minutes, but because the time it takes to complete an upgrade strongly depends on your infrastructure and configuration you might have to increase it further.

**Result:** The newly generated workload definitions are applied to your Kubernetes cluster and your Connectware pods are replaced.

</details>

<details>

<summary><strong>13. Verifying the Connectware Upgrade</strong></summary>

You can monitor the Connectware upgrade progress to verify that everything runs smoothly, to know when the installation is successful, or to investigate potential issues.

#### Monitoring the Connectware Upgrade

The Connectware upgrade can take a few minutes. To monitor the upgrade process, do one of the following:

* To monitor the current status of the upgrade process, enter the following command:

{% code lineNumbers="true" %}

```bash
kubectl get pods -n ${NAMESPACE}
```

{% endcode %}

* To monitor the continuous progress of the upgrade process, enter the following command:

{% code lineNumbers="true" %}

```bash
while [ True ]; do clear; kubectl get pod -n ${NAMESPACE}; sleep 5; done
```

{% endcode %}

* To stop monitoring the continuous progress of the upgrade process , press <kbd>Ctrl</kbd>+<kbd>C</kbd>.

#### Pod Stages During the Connectware Upgrade

During the Connectware upgrade, the pods go through the following stages:

* Terminating
* Pending
* PodInitializing
* ContainerCreating
* Init:x/x
* Running

When pods reach the STATUS Running, they go through their individual startup before reporting as Ready. To be fully functional, all pods must reach the STATUS Running and report all their containers as ready. This is indicated by them showing the same number on both sides of the / in the column READY.

**Example**

{% code lineNumbers="true" %}

```bash
kubectl get pod -n ${NAMESPACE}
```

{% endcode %}

| NAME                                   | READY | STATUS  | RESTARTS | AGE   |
| -------------------------------------- | ----- | ------- | -------- | ----- |
| admin-web-app-7cd8ccfbc5-bvnzx         | 1/1   | Running | 0        | 3h44m |
| auth-server-5b8c899958-f9nl4           | 1/1   | Running | 0        | 3m3s  |
| broker-0                               | 1/1   | Running | 0        | 3h44m |
| broker-1                               | 1/1   | Running | 0        | 2m1s  |
| connectware-7784b5f4c5-g8krn           | 1/1   | Running | 0        | 21s   |
| container-manager-558d9c4cbf-m82bz     | 1/1   | Running | 0        | 3h44m |
| doc-server-55c77d4d4c-nwq5f            | 1/1   | Running | 0        | 3h44m |
| ingress-controller-6bcf66495c-l5dpk    | 1/1   | Running | 0        | 18s   |
| postgresql-0                           | 1/1   | Running | 0        | 3h44m |
| protocol-mapper-67cfc6c848-qqtx9       | 1/1   | Running | 0        | 3h44m |
| service-manager-f68ccb767-cftps        | 1/1   | Running | 0        | 3h44m |
| system-control-server-58f47c69bf-plzt5 | 1/1   | Running | 0        | 3h44m |
| workbench-5c69654659-qwhgc             | 1/1   | Running | 0        | 15s   |

At this point Connectware is upgraded and started. You can now make additional configurations or verify the upgrade status in the Admin UI.

</details>

### 5. Enabling Agents in the Connectware Helm Chart

When upgrading to Connectware 2.0.0, protocol-mapper agents must be explicitly enabled again. This requires updating Helm values and configuring TLS certificates — or, in less secure setups, choosing to trust all certificates.

The following steps are required:

1. Update Helm values to their new equivalents.
2. Configure TLS (recommended) or opt to trust all certificates (not recommended).
3. Re-run `helm upgrade` to apply the changes.

Agents connecting to Connectware must either:

* Provide a valid CA certificate that matches the server certificate, **OR**
* Skip certificate validation by setting `CYBUS_TRUST_ALL_CERTS` to `true` (not recommended).

#### Which Certificate to Use

The certificate that you provide depends on how the agent connects:

* Via Connectware ingress: Use `cybus_ca.crt`.
* Via the internal network: Use `shared_yearly_ca.crt`.
* Simplified option that works for both cases: Use `cybus_combined_ca.crt`.

Use the table below to decide which option applies to your setup:

<details>

<summary><strong>Overview of Certificate Behavior</strong></summary>

| CA certificate | Value of `CYBUS_TRUST_ALL_CERTS` | Behavior                                                                                                                                                                                                                                                                                                        | Log message during control connection                                                              |
| -------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Not Configured | false                            | **Default**: TLS connections, like the control connection to Connectware, will try to use the system trust store to do certificate validation. This will only work when the CAs being used in Connectware are signed by a well-known CA authority or when self-signed CAs were added to the system trust store. | CA certificate not found, using system trusted CAs for NATS connection.                            |
| Not Configured | true                             | TLS connections, like the control connection to Connectware, will not validate certificates and will trust all certificates.                                                                                                                                                                                    | CA certificate not found, Connectware configured for trusting all certificates for NATS connection |
| Configured     | true                             | TLS connections, like the control connection to Connectware, will not validate server certificates and will trust any cert.                                                                                                                                                                                     | CA certificate found, but trusting all certificates for NATS connection                            |
| Configured     | false                            | **Recommended**: TLS connections, like the control connection to Connectware, will validate server certificates and will not trust any cert.                                                                                                                                                                    | CA certificate found, using it for NATS connection with CA verification                            |

</details>

#### What You Need to Do

<details>

<summary><strong>1. Updating the Helm Values</strong></summary>

You must update the Helm values of your `connectware` installation again to re-enable agents by removing the "#" you added, or adding them to the Helm values file again. Then add the `cybus_combined_ca.crt` or set `CYBUS_TRUST_ALL_CERTS` to `true`. If you were directly targeting our MQTT broker or control-plane-broker before, you should also move the respective configuration to their new replacements.

The following Helm values have changed. If you had specific configuration for these in the past, update the Helm values accordingly.

For some Helm values, you need to take additional steps depending on your setup. The required steps are covered in the following sections.

| **Old Helm Value**                                              | **New Helm Value**                                        | **Required Change**                               |
| --------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------- |
| `global.protocolMapperAgents[*].mTLS.caChain.cert`              | `global.protocolMapperAgents[*].tls.ca.certChain`         | Move                                              |
| `global.protocolMapperAgents[*].mTLS.caChain.existingConfigMap` | `global.protocolMapperAgents[*].tls.ca.existingConfigMap` | Move                                              |
| `global.protocolMapperAgents[*].mqttDataHost`                   | `global.protocolMapperAgents[*].dataPlane.host`           | See **1.1 - Directly Targeting MQTT Broker**      |
| `global.protocolMapperAgents[*].mqttDataPort`                   | `global.protocolMapperAgents[*].dataPlane.port`           | See **1.1 - Directly Targeting MQTT Broker**      |
| `global.protocolMapperAgents[*].mqttHost`                       | `global.protocolMapperAgents[*].streamServer.host`        | See **1.2 - Directly Targeting Streaming Server** |
| `global.protocolMapperAgents[*].mqttPort`                       | `global.protocolMapperAgents[*].streamServer.port`        | See **1.2 - Directly Targeting Streaming Server** |

</details>

<details>

<summary><strong>1.1 - Directly Targeting MQTT Broker</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our MQTT broker instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

The major hindrance is, that the name "broker", which is used by our MQTT broker on the internal network, is not part of the `cybus_server.crt` by default. In order to connect agents with a TLS connection to this hostname, you either need to add the hostname "broker" as a Subject Alternate Name (SAN) to the certificate, or set `CYBUS_TRUST_ALL_CERTS=true` for the agent.

**Adding the Hostname to the Default Certificate**

If you are using the built-in default certificate for Connectware, you can add the hostname "broker" through the Helm value `global.ingressDNSNames`:

{% code lineNumbers="true" %}

```yaml
global:
  ingressDNSNames:
    - broker
```

{% endcode %}

It is easiest if you add this Helm value before running your upgrade to Connectware 2.0.0, since activating it will automatically be covered by the upgrade guide.

If applying this configuration after already upgrading to Connectware 2.0.0, running `helm upgrade` on your Connectware installation will cause the `system-control-server` Deployment to restart. Once it is ready again, restart the `broker` StatefulSet:

{% code lineNumbers="true" %}

```bash
kubectl rollout restart broker -n ${NAMESPACE}
```

{% endcode %}

**Configuring Your Agents to Target the MQTT Broker**

Next you need to configure your agents to target the MQTT broker directly by using the `protocolMapperAgents[*].dataPlane.host` Helm value:

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      dataPlane:
        host: broker
    - name: bender-robots
      dataPlane:
        host: broker
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like TLS and mTLS settings, however, if for some reason you need to override this, use the Helm value `protocolMapperAgents[*].dataPlane.port`.

</details>

<details>

<summary><strong>1.2 - Directly Targeting Control Connection Streaming Server</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our streaming server control plane instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

**Configuring Your Agents to Target the Streaming Server**

Next you need to configure your agents to target the streaming server directly by using the `protocolMapperAgents[*].streamServer.host` Helm value. The default internal name is "nats".

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      streamServer:
        host: nats
    - name: bender-robots
      streamServer:
        host: nats
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like mTLS settings, however, if for some reason you need to override this, use the Helm value `protocolMapperAgents[*].streamServer.port`.

</details>

<details>

<summary><strong>2. Adding the CA Certificate to Your Agent</strong></summary>

You will need to have the CA certificate you want to add at hand, in this example we will assume, that you are using the `cybus_combined_ca.crt`:

**1. Copy `cybus_combined_ca.crt` from Connectware:**

{% code lineNumbers="true" %}

```bash
kubectl cp -n [your namespace] postgresql-0:/connectware_certs/cybus_combined_ca.crt cybus_combined_ca.crt
```

{% endcode %}

**2. Add `cybus_combined_ca.crt` to Agent Helm Values:**

Add the CA certificate to the Helm values of every agent in your `connectware` installation:

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      tls:
        ca:
          certChain: |
            -----BEGIN CERTIFICATE-----
            MIIFpTCCA40CFEQKP621lWyKwv/7bZGbYEoxrLGdMA0GCSqGSIb3DQEBCwUAMIGN
            [skipped lines]
            tTa2qvRLD2J9Eh1KXZ//8IhLc+lIjZsqoPTnhZ7QXZCGwLFdOTEL15mbrgmJOiz/
            lB0RUj8zolJa
            -----END CERTIFICATE-----
            -----BEGIN CERTIFICATE-----
            MIIGATCCA+mgAwIBAgIUCdqCz7EzCbalj4n7qbxZFxi3XdAwDQYJKoZIhvcNAQEL
            [skipped lines]
            ja2TMCBzQSaGyUoLs6Sm2hDD/Y5E6z56Dh7oKQPkoCWjc3+ShF4ilBO9cpyHY0dP
            CcN5u+A=
            -----END CERTIFICATE-----
    - name: bender-robots
      tls:
        ca:
          certChain: |
            -----BEGIN CERTIFICATE-----
            MIIFpTCCA40CFEQKP621lWyKwv/7bZGbYEoxrLGdMA0GCSqGSIb3DQEBCwUAMIGN
            [skipped lines]
            tTa2qvRLD2J9Eh1KXZ//8IhLc+lIjZsqoPTnhZ7QXZCGwLFdOTEL15mbrgmJOiz/
            lB0RUj8zolJa
            -----END CERTIFICATE-----
            -----BEGIN CERTIFICATE-----
            MIIGATCCA+mgAwIBAgIUCdqCz7EzCbalj4n7qbxZFxi3XdAwDQYJKoZIhvcNAQEL
            [skipped lines]
            ja2TMCBzQSaGyUoLs6Sm2hDD/Y5E6z56Dh7oKQPkoCWjc3+ShF4ilBO9cpyHY0dP
            CcN5u+A=
            -----END CERTIFICATE-----
```

{% endcode %}

Alternatively you can add it using an existing Kubernetes ConfigMap:

{% code lineNumbers="true" %}

```bash
kubectl create -n ${NAMESPACE} configmap my-connectware-ca --from-file cybus_combined_ca.crt
```

{% endcode %}

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      tls:
        ca:
          existingConfigMap: my-connectware-ca
    - name: bender-robots
      tls:
        ca:
          existingConfigMap: my-connectware-ca
```

{% endcode %}

</details>

<details>

<summary><strong>3. (Alternative) Disable TLS Certificate Validation</strong></summary>

As an alternative you can disable TLS certificate validation for agents. This of course has negative impact on security of your TLS connections, allowing for Man-in-the-middle attacks, but this may be acceptable for development instances or test installations.

{% hint style="info" %}
This is only possible with agents using the username/password authentication method. If you are using mTLS for your agents, you need to care for a proper certificate setup.
{% endhint %}

{% code lineNumbers="true" %}

```yaml
global:
  protocolMapperAgents:
    - name: welder-robots
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
    - name: bender-robots
      env:
        - name: CYBUS_TRUST_ALL_CERTS
          value: 'true'
```

{% endcode %}

</details>

<details>

<summary><strong>4. Run Helm Upgrade Again</strong></summary>

After choosing and configuring your method of choice, you can run `helm upgrade` on your `connectware` installation again.

* To upgrade Connectware, enter the following command:

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} ${REPO_NAME}/connectware --version <2.0.0> -f <values.yaml>
```

{% endcode %}

</details>

### 6. Updating Helm Values for the Connectware Agent Helm Chart

#### Why the Change?

{% hint style="info" %}
This guide explains how to update agents that use the `connectware-agent` Helm chart. If you are using agents via Docker, refer to the [Docker Guide](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker).
{% endhint %}

With Connectware 2.0.0, the default handling of certificate chain verification has changed. Previously, protocol-mapper agents required explicit configuration to validate peer certificate chains. Now, certificate chain verification is enabled and enforced by default. While you can revert to the old behavior using a configuration switch, we strongly recommend using a proper TLS certificate chain.

You now must provide the CA certificate signing Connectware's public server certificate `cybus_server.crt` to agents using the Helm value `protocolMapperAgentDefaults.tls.ca.certChain` (renamed from `protocolMapperAgentDefaults.mTLS.caChain.cert`).

Additionally, the `control-plane-broker` has been replaced with a new streaming-based control plane. Along with this change, the configuration values for both the control plane and the data plane have been redesigned. The new values are intended to be generic and resilient against future technology changes. As a result, several Helm values have been deprecated, renamed, or newly introduced.

#### What You Need to Do

<details>

<summary><strong>1. Updating the Helm Values</strong></summary>

**Obsolete Helm Values (Connectware-Agent Chart)**

Some [Helm values](/reference/helm-chart-reference) are obsolete and have been removed. Remove the following Helm values from your `values.yaml` file for the `connectware` Helm chart:

* `protocolMapperAgentDefaults.controlPlaneBrokerEnabled`
* `protocolMapperAgents[*].controlPlaneBrokerEnabled`
* `protocolMapperAgentDefaults.controlPlane`
* `protocolMapperAgents[*].controlPlane`
* `protocolMapperAgentDefaults.rpcTimeout`
* `protocolMapperAgents[*].rpcTimeout`

**Changed Helm Values (Connectware-Agent Chart)**

The following Helm values have changed. If you had specific configuration for these in the past, update the Helm values accordingly.

For some Helm values, you need to take additional steps depending on your setup. The required steps are covered in the following sections.

| **Old Helm Value**                                           | **New Helm Value**                                     | **Required Change**                               |
| ------------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------- |
| `protocolMapperAgentDefaults.mTLS.caChain.cert`              | `protocolMapperAgentDefaults.tls.ca.certChain`         | Move                                              |
| `protocolMapperAgentDefaults.mTLS.caChain.existingConfigMap` | `protocolMapperAgentDefaults.tls.ca.existingConfigMap` | Move                                              |
| `protocolMapperAgents[*].mqtt.tls`                           | `protocolMapperAgents[*].dataPlane.tls`                | Move                                              |
| `protocolMapperAgents[*].mqtt.dataHost`                      | `protocolMapperAgents[*].dataPlane.host`               | See **1.1 - Directly Targeting MQTT Broker**      |
| `protocolMapperAgents[*].mqtt.dataPort`                      | `protocolMapperAgents[*].dataPlane.port`               | See **1.1 - Directly Targeting MQTT Broker**      |
| `protocolMapperAgents[*].mqtt.controlHost`                   | `protocolMapperAgents[*].streamServer.host`            | See **1.2 - Directly Targeting Streaming Server** |
| `protocolMapperAgents[*].mqtt.controlPort`                   | `protocolMapperAgents[*].streamServer.port`            | See **1.2 - Directly Targeting Streaming Server** |

</details>

<details>

<summary><strong>1.1 - Directly Targeting MQTT Broker</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our MQTT broker instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

The major hindrance is, that the name "broker", which is used by our MQTT broker on the internal network, is not part of the `cybus_server.crt` by default. In order to connect agents with a TLS connection to this hostname, you either need to add the hostname "broker" as a Subject Alternate Name (SAN) to the certificate, or set `CYBUS_TRUST_ALL_CERTS=true` for the agent.

**Adding the Hostname to the Default Certificate**

If you are using the built-in default certificate for Connectware, you can add the hostname "broker" through the Helm value `global.ingressDNSNames`:

{% code lineNumbers="true" %}

```yaml
global:
  ingressDNSNames:
    - broker
```

{% endcode %}

It is easiest if you add this Helm value before running your upgrade to Connectware 2.0.0, since activating it will automatically be covered by the upgrade guide.

If applying this configuration after already upgrading to Connectware 2.0.0, running `helm upgrade` on your Connectware installation will cause the `system-control-server` Deployment to restart. Once it is ready again, restart the `broker` StatefulSet:

{% code lineNumbers="true" %}

```bash
kubectl rollout restart broker -n ${NAMESPACE}
```

{% endcode %}

**Configuring Your Agents to Target the MQTT Broker**

Next you need to configure your agents to target the MQTT broker directly by using the `protocolMapperAgentDefaults.dataPlane.host` Helm value:

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  dataPlane:
    host: broker
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like TLS and mTLS settings, however, if for some reason you need to override this, use the Helm value `protocolMapperAgentDefaults.dataPlane.port`.

</details>

<details>

<summary><strong>1.2 - Directly Targeting Streaming Server</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our streaming server control plane instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

**Configuring Your Agents to Target the Streaming Server**

Next you need to configure your agents to target the streaming server directly by using the `protocolMapperAgentDefaults.streamServer.host` Helm value. The default internal name is "nats".

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  streamServer:
    host: nats
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like mTLS settings, however, if for some reason you need to override this, use the Helm value `protocolMapperAgentDefaults.streamServer.port`.

</details>

<details>

<summary><strong>2. Adding the CA Certificate to Your Agent</strong></summary>

To connect a protocol-mapper agent with Connectware 2.0.0, you must either provide the agent with the valid CA certificate for the server certificate in use, or disable verification of TLS certificate validity by setting the environment variable `CYBUS_TRUST_ALL_CERTS` to `true` on the agent.

Depending on the fact if you are connecting an agent through Connectware's ingress or through the internal network, you may need to provide either `cybus_ca.crt` or `shared_yearly_ca.crt`, but if you want to skip this complexity, there is a new file called `cybus_combined_ca.crt`, which includes both CA bundles, allowing internal and external connections.

The following examples use the method of configuring all agents inside one `connectware-agent` installation through the `protocolMapperAgentDefaults` Helm value context. However, you can also configure this using the `protocolMapperAgents` Helm value context as described in [Configuration Principles for the connectware-agent Helm Chart](/cybus-helm-charts/connectware-agent-helm-chart#configuration-principles-for-the-connectware-agent-helm-chart).

You need to have the CA certificate that you want to add at hand. In this example, we assume that you are using the `cybus_combined_ca.crt`:

1. Copy `cybus_combined_ca.crt` from Connectware:

{% code lineNumbers="true" %}

```bash
kubectl cp -n [your namespace] postgresql-0:/connectware_certs/cybus_combined_ca.crt cybus_combined_ca.crt
```

{% endcode %}

2. Add the CA certificate `cybus_combined_ca.crt` to the Helm values of your `connectware-agent` installation:

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  tls:
    ca:
      certChain: |
        -----BEGIN CERTIFICATE-----
        MIIFpTCCA40CFEQKP621lWyKwv/7bZGbYEoxrLGdMA0GCSqGSIb3DQEBCwUAMIGN
        [skipped lines]
        tTa2qvRLD2J9Eh1KXZ//8IhLc+lIjZsqoPTnhZ7QXZCGwLFdOTEL15mbrgmJOiz/
        lB0RUj8zolJa
        -----END CERTIFICATE-----
        -----BEGIN CERTIFICATE-----
        MIIGATCCA+mgAwIBAgIUCdqCz7EzCbalj4n7qbxZFxi3XdAwDQYJKoZIhvcNAQEL
        [skipped lines]
        ja2TMCBzQSaGyUoLs6Sm2hDD/Y5E6z56Dh7oKQPkoCWjc3+ShF4ilBO9cpyHY0dP
        CcN5u+A=
        -----END CERTIFICATE-----
```

{% endcode %}

Alternatively, you can add it using an existing Kubernetes ConfigMap:

{% code lineNumbers="true" %}

```bash
kubectl create -n ${NAMESPACE} configmap my-connectware-ca --from-file cybus_combined_ca.crt
```

{% endcode %}

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  tls:
    ca:
      existingConfigMap: my-connectware-ca
```

{% endcode %}

</details>

<details>

<summary><strong>3. (Alternative) Disable TLS Certificate Validation</strong></summary>

You can choose to disable TLS certificate validation for agents. This is **not recommended**, as it weakens security and makes your setup vulnerable to man-in-the-middle attacks. However, it may be acceptable in non-production environments such as development or testing.

{% hint style="info" %}
This option is only available for agents using username/password authentication. If your agents use mTLS, you must configure proper certificates instead.
{% endhint %}

{% code lineNumbers="true" %}

```yaml
protocolMapperAgentDefaults:
  env:
    - name: CYBUS_TRUST_ALL_CERTS
      value: 'true'
```

{% endcode %}

</details>

### 7. Upgrading Agents for the Connectware Agent Helm Chart

#### What You Need to Do

{% hint style="info" %}
This guide explains how to update agents which use the `connectware-agent` Helm chart. If you are using agents via Docker, follow the [Docker upgrade guide](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker) for this part.
{% endhint %}

* To upgrade your agents installed via the `connectware-agent` Helm chart, see [Upgrading the connectware-agent Helm Chart](/data-flows/agents/agents-in-kubernetes/upgrading-the-connectware-agent-helm-chart).

### 8. Reinstalling Services

#### Why the Change?

With Connectware 2.0.0, your services and resources are no longer stored on the service-manager volume, but inside the PostgreSQL database.

#### What You Need to Do

<details>

<summary><strong>Reinstalling Your Services</strong></summary>

After completing the upgrade, you must reinstall all previously used services. You can do this using your preferred method:

* Via the Admin UI, see [Installing Services](/data-flows/services/managing/installing).
* Automatically through a CI pipeline.

Additionally, there have been changes to the relationships between services. Understanding how these interdependencies behave at runtime is crucial for correct deployment and maintenance.

**Install parent services first (recommended)**: If the service depends on another service (parent/child relationship), install the parent service first. This ensures:

* Service relations are created during installation.
* Each service can be installed with `targetState=enabled`.

**Install child services first (alternative)**: It is possible to install the dependent (child) service first, but this comes with limitations:

* Service relations are only established when the service is enabled.
* The dependent (child) service can **only** be installed with `targetState=disabled`.

For more details, see [Service Dependency Behavior](/data-flows/services/inter-service-referencing#service-dependency-behavior) and [targetState](/data-flows/service-commissioning-files/resources/cybus-endpoint#targetstate).

</details>

## Feature-Specific Upgrade Steps

Only follow these if you use the related features, so they continue working after the upgrade.

### 1. Permissions and Roles

#### Why the Change?

Permissions allow administrators to define who can access what resources and what actions they can perform. Each permission represents a specific access right to a resource.

Connectware 2.0.0 introduces new and permissions. Because of this, custom roles or specific permissions you have set up might not allow users to do everything they could before the 2.0.0 upgrade.

#### What You Need To Do

<details>

<summary><strong>Verifying Permissions</strong></summary>

* Check the permissions of your users. Compare them with the default roles in Connectware 2.0.0 and make any updates needed so your users can continue working without interruptions.

For more information on managing permissions, see [Permissions](/access/user-management/permissions).

</details>

### 2. Custom Connectors

#### Why the Change?

Connectware has evolved its architecture, removing dependencies like VRPC and improving protocol handling. To ensure compatibility, you must update your custom connector implementations.

#### What You Need To Do

If you are using [custom connectors](/connectors/custom-connectors), follow these steps to make your custom connector compatible with Connectware 2.0.0.

<details>

<summary><strong>1. Remove VRPC</strong></summary>

VRPC is no longer supported in the custom connector environment.

* Remove all VRPC references in the custom connector code. This includes the import and any usage of `VrpcAdapter`:

**Example**

{% code lineNumbers="true" %}

```javascript
// const { VrpcAdapter } = require('vrpc') <- REMOVE THIS
const Connection = require('./FoobarConnection')
const Endpoint = require('./FoobarEndpoint')

// VrpcAdapter.register(Endpoint, { schema: Endpoint.getSchema() }) <- REMOVE THIS
// VrpcAdapter.register(Connection, { schema: Connection.getSchema() }) <- REMOVE THIS
```

{% endcode %}

</details>

<details>

<summary><strong>2. Follow the Directory Naming Conventions</strong></summary>

* When defining the Dockerfile, ensure that the destination path for the copied source files ends in a protocol-specific directory name written entirely in lowercase.

**Example**

{% code lineNumbers="true" %}

```yaml
# protocol directory must be lowercase
COPY ./src ./src/protocols/foobar
```

{% endcode %}

</details>

<details>

<summary><strong>3. Follow the Schema Naming Conventions</strong></summary>

* The schema `$id` must match the file name (without the `.json`).
* The schema must start with a capital letter, like `Foobar`.

**Example**

* In `FoobarConnection.json`, the class must be like:

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarConnection"
  ...
}
```

{% endcode %}

* In `FoobarEndpoint.json`, the class must be like:

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarEndpoint"
  ...
}
```

{% endcode %}

</details>

<details>

<summary><strong>4. Schema Versioning</strong></summary>

Schemas support versioning through the additional `version` property, which must be a positive integer greater than zero. If this property is omitted, the default value is `1`.

Versioning ensures that only the latest version of a schema is considered active and valid. This means that even though all custom connector instances should run the same version of schemas, the latest version will overwrite any previous version in the CW control plane.

**Example**

* `FoobarConnection.json` supporting versioning.

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarConnection",
  "version": 3
  ...
}
```

{% endcode %}

</details>

<details>

<summary><strong>5. Follow the Source Directory Naming Conventions</strong></summary>

Follow the case-sensitive naming conventions based on the protocol name.

* File names must start with an uppercase protocol name (e.g., `Foobar`).
* Connection and endpoint suffixes are mandatory.
* JS files define classes.
* JSON files define schemas.

**Example**

{% code lineNumbers="true" %}

```yaml
src/
├── FoobarConnection.js
├── FoobarConnection.json
├── FoobarEndpoint.js
└── FoobarEndpoint.json
```

{% endcode %}

</details>

<details>

<summary><strong>6. Follow the Class Naming Conventions</strong></summary>

* The class name must match the file name, excluding the `.js` extension.
* The class name must start with a capital letter, such as `Foobar`.

**Example**

* In `FoobarConnection.js`, the class must be:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection extends Connection { ... }
```

{% endcode %}

* In `FoobarEndpoint.js`, the class must be:

{% code lineNumbers="true" %}

```javascript
class FoobarEndpoint extends Endpoint { ... }
```

{% endcode %}

</details>

<details>

<summary><strong>7. Class Constructors</strong></summary>

Unless you need a specific constructor, there is no need to specify one because it is inherited from the parent class. However, if you need to implement a custom constructor for the `Connection` or `Endpoint` classes, preserve the following format:

* In `FoobarConnection.js`, the class constructor must be like:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection extends Connection {
---
constructor (params) {
super(params)
---
// custom code
---
}
---
}
```

{% endcode %}

* In `FoobarEndpoint.js`, the class constructor must be like:

{% code lineNumbers="true" %}

```javascript
class FoobarEndpoint extends Endpoint {
---
constructor (params, dataPlaneConnectionInstance, parentConnectionInstance) {
super(params, dataPlaneConnectionInstance, parentConnectionInstance)
---
// custom code
---
}
---
}
```

{% endcode %}

</details>

<details>

<summary><strong>8. Do not Set the _topic Property Manually</strong></summary>

The `_topic` property is now handled automatically. Manually assigning it will cause errors.

The following code is invalid and must be removed since topics are now built internally.

{% code lineNumbers="true" %}

```javascript
// this is invalid, remove it
this._topic = 'this/is/a/topic'
```

{% endcode %}

</details>

<details>

<summary><strong>9. ES Modules Not Supported</strong></summary>

The standard JavaScript environment of custom connectors is based on CommonJS modules. ES modules are not supported.

</details>

<details>

<summary><strong>10. TypeScript Configuration</strong></summary>

TypeScript is not officially supported in development workflows. However, if you want to use TypeScript and compile it to JavaScript, make sure to configure your `tsconfig.json` file as follows:

{% code lineNumbers="true" %}

```json
{
  "compilerOptions": {
    ....
    "target": "es2022",    /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "lib": ["es6"],        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    "module": "commonjs",  /* Specify what module code is generated. */
    ....
  },
  "include": ["src/**/*.ts", "src/**/*.json", "src/**/*.js", "src/**/*.d.ts", "test/**/*"]
}
```

{% endcode %}

Additionally, the compiled JavaScript output must include an `exports.default` assignment and the exported class itself. This ensures interoperability with our CommonJS-based module system. The compiled `.js` file should result in:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection { ... }
exports.default = FoobarConnection;
```

{% endcode %}

</details>

### 3. Systemstate Protocol

#### Why the Change?

To improve performance and reduce unnecessary messaging load, the Systemstate protocol no longer supports whole-service tracking or redundant status events. This simplifies agent responsibilities and avoids misleading lifecycle signals.

#### What You Need to Do

If you are using the [Systemstate protocol](/connectors/enterprise-connectors/systemstate), do the following:

<details>

<summary><strong>1. Stop Tracking Whole Services</strong></summary>

* Tracking the entire service object is no longer allowed. You must update your connector configuration to track individual resources only (like specific endpoints or connections).

**Example**

{% code lineNumbers="true" %}

```yaml
# Before (no longer supported)
serviceEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Systemstate
    connection: !ref systemStateConnection
    subscribe:
      resourceId: !sub '${Cybus::ServiceId}'
```

{% endcode %}

</details>

<details>

<summary><strong>2. Update Event Handling Logic</strong></summary>

The following status events have been removed from Systemstate. If your implementation depends on them (e.g., for health monitoring or automation), you must refactor that logic:

* `subscribed`/`unsubscribed`
* `online`/`offline`

</details>

### 4. Log Monitoring

#### Why the Change?

With version 2.0.0, several log messages have been corrected to fix spelling mistakes. These changes may affect existing log monitoring configurations.

#### What You Need to Do

<details>

<summary><strong>Updating Your Log Monitoring</strong></summary>

If you rely on log monitoring, review whether your setup references any of the updated log messages and adjust accordingly.

| Type          | Log Level | Original (with typo)                                                                                | Corrected line                                                                                      |
| ------------- | --------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Log message   | info      | MS Entra Login was succesful, redirecting to                                                        | MS Entra Login was successful, redirecting to                                                       |
| Log message   | debug     | DELETE /:id/tokens sucess for user: '\<req.params.id>'                                              | DELETE /:id/tokens success for user: '\<req.params.id>'                                             |
| Error message |           | Views are found, the restore implenetation do not support views!                                    | Views are found, the restore implementation do not support views!                                   |
| Error message |           | query paramter error is not a valid HTTP error code (\<req.query.code>)                             | query parameter error is not a valid HTTP error code (\<req.query.code>)                            |
| Log message   | debug     | Cleared persistance of:                                                                             | Cleared persistence of:                                                                             |
| Error message | warn      | HttpNode is configured with method 'GET' but operation 'serverRecieves' (instead of serverProvides) | HttpNode is configured with method 'GET' but operation 'serverReceives' (instead of serverProvides) |
| Log message   |           | Error when trying to recieve OPC-UA Method details from nodeId : \<err.message>                     | Error when trying to receive OPC-UA Method details from nodeId : \<err.message>                     |
| Log message   | warn      | tried to pass the value as an INT64 and found no matching convertion                                | tried to pass the value as an INT64 and found no matching conversion                                |
| Log message   | warn      | tried to pass the value as an UINT64 and found no matching convertion                               | tried to pass the value as an UINT64 and found no matching conversion                               |
| Log message   | debug     | Sucessfully subscribed to topic: \<mqttOpts.topic>.                                                 | Successfully subscribed to topic: \<mqttOpts.topic>.                                                |
| Log message   | error     | error occured during shutting down the server                                                       | error occurred during shutting down the server                                                      |
| Log message   | error     | expected payload convertion to fail because given payload was not a JSON notation, but 'err == nil' | expected payload conversion to fail because given payload was not a JSON notation, but 'err == nil' |

</details>

### 5. Heidenhain Agents (Windows)

#### Why the Change?

For Connectware 2.0.0, the Heidenhain protocol has been updated.

#### What You Need to Do

<details>

<summary><strong>Installing the Heidenhain Agent</strong></summary>

You must upgrade the Windows-based [Cybus Heidenhain Agent](/connectors/shop-floor-connectors/heidenhain-dnc) to work with Connectware 2.0.0.

1. Uninstall the existing Heidenhain agent installation from your Windows system.
2. Install the updated Heidenhain agent. You can find the download link at [Heidenhain DNC](/connectors/shop-floor-connectors/heidenhain-dnc).

</details>

### 6. Auto-Generated MQTT Topics of Resources

#### Why the Change?

With Connectware 2.0.0, auto-generated MQTT topics no longer include resource-specific properties. This makes the topic generation more unified and explicit. You must update any service commissioning file that hardcodes those old auto-generated topics.

**Example of old behavior**

Some auto-generated topics contained property-specific parts:

* S7: `services/myService/pressure/address:DB1,REAL6`
* Modbus: `services/myService/current/fc:3/address:7`
* HTTP: `services/myService/myEndpoint/get[object Object]`

These paths might have been referenced inside `Cybus::Mapping` resources. Using auto-generated topics inside `Cybus::Mapping` is **not** recommended. Instead, use references via `!ref, “Reference Method”`.

#### What You Need to Do

<details>

<summary><strong>Updating Auto-Generated Topic References</strong></summary>

Auto-generated topics no longer include resource-specific properties. They always follow:

{% code lineNumbers="true" %}

```bash
<Cybus::MqttRoot>/<serviceId>/<resourceName>
```

{% endcode %}

**Example of new behavior**

* S7: `services/myService/pressure`
* Modbus: `services/myService/current`
* HTTP: `services/myService/myEndpoint`

**Procedure**

1. Scan your service commissioning files for any usage of auto-generated topics.
2. Adapt those references by replacing direct topic strings with `!ref` references.

For more details, see [Reference Method (!ref)](/data-flows/service-commissioning-files/parameters#reference-method-ref).

</details>

### 7. Auto-Generated MQTT Users

#### Why the Change?

Before 2.0.0, Connectware created a hidden MQTT user for every installed service. These auto-generated users were only used when the service commissioning file explicitly referenced the pseudo parameter [Cybus::MqttUser](/data-flows/service-commissioning-files/parameters#cybus-mqttuser).

With Connectware 2.0.0, hidden users and groups are created only when the service commissioning file uses the `Cybus::MqttUser` pseudo parameter. This reduces unused accounts and makes credential usage explicit.

#### What You Need to Do

<details>

<summary><strong>Verify Your Service Commissioning Files</strong></summary>

If you are using auto-generated MQTT users outside of services (e.g., scripts, dashboards, or other non-commissioning references), migrate to explicit identities:

* Create dedicated users with the required roles/permissions. See [User Management](/access/user-management).
* Update your external systems to use the new explicit credentials.

</details>


# Upgrading Connectware to 1.11.0 (Kubernetes)

Follow the step-by-step procedure to upgrade a Kubernetes-based Connectware installation to version 1.11.0.

{% hint style="danger" %}
We have streamlined the upgrade procedure for version 1.11.0 with version 2.0.0. If you are on 1.7.0 or above, skip 1.11.0 and upgrade directly to 2.0.0. For more information, see [Upgrading Connectware to 2.0.0 (Kubernetes)](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes).
{% endhint %}


# Upgrading Connectware to 1.7.0 (Kubernetes)

How to upgrade Connectware to version 1.7.0 on Kubernetes.

Connectware 1.7.0 affects the backward compatibility of the Connectware broker. Older broker data volumes are not compatible with brokers of Connectware 1.7.0 and newer. Upgrading to Connectware 1.7.0 requires additional upgrade procedures.

Additionally, multi-factor authentication (MFA) is now controlled via a dedicated configuration switch.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Important Notes

This upgrade will delete all persisted data of the Connectware broker. This includes client sessions, subscriptions, and retained data. If your configuration relies on any type of data persisted by the broker, make sure to properly initialize your applications after the upgrade.

If you rely on persisted data, create a backup or snapshot of the broker data volumes. This allows you to roll back in case of complications.

## Upgrading Procedure

Here are the complete instructions for upgrading your Connectware installation to version 1.7.0.

1. Scale down the broker cluster in Kubernetes. Set the number of broker nodes and control-plane-broker nodes to zero and wait until all broker pods have been successfully removed.
2. Delete the broker and control-plane-broker data volumes. Log volumes do not have to be deleted.
3. If you are using multi-factor authentication (MFA), set the Helm value `global.authentication.mfa.enabled` to `true`.
4. Apply the updated Helm chart of Connectware version 1.7.0 For more information, see [Installing Connectware on Kubernetes](/deployment/installing-connectware/on-kubernetes).

Once all pods are up and running again and no new deviations appear in Connectware, the upgrade has been successful.


# Upgrading Connectware (Docker)

Upgrade Connectware on Docker.

{% hint style="warning" %}

## Check your upgrade path

Some Connectware versions require intermediate upgrade steps. Before you upgrade, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine the upgrade path for your current version.
{% endhint %}

{% hint style="warning" %}

## Downgrading to previous Connectware versions is not supported

{% endhint %}

## Upgrading Connectware to a New Version

* To upgrade Connectware to a newer version, get the latest installer script by following the steps in the [Prepare Installer Script](/deployment/installing-connectware/on-docker#preparing-the-installer-script) chapter. When running the update, select your current Connectware installation directory.

The update will automatically preserve your existing configuration, including your license key and network settings. If you're prompted to enter a license key during the update, this usually means you have selected the wrong installation directory. In this case, cancel the update and verify you have chosen the correct path.

{% hint style="warning" %}
If you originally installed Connectware using sudo privileges, make sure to use `sudo` when running the update as well.
{% endhint %}

## Upgrading Connectware in Silent Mode

The installer supports an automated deployment mode that requires no manual intervention. You can activate this by using either `-s` or `--silent`, and `-d`(directory) when [running the installation script](#running-the-installer-script).

If you need to customize your installation, the script offers several configuration options. Run the installer with `--help` to view all available parameters.

**Example**

{% code lineNumbers="true" %}

```yaml
./connectware-online-installer.sh -s -d <PATH/TO/YOUR/CONNECTWARE/FOLDER>
```

{% endcode %}


# Upgrading Connectware to 2.4.0 (Docker)

How to upgrade Connectware to version 2.4.0 on Docker.

Connectware 2.4.0 adds the `caFile` property to the OPC UA Server, refreshes the Admin UI, and updates Node.js versions across Connectware services. For a complete list of changes, see the [2.4.0 changelog](https://docs.cybus.io/deployment/upgrading-connectware/on-docker/pages/WQsCXfI86SHyPaoQB37K#connectware-2.4.0).

{% hint style="warning" %}

## Check your upgrade path

The steps in this guide apply to specific setups. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which upgrades and steps apply to your installation.
{% endhint %}

{% stepper %}
{% step %}

## Upgrading Connectware to 2.4.0

Follow the instructions in [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker) to upgrade to version 2.4.0.
{% endstep %}

{% step %}

## OPC UA Server with Custom PKI: Add caFile

This step applies if you are running OPC UA Server services with a **custom PKI** — that is, you have configured your own `certificateFile` and `privateKeyFile` signed by your organization's CA. If you do not use the OPC UA Server, skip this step.

Previously, the only way to provide your CA certificate to the OPC UA Server was to manually place it in `/app/.config/node-opcua-default-nodejs` inside the container. Connectware 2.4.0 introduces the `caFile` property as the recommended way to provide the CA certificate to the OPC UA Server.

To migrate, add `caFile` to the `properties` of your OPC UA Server resource in each affected service commissioning file, pointing to the path of your CA certificate inside the container:

{% code lineNumbers="true" %}

```yaml
resources:
  opcuaServer:
    type: Cybus::Server::Opcua
    properties:
      protocol: OpcuaServer
      certificateFile: /path/to/server.crt
      privateKeyFile: /path/to/server.key
      caFile: /path/to/ca.crt
```

{% endcode %}

For more information, see [CA Certificate](/connectors/servers/opc-ua-server#ca-certificate).
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.1.0 (Docker)

How to upgrade Connectware to version 2.1.0 on Docker.

Connectware 2.1.0 introduces support for the Siemens SIMATIC S7+ protocol and OPC UA complex data types. It also reintroduces service-level tracking for the Systemstate protocol, offering improved performance. Furthermore, it provides significant enhancements to resource deviation tracking and OPC UA reliability. For a complete list of changes, see the [2.1.0 changelog](https://docs.cybus.io/deployment/upgrading-connectware/on-docker/pages/WQsCXfI86SHyPaoQB37K#what-has-changed-in-2.1.0).

{% hint style="warning" %}

## Check your upgrade path

The steps in this guide apply to specific setups. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which upgrades and steps apply to your installation.
{% endhint %}

{% stepper %}
{% step %}

## Upgrading Connectware to 2.1.0

Follow the instructions in [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker) to upgrade to version 2.1.0.
{% endstep %}

{% step %}

## Optional: Cleaning Up Disk Space After Upgrading to 2.1.0

As part of the Systemstate improvements in 2.1.0, the `resourceStates` NATS bucket is no longer used. If you want to save disk space, you can delete this bucket.

* To clean up disk space, run the following:

{% code lineNumbers="true" %}

```bash
CW_SCS_CONTAINER=$(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=system-control-server")
docker run --rm -it \
-v $(docker inspect ${CW_SCS_CONTAINER}  | jq -r '.[].Mounts[] | select(.Destination == "/connectware_certs") | .Name'):/connectware_certs \
--network=container:${CW_SCS_CONTAINER} \
--pid=container:${CW_SCS_CONTAINER} \
registry.cybus.io/cybus/connectware-toolkit:1.4.0 -c 'source /connectware_certs/env-1.0.sh && nats -s nats:4222 --user cybus_auth --password $CYBUS_NATS_AUTH_PASSWORD --tlscert=/connectware_certs/cybus_client.crt --tlskey=/connectware_certs/cybus_client.key --tlsca=/connectware_certs/cybus_combined_ca.crt kv del resourceStates -f'
```

{% endcode %}
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.0.5 (Docker)

How to upgrade Connectware to version 2.0.5 on Docker.

Connectware 2.0.5 brings significant improvements to OPC UA reliability and CybusMQ performance, reducing message loss and improving system stability under load. For more information, see [What has changed in 2.0.5](/changelog#what-has-changed-in-205).

This upgrade requires you to delete the data volumes that store the metadata of CybusMQ.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Important Notes

This upgrade will delete all persisted data of the Connectware broker. This includes client sessions, subscriptions, and retained data. If your configuration relies on any type of data persisted by the broker, make sure to properly initialize your applications after the upgrade.

If you rely on persisted data, create a backup or snapshot of the broker data volumes. This allows you to roll back in case of complications.

## Upgrading Procedure

{% hint style="warning" %}
If your installation is older than 2.0.2, first complete the [upgrade to 2.0.2](/deployment/upgrading-connectware/on-docker/to-2-0-2-on-docker) before upgrading to 2.0.5.
{% endhint %}

1. Delete the broker data volume of Connectware. For more information, see [Deleting Broker Data Volumes on Docker Compose](/broker/cybusmq/operations/deleting-broker-data-volumes#deleting-broker-data-volumes-on-docker-compose).
2. Download and install Connectware 2.0.5. For more information, see [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker).


# Upgrading Connectware to 2.0.2 (Docker)

How to upgrade Connectware to version 2.0.2 on Docker.

Connectware 2.0.2 introduces new configuration options for HTTP connections.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Upgrading Procedure

1. Upgrade Connectware to 2.0.2 by following the instructions in [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker).
2. Apply the new HTTP connection options to existing services. To do so, [disable](/data-flows/services/managing/disabling) and re-[enable](/data-flows/services/managing/enabling) each affected service after upgrading.

For more information about the new HTTP connection options, see [What has changed in 2.0.2](https://docs.cybus.io/deployment/upgrading-connectware/on-docker/pages/WQsCXfI86SHyPaoQB37K#what-has-changed-in-2.0.2).


# Upgrading Connectware to 2.0.1 (Docker)

How to upgrade Connectware to version 2.0.1 on Docker.

Connectware 2.0.1 introduces enhancements to the [Data Explorer](/monitoring/data-explorer).

{% hint style="warning" %}
If you are using services configured with `CYBUS_MQTT_ROOT`, you must run a migration script after installing Connectware 2.0.1 to ensure full Data Explorer compatibility.

If you are not using `CYBUS_MQTT_ROOT`, you can [upgrade](#upgrading-procedure) as usual — just note the additional [hardware requirements](#hardware-requirements).
{% endhint %}

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Hardware Requirements

Connectware 2.0.1 adds a new microservice for MQTT topic exploration. As a result, Connectware requires the following **additional resources**:

* 200m CPU (0.2 CPU)
* 750 MiB of memory

{% hint style="warning" %}
As with any deployment, we recommend monitoring system performance and adjusting resources as needed.
{% endhint %}

## Upgrading Procedure

{% hint style="warning" %}
If your installation is older than 2.0.0, first complete the [upgrade to 2.0.0](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker) before upgrading to 2.0.1.
{% endhint %}

{% stepper %}
{% step %}

### Upgrading Connectware to 2.0.1

1. To stop Connectware, go to the Connectware installation directory (default: `/opt/connectware`) and run the following command:

{% code lineNumbers="true" %}

```bash
docker compose down
```

{% endcode %}

2. Download and install Connectware 2.0.1. For more information, see [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker).
3. Start Connectware with the following command:

{% code lineNumbers="true" %}

```bash
docker compose up -d
```

{% endcode %}

**Result:** Connectware is upgraded to 2.0.1.

{% hint style="warning" %}
If you are using services configured with `CYBUS_MQTT_ROOT`, continue with [step 2](#migrating-services-with-cybus_mqtt_root-configuration).

If you are not using `CYBUS_MQTT_ROOT`, your Connectware upgrade to 2.0.1 is complete. Just note the additional [hardware requirements](#hardware-requirements).
{% endhint %}
{% endstep %}

{% step %}

### Migrating Services with `CYBUS_MQTT_ROOT` Configuration

If you are using services configured with `CYBUS_MQTT_ROOT`, you must run a migration script after installing Connectware 2.0.1 to ensure full Data Explorer compatibility.

1. Ensure that only a single instance of Connectware is running in this Docker installation. If you run multiple installations on the same machine, identify the system-control-server container belonging to this installation manually using `docker ps` and use its name as `CW_SCS_CONTAINER` in the next step.
2. Run the migration script. This is required if you have services using `CYBUS_MQTT_ROOT`.

{% code lineNumbers="true" %}

```bash
CW_SCS_CONTAINER=$(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=system-control-server")
docker run --rm -it \
-v $(docker inspect ${CW_SCS_CONTAINER}  | jq -r '.[].Mounts[] | select(.Destination == "/connectware_certs") | .Name'):/connectware_certs \
--network=container:${CW_SCS_CONTAINER} \
--pid=container:${CW_SCS_CONTAINER} \
registry.cybus.io/cybus/connectware-toolkit:1.3.0 -c 'cw-db-migrate-2_0_1'
```

{% endcode %}

3. Verify that the script ran without errors.
4. Ensure that only a single instance of Connectware is running in this Docker installation. If you run multiple installations on the same machine, identify the `topic-explorer` container that belongs to this installation manually using `docker ps` and use its name as `CW_TE_CONTAINER` in the next step.
5. Restart the `topic-explorer` container:

{% code lineNumbers="true" %}

```bash
CW_TE_CONTAINER=$(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=topic-explorer")
docker restart $CW_TE_CONTAINER
```

{% endcode %}

**Result:** The migration script updates the database with new column values. You do not need to reinstall your services.
{% endstep %}
{% endstepper %}


# Upgrading Connectware to 2.0.0 (Docker)

How to upgrade Connectware to version 2.0.0 on Docker.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Before You Begin

Upgrading to Connectware 2.0.0 introduces significant improvements in performance, scalability, and reliability. However, these changes also come with updated requirements for versions, networking, hardware, and storage.

This guide outlines the prerequisites and known limitations you must consider to ensure a smooth and successful upgrade.

{% hint style="warning" %}
Before starting the upgrade, read the entire guide. Some steps require developer work or preparation before the upgrade process begins.
{% endhint %}

{% hint style="warning" %}
Upgrading to Connectware 2.0.0 requires reinstalling all services. The main benefit of upgrading instead of performing a fresh installation is that it preserves the user database, including Multi-Factor Authentication. If you do not rely heavily on these features, a fresh installation may be the better option.

Even with a fresh installation, you will still need to follow this upgrade guide to update configuration parameters and adapt to the behavioral changes introduced in Connectware 2.0.0. However, you can skip the multi-step upgrade process itself.

If you are considering a fresh installation, we strongly recommend consulting with the Cybus Customer Support beforehand to confirm whether this is the right approach for your setup.
{% endhint %}

### Connectware Version Requirements

To be able to upgrade to Connectware 2.0.0, your Connectware version must be 1.7.0 or above.

If your Connectware installation is below 1.7.0, make sure that you have followed [Upgrading Connectware to 1.7.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-1-7-0-on-docker) before upgrading to 2.0.0.

### Network Requirements

#### Why the Change?

With Connectware 2.0.0, some internal components have been updated to improve communication and performance. As a result, the network configuration has changed:

* **Added**: TCP/4222 and TCP/4223
* **Removed**: TCP/1884 and TCP/8884

#### What You Need to Do

<details>

<summary><strong>Updating the Network Ports</strong></summary>

Verify that your firewalls and security rules are updated to allow the new ports (TCP/4222 and TCP/4223) and to remove dependencies on the deprecated ones (TCP/1884 and TCP/8884).

This ensures uninterrupted connectivity between your agents and Connectware.

</details>

### Hardware Requirements

#### Why the Change?

Connectware 2.0.0 makes increased use of its PostgreSQL database and adds some components. When planning this upgrade, ensure your infrastructure can accommodate the enhanced resource requirements. This upgrade requires additional computing power.

#### What You Need to Do

<details>

<summary><strong>Updating the Hardware Setup</strong></summary>

We recommend adding the following resources to your hardware setup:

* **7** CPU cores
* **6** GB of memory
* **20** Gi of storage

However, these are general guidelines. Check what your specific system needs and make adjustments accordingly.

</details>

### Storage Requirements

#### Why the Change?

We have added two new components to Connectware:

* A streaming server called NATS
* A service called resource-status-tracking

Alongside other improvements, these additions enable Connectware to scale effectively for much larger deployments.

### Known Limitations

1. **Adding Certificates Through Admin UI Not Supported**

* You cannot add certificates to Connectware's CA bundle via the Admin UI.
* Instead, modify the `cybus_ca.crt` file directly on the `certs` volume.

2. **Backup via Admin UI Not Supported**

* The backup functionality through Admin UI is not supported.
* Instead, create backups of the database by running a `pg_dump` command on the postgresql container.
* When running the command, make sure that only a single Connectware instance is running. Otherwise, select the container manually.

{% code title="Example" lineNumbers="true" %}

```bash
docker exec \
    $(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=postgresql") \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}

## Upgrade Procedure

Follow this procedure to upgrade your Connectware installation to version 2.0.0. The steps are divided into two parts:

* **Mandatory Upgrade Steps**: Required for all installations to ensure a smooth and stable upgrade.
* **Feature-Specific Upgrade Steps**: Only needed if you use certain features, so they remain compatible with Connectware 2.0.0.

Expand the following sections for an overview of all upgrade steps.

<details>

<summary><strong>Mandatory Upgrade Steps</strong></summary>

These steps apply to every Connectware installation upgrading to Connectware 2.0.0. For a detailed guide, see [Mandatory Upgrade Steps](#mandatory-upgrade-steps).

{% hint style="warning" %}
Depending on your setup, you may also need to perform additional Conditional Steps.
{% endhint %}

1. [**TLS Changes**](#id-1.-tls-changes): Default behavior on certificate validation has been adjusted.
2. [**Update .env Configuration**](#id-2.-update-.env-configuration): Remove any obsolete environment variables and update the configuration for changed or new environment variables as necessary.
3. [**Preparing the Connectware Upgrade**](#id-3.-preparing-the-connectware-upgrade).
4. [**Upgrading to Connectware 2.0.0**](#id-4.-upgrading-to-connectware-2.0.0): Download and install Connectware 2.0.0.
5. [**Updating Agent Configuration**](#id-6.-updating-agent-configuration): Update your agent configuration to comply with the updated configuration.
6. [**Upgrading Agents**](#id-7.-upgrading-agents): Upgrade your agents.
7. [**Reinstalling Services**](#id-8.-reinstalling-services): This upgrade changes where your services are stored. You will need to reinstall any services after the upgrade.

</details>

<details>

<summary><strong>Feature-Specific Upgrade Steps</strong></summary>

Only follow these if you use the related features, so they continue working after the upgrade.

1. [**Roles and Permissions**](#id-1.-permissions-and-roles): New permissions were added to Connectware. Verify your custom roles, if they require updates.
2. [**Custom Connectors**](#id-2.-custom-connectors): Update your customer connector configurations to meet new requirements.
3. [**Systemstate Protocol**](#id-3.-systemstate-protocol): Update your Systemstate protocol configurations to meet new requirements.
4. [**Log Monitoring**](#id-4.-log-monitoring): Some logging strings are changed. If you use log monitoring, you may need to update it.
5. [**Heidenhain Agents**](#id-5.-heidenhain-agents-windows): Upgrade your Heidenhain agents.
6. [**Auto-Generated MQTT Topics of Resources**](#id-6.-auto-generated-mqtt-topics-of-resources): Topic generation no longer includes resource-specific properties. Update your service commissioning files if you relied on old patterns.
7. [**Auto-Generated MQTT Users**](#id-7.-auto-generated-mqtt-users): The behavior of how MQTT users are auto-generated has changed. You may need to update your service commissioning file if you relied on auto-generated MQTT users.

</details>

## Mandatory Upgrade Steps

These steps are required to upgrade your Connectware installation to Connectware 2.0.0.

### 1. TLS Changes

#### Why the Change?

To enhance security by default, Connectware agents now verify TLS certificate chains automatically. This ensures that all components communicate over a valid trust chain, while still giving you the option to keep the old behavior by explicitly disabling TLS verification.

#### Key Changes

<details>

<summary><strong>1. Introducing the cybus_combined_ca.crt</strong></summary>

Connectware maintains two separate CA chains:

* External certificates validated by `cybus_ca.crt`.
* Internal certificates validated by `shared_yearly_ca.crt`.

Which CA an agent requires depends on the hostname through which it connects to Connectware. For example, through the Connectware ingress, or directly to the Control Streaming Server (NATS) through the internal network.

To simplify configuration, we introduced `cybus_combined_ca.crt`, a bundle containing both chains, so agents can use a single file without needing to distinguish between internal and external CA certificates.

</details>

<details>

<summary><strong>2. Certificate Chain Verification in Agents</strong></summary>

Agents now enforce TLS chain validation by default. Each agent requires access to `cybus_combined_ca.crt`, available on the `certs` volume.

* To revert to the previous behavior (skipping verification), set the environment variable `CYBUS_TRUST_ALL_CERTS` to `true`. Note that it has been renamed from `TRUST_ALL_CERTS`.

</details>

<details>

<summary><strong>3. Configuring Certificate Hostnames</strong></summary>

The default Connectware-generated CA includes the hostnames `localhost` and `connectware`.

* To add more hostnames, configure a comma separated list in the environment variable `CYBUS_INGRESS_DNS_NAMES`.
* You will also be prompted for these names as part of running the Connectware installer.

</details>

<details>

<summary><strong>4. Renewal of Certificate Chains</strong></summary>

With 2.0.0, the internal CA chain is replaced:

* Certificate Authority renamed from `CybusCA` to `CybusInternalCA`.
* The hostname `nats` is added as a Subject Alternate Name (SAN) to `shared_yearly_server.crt`.

The built-in default external CA certificate chain is also replaced.

* The hostname `connectware` is added as a SAN to `cybus_server.crt`.

If you rely on monitoring, custom setups, or modified certificates, adapt your configuration accordingly.

</details>

<details>

<summary><strong>5. Replacing CA Certificate Chain</strong></summary>

To replace Connectware’s default external chain with your enterprise-managed CA:

* Replace `cybus_ca.crt` with your enterprise CA certificate.
* Ensure `cybus_server.crt` and `cybus_server.key` form a valid key pair, signed by the CA in `cybus_ca.crt`.

Do not replace the internal CA (`shared_yearly_ca.crt`).

After replacement:

1. Restart the `system-control-server` deployment to rebuild and synchronize the combined CA bundle (`cybus_combined_ca.crt`). Ensure that only a single Connectware instance is running.

{% code lineNumbers="true" %}

```bash
docker restart $(docker container ls -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=system-control-server" -q)
```

{% endcode %}

2. Restart all Connectware services.

</details>

### 2. Update .env Configuration

#### Why the Change?

Some changes to Connectware require updating your environment variable configuration. Adapt your `.env` file accordingly.

* All parameters to tune the inter-service communication have been removed.

#### Obsolete Environment Variables Values

<details>

<summary><strong>Removing Obsolete Environment Variables</strong></summary>

Some [environment variables](/reference/environment-variables#docker-compose) are obsolete and have been removed. Remove the following environment variables from your .env file for Connectware:

* `CYBUS_CM_RPC_TIMEOUT`
* `CYBUS_ADMIN_WEB_APP_VRPC_TIMEOUT`
* `CYBUS_PM_RPC_TIMEOUT`
* `CYBUS_SM_RPC_TIMEOUT`
* `CYBUS_SCS_RPC_TIMEOUT`
* `CYBUS_USE_SERVICES_GRAPH`

</details>

#### New Environment Variables

<details>

<summary><strong>1. Ingress DNS Name Configuration</strong></summary>

With the changes TLS behavior in Connectware, it has become essential to add the DNS names under which Connectware is addressed, for example by agents.

If you are replacing Connectware's default PKI, you can, and likely have managed this yourself by providing a valid `cybus_server.crt` containing all Subject Alternate Names (SANs) used within your setup.

If you are using Connectware's default PKI, you can use the new environment variable `CYBUS_INGRESS_DNS_NAMES`, which is a comma separated list of names that will be added to the default `cybus_server.crt`.

#### Hostname Formats

You can include multiple hostnames in the list. The certificate will include all specified names in its SAN section.

The configuration accepts various hostname formats:

* Wildcards (e.g., `*.company.io`)
* Subdomains (e.g., `connectware.company.io`)
* Custom hostnames (e.g., `localhost`)
* IP addresses (e.g. 192.168.100.42)

**Example**

{% code lineNumbers="true" %}

```ini
CYBUS_INGRESS_DNS_NAMES=connectware.company.io,*.company.io,192.168.100.42
```

{% endcode %}

The Connectware installer will also ask you for this value.

</details>

### 3. Preparing the Connectware Upgrade

#### Why the Change?

Connectware 2.0.0 introduces architectural improvements that require you to remove or adjust certain resources before running the upgrade. This ensures a clean and successful upgrade process.

#### What You Need to Do

<details>

<summary><strong>1. Backing Up Your PostgreSQL Database</strong></summary>

With Connectware 2.0.0, Connectware uses a new major version of PostgreSQL. You need to delete your `postgresql` volume before upgrading Connectware (this is covered later in this upgrade guide). This requires you to create a backup of your database and restore this after the upgrade.

{% hint style="warning" %}
Any modifications done to Connectware after the following database backup will be lost after the Connectware 2.0.0 upgrade. We recommend to create the backup right before upgrading to Connectware 2.0.0.
{% endhint %}

1. To create a backup of your database, first identify the correct container from the NAMES column:

{% code lineNumbers="true" %}

```bash
docker container ls -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=postgresql"
```

{% endcode %}

If more than one container is shown, you need to identify the correct container. The prefix of the container is usually the folder name in which your Docker Composition is stored. For example, if you installed it in `/opt/connectware`, the name of the container would be `connectware-postgresql-1`.

2. Create a backup of the database in the file `connectware_database.sql`, replacing `${CONTAINER_NAME}` with the name of the container identified in step 1.

{% code lineNumbers="true" %}

```bash
docker exec \
    ${CONTAINER_NAME} \
    bash -c "pg_dump -U cybus-admin --if-exists -c cybus_connectware" \
    > connectware_database.sql
```

{% endcode %}

3. Make sure the backup is successful, then store the database file in a secure location.

</details>

<details>

<summary><strong>2. Service-Manager Volume Backup &#x26; Removal</strong></summary>

The `service-manager` volume is deprecated and will not be used after the upgrade to 2.0.0.

After upgrading, you can remove this Docker volume. You can identify the volume using this command:

{% code lineNumbers="true" %}

```bash
docker volume ls -f "label=com.docker.compose.volume=service-manager"
```

{% endcode %}

In the future, the former contents of this volume will be stored in the PostgreSQL database, but they will not be migrated automatically. You must reinstall any services that you previously used. See [Reinstalling Services](#12-reinstalling-services).

If you do not have your services stored outside of Connectware, make sure to export your services, or create a backup of your `service-manager` volume before upgrading.

</details>

### 4. Upgrading to Connectware 2.0.0

{% hint style="warning" %}
Make sure all prior steps are completed before proceeding with the upgrade.
{% endhint %}

<details>

<summary><strong>1. Reviewing the Connectware Changelog</strong></summary>

Before upgrading to Connectware 2.0.0, review the [changelog](/changelog#what-has-changed-in-200) to familiarize yourself with new features, bug fixes, and other changes introduced in Connectware 2.0.0.

</details>

<details>

<summary><strong>2. Verifying your Backups</strong></summary>

Make sure that you store backups of your setup. This allows you to restore a previous state if necessary.

Your backups must consist of the following files:

* All Docker volumes
* Your Connectware database
* Your .env file
* All service commissioning files

Depending on your local infrastructure, it may be necessary to back up additional files.

</details>

<details>

<summary><strong>3. Shutting Down Protocol-Mapper Agents</strong></summary>

Before running the upgrade, you must stop all connected agents. Any agents that remain active during the upgrade will have to go through the registration process again.

* **Docker Run**: To stop agents which were started using `docker run`, use the `docker stop` command. If you are not aware of the name these containers use, run the `docker ps` command to find out.
* **Docker Compose**: If your agents are running in Docker Compose, use the `docker compose down` command to stop them.
* **Agent Helm Chart**: You can shut down agents that have been installed via the `connectware-agent` Helm chart using this command:

{% code lineNumbers="true" %}

```bash
kubectl get -n ${NAMESPACE} sts -lapp.kubernetes.io/component=protocol-mapper-agent -o name | xargs -I % kubectl scale -n ${NAMESPACE} % --replicas 0
```

{% endcode %}

</details>

<details>

<summary><strong>4.Shutting Down Connectware</strong></summary>

* Before running the installer, you must shut down Connectware.

1. Make sure you enter the directory in which you installed Connectware, where your `docker-compose.yaml` and `.env` files are located. This is likely `/opt/connectware`.
2. Shutdown Connectware:

{% code lineNumbers="true" %}

```bash
docker compose down
```

{% endcode %}

</details>

<details>

<summary><strong>5. Removing the PostgreSQL Volume</strong></summary>

* Before running the installer, you must remove the `postgresql` volume.

1. Identify the correct volume to delete:

{% code lineNumbers="true" %}

```bash
docker volume ls -f "label=com.docker.compose.volume=postgresql"
```

{% endcode %}

If this shows more than one volume, you must identify the correct volume. The prefix of this volume is usually the folder name in which your Docker Composition is stored. For example, if you installed in `/opt/connectware`, the name of this volume would be `connectware_postgresql`.

2. Delete the postgresql volume:

{% code lineNumbers="true" %}

```bash
docker volume rm [volume-identified-in-step-1]"
```

{% endcode %}

</details>

<details>

<summary><strong>6. Initial Connectware Upgrade</strong></summary>

* To upgrade Connectware to a newer version, follow the steps in the [Prepare Installer Script](/deployment/installing-connectware/on-docker#preparing-the-installer-script) to get the latest installer script. When running the update, select your current Connectware installation directory.

The update will automatically preserve your existing configuration, including your license key and network settings. If you are prompted to enter a license key during the update, this usually means that you have selected the wrong installation directory. In this case, cancel the update and verify you have chosen the correct directory.

{% hint style="warning" %}
If you originally installed Connectware with sudo privileges, make sure that you use `sudo` again when running the update.
{% endhint %}

{% hint style="warning" %}

## Downgrading to previous Connectware versions is not supported

{% endhint %}

## Upgrading Connectware in Silent Mode

The installer supports an automated deployment mode that requires no manual intervention. You can activate this by using either `-s` or `--silent`, and `-d`(directory) when [running the installation script](#running-the-installer-script).

If you need to customize your installation, the script offers several configuration options. Run the installer with `--help` to view all available parameters.

**Example**

{% code lineNumbers="true" %}

```bash
./connectware-online-installer.sh -s -d <PATH/TO/YOUR/CONNECTWARE/FOLDER>
```

{% endcode %}

The installer will tell you that you are ready to run `docker compose up` now. However, before you do this, there are some additional steps that need to be completed.

</details>

<details>

<summary><strong>7. Running Database Restore &#x26; Starting Connectware</strong></summary>

1. Create a file called `docker-compose.override.yaml` and add the following content:

{% code lineNumbers="true" %}

```yaml
services:
  admin-web-app:
    profiles:
      - do-not-start
  auth-server:
    profiles:
      - do-not-start
  broker:
    profiles:
      - do-not-start
  connectware:
    profiles:
      - do-not-start
  container-manager:
    profiles:
      - do-not-start
  doc-server:
    profiles:
      - do-not-start
  ingress-controller:
    profiles:
      - do-not-start
  protocol-mapper:
    profiles:
      - do-not-start
  service-manager:
    profiles:
      - do-not-start
  workbench:
    profiles:
      - do-not-start
  resource-status-tracking:
    profiles:
      - do-not-start
  nats:
    profiles:
      - do-not-start
```

{% endcode %}

{% hint style="info" %}
If you are already using a file `docker-compose.override.yaml`, make sure to temporary rename this file for the upgrade.
{% endhint %}

2. Start the Docker Composition:

{% code lineNumbers="true" %}

```bash
docker compose up -d
```

{% endcode %}

3. Once the postgresql container has started, restore the database (reuse the container name previously identified when backup up the database):

{% code lineNumbers="true" %}

```bash
cat connectware_database.sql | docker exec -i \
    ${CONTAINER_NAME} \
    bash -c "psql -U cybus-admin -d cybus_connectware"
```

{% endcode %}

4. Stop the Docker Composition:

{% code lineNumbers="true" %}

```bash
docker compose down
```

{% endcode %}

5. Remove `docker-compose.override.yaml`

{% code lineNumbers="true" %}

```bash
rm docker-compose.override.yaml
```

{% endcode %}

{% hint style="info" %}
If you were already using a file `docker-compose.override.yaml`, make sure to restore it now.
{% endhint %}

6. Start Connectware 2.0.0:

{% code lineNumbers="true" %}

```bash
docker compose up -d
```

{% endcode %}

7. Restart Connectware 2.0.0:

Finally, restart Connectware once more to ensure any certificate updates are properly applied:

{% code lineNumbers="true" %}

```bash
docker compose down && docker compose up -d
```

{% endcode %}

</details>

### 5. Updating Agent Configuration

#### Why the Change?

{% hint style="info" %}
This guide explains how to update agents that use Docker. If you are using agents via the `connectware-agent` Helm chart, refer to the [Kubernetes Guide](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes).
{% endhint %}

With Connectware 2.0.0, the default handling of certificate chain verification has changed. Previously, protocol-mapper agents required explicit configuration to validate peer certificate chains. Now, certificate chain verification is enabled and enforced by default. While you can revert to the old behavior using a configuration switch, we strongly recommend using a proper TLS certificate chain.

You now must provide the CA certificate signing Connectware's public server certificate `cybus_server.crt` to agents.

Additionally, the `control-plane-broker` has been replaced with a new streaming-based control plane. Along with this change, the configuration values for both the control plane and the data plane have been redesigned. The new values are intended to be generic and resilient against future technology changes. As a result, several environment variables have been deprecated, renamed, or newly introduced.

#### What You Need to Do

Because Connectware agents are single containers, they can be orchestrated by many means, exceeding the possibilities of this upgrade guide. We will provide examples for Docker Compose orchestration. We trust that you know how to adapt these to an orchestrator of your choice. Contact Cybus Support for additional assistance.

<details>

<summary><strong>1. Adding the CA Certificate to Your Agent</strong></summary>

To connect a protocol-mapper agent with Connectware 2.0.0, you must either provide the agent with the valid CA certificate for the server certificate in use, or disable verification of TLS certificate validity by setting the environment variable `CYBUS_TRUST_ALL_CERTS` to `true` on the agent.

Whether you are connecting an agent via Connectware's ingress or the internal network will determine whether you need to provide either `cybus_ca.crt` or `shared_yearly_ca.crt`. However, if you want to avoid this complexity, there is a new file called `cybus_combined_ca.crt` which includes both CA bundles and allows both internal and external connections.

You need to have the CA certificate that you want to add at hand. In this example, we assume that you are using the `cybus_combined_ca.crt`:

1. Identify the correct container from the NAMES column:

{% code lineNumbers="true" %}

```bash
docker container ls -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=system-control-server"
```

{% endcode %}

2. Copy `cybus_combined_ca.crt` from Connectware:

{% code lineNumbers="true" %}

```bash
docker cp [container-name-from-step-1]:/connectware_certs/cybus_combined_ca.crt cybus_combined_ca.crt
```

{% endcode %}

3. Copy the CA certificate `cybus_combined_ca.crt` to the directory which contains the `docker-compose.yaml` file for your agent:

**Example using /opt/connectware-agent/ as directory:**

{% code lineNumbers="true" %}

```bash
cp cybus_combined_ca.crt /opt/connectware-agent/
```

{% endcode %}

4. Mount the CA certificate `cybus_combined_ca.crt` to the `/connectware/certs/ca/ca-chain.pem` mount point of your agent by adding a volume in `docker-compose.yaml`:

**Example using /opt/connectware-agent/ as directory:**

{% code lineNumbers="true" %}

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: localhost
    volumes:
      - protocol-mapper-agent:/data
      - ./cybus_combined_ca.crt:/connectware/certs/ca/ca-chain.pem # Mount your cybus_combined_ca to the agent
    restart: unless-stopped
    network_mode: host
    hostname: my-docker-compose-agent
volumes:
  protocol-mapper-agent:
```

{% endcode %}

</details>

<details>

<summary><strong>2. (Alternative) Disable TLS Certificate Validation</strong></summary>

You can choose to disable TLS certificate validation for agents. This is **not recommended**, as it weakens security and makes your setup vulnerable to man-in-the-middle attacks. However, it may be acceptable in non-production environments such as development or testing.

{% hint style="info" %}
This option is only available for agents using username/password authentication. If your agents use mTLS, you must configure proper certificates instead.
{% endhint %}

{% code lineNumbers="true" %}

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: localhost
      CYBUS_TRUST_ALL_CERTS: true # disable certificate validation
    volumes:
      - protocol-mapper-agent:/data
    restart: unless-stopped
    network_mode: host
    hostname: my-docker-compose-agent
volumes:
  protocol-mapper-agent:
```

{% endcode %}

</details>

<details>

<summary><strong>3. Updating Environment Variables</strong></summary>

**Obsolete Environment Variables (Agents)**

Some [Environment Variables](/reference/environment-variables#docker-compose) are obsolete and have been removed. Remove the following environment variables from your agent orchestration:

* `CYBUS_PM_RPC_TIMEOUT`
* `CYBUS_CONTROLPLANE_URI`

**New or Changed Environment Variables (Agents)**

The following environment variables have changed. If you had specific configuration for these in the past, update your orchestration accordingly.

For some environment variables, you need to take additional steps depending on your setup. The required steps are covered in the following sections.

| **Old Environment Variable** | **New Environment Variable**                             | **Required Change**                                                                            |
| ---------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| -                            | `CYBUS_DATAPLANE_USE_TLS`                                | Set to `true` if you want your agents to use TLS encryption for the MQTT data plan             |
| `USE_MUTUAL_TLS`             | `CYBUS_USE_MUTUAL_TLS`                                   | Set to `true` if you want your agents to use mTLS authentication for the MQTT data plan        |
| `TRUST_ALL_CERTS`            | `CYBUS_TRUST_ALL_CERTS`                                  | Set to `true` if you want your agents to skip TLS certificate validation.                      |
| `CYBUS_DATA_MQTT_HOST`       | `CYBUS_DATAPLANE_HOST`                                   | See **3.2 - Directly Targeting MQTT Broker**                                                   |
| `CYBUS_DATA_MQTT_PORT`       | `CYBUS_DATAPLANE_PORT`                                   | See **3.2 - Directly Targeting MQTT Broker**                                                   |
| `CYBUS_MQTT_HOST`            | `CYBUS_STREAMSERVER_HOST`                                | See **3.3 - Directly Targeting Streaming Server**                                              |
| `CYBUS_MQTT_PORT`            | `CYBUS_STREAMSERVER_PORT`                                | See **3.3 - Directly Targeting Streaming Server**                                              |
| `CYBUS_MQTT_SCHEME`          | `CYBUS_DATAPLANE_SCHEME` and `CYBUS_STREAMSERVER_SCHEME` | See **3.2 - Directly Targeting MQTT Broker** and **3.3 - Directly Targeting Streaming Server** |

</details>

<details>

<summary><strong>3.1 - Updating Connectware Ingress Targeting</strong></summary>

Connectware 2.0.0 changes how you address your Connectware instance with agents.

Previously, the environment variable `CYBUS_MQTT_HOST` was used. Later, `CYBUS_HOSTNAME_INGRESS` was introduced for targeting the ingress, while `CYBUS_MQTT_HOST` was used for targeting the `control-plane-broker`. Additionally, `CYBUS_DATA_MQTT_HOST` was introduced to control the MQTT broker that the agent connected to as data plane. `CYBUS_MQTT_HOST` acted as a fallback for all three environment variables.

With the removal of the `control-plane-broker`, we are simplifying and decoupling the configuration:

* If you are only using the Connectware ingress for your agents, you must only configure `CYBUS_HOSTNAME_INGRESS`.
* If you have more complex setup, which targeted the MQTT data plane broker or the `control-plane-broker`, use `CYBUS_DATAPLANE_HOST` and `CYBUS_STREAMSERVER_HOST` to refine your configuration, as explained in the next steps.

In short, make sure that you target your Connectware instance using the `CYBUS_HOSTNAME_INGRESS` environment variable, replacing any legacy `CYBUS_MQTT_HOST` configuration you may have had, without the intention of directly targeting the MQTT data plane broker.

{% code lineNumbers="true" %}

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: localhost # make sure you use CYBUS_HOSTNAME_INGRESS as the general Connectware target for your agent
      CYBUS_DATAPLANE_HOST: broker # use new environment variables for more complex network setups
    volumes:
      - protocol-mapper-agent:/data
      - ./cybus_combined_ca.crt:/connectware/certs/ca/ca-chain.pem
    restart: unless-stopped
    hostname: my-docker-compose-agent
    network_mode: host
volumes:
  protocol-mapper-agent:
```

{% endcode %}

</details>

<details>

<summary><strong>3.2 - Directly Targeting MQTT Broker</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our MQTT broker instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

The major hindrance is, that the name "broker", which is used by our MQTT broker on the internal network, is not part of the `cybus_server.crt` by default. In order to connect agents with a TLS connection to this hostname, you either need to add the hostname "broker" as a Subject Alternate Name (SAN) to the certificate, or set `CYBUS_TRUST_ALL_CERTS=true` for the agent. The previous steps explained how to add the CA certificate bundle file and how to set the environment variable.

**Adding the Hostname to the Default Certificate**

If you are using the built-in default certificate for Connectware, you can add the hostname "broker" through the environment variable `CYBUS_HOSTNAME_INGRESS` in the `.env` file of your Connectware installation:

{% code lineNumbers="true" %}

```ini
CYBUS_INGRESS_DNS_NAMES=connectware.company.io,broker
```

{% endcode %}

It is easiest if you add this configuration during your upgrade to Connectware 2.0.0, since activating it will automatically be covered by the upgrade guide. You will be asked for the ingress hostnames by the installer script. You can also use the parameter `--ingress-dns-names` for the Connectware installer to set this.

If applying this configuration after already upgrading to Connectware 2.0.0, running `docker compose up -d` on your Connectware installation will cause the multiple containers to restart. Once they are ready, restart Connectware again:

{% code lineNumbers="true" %}

```bash
docker compose down
docker compose up -d
```

{% endcode %}

**Configuring Your Agents to Target the MQTT Broker**

Next, you must configure your agents to target the MQTT broker directly by using the `CYBUS_DATAPLANE_*` environment variables. To use TLS encryption for this connection, you must set `CYBUS_DATAPLANE_USE_TLS` to `true` and provide the agent with the CA certificate bundle, as explained previously.

**Docker Compose Example**

To add a Docker Composition to an existing network, you must add it as external network. For this, you need to know the name of the network.

This example assumes the name is `connectware_cybus`, however you can find it using this command (NAME column):

{% code lineNumbers="true" %}

```bash
docker network ls -f "label=com.docker.compose.network=cybus"
```

{% endcode %}

{% code lineNumbers="true" %}

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: connectware
      CYBUS_DATAPLANE_HOST: broker
      CYBUS_DATAPLANE_USE_TLS: true
    volumes:
      - protocol-mapper-agent:/data
      - ./cybus_combined_ca.crt:/connectware/certs/ca/ca-chain.pem
    restart: unless-stopped
    hostname: my-docker-compose-agent
    networks:
      - connectware_cybus # name from previous step
    extra_hosts:
      - 'connectware:host-gateway' # this extra host ensures the agent is still able to make HTTP API calls
volumes:
  protocol-mapper-agent:
networks:
  connectware_cybus: # name from previous step
    external: true
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like TLS and mTLS settings, however, if for some reason you need to override this, use the environment variable `CYBUS_DATAPLANE_PORT`.

</details>

<details>

<summary><strong>3.3 - Directly Targeting Streaming Server</strong></summary>

When deploying agents in the internal network of Connectware, they are able to directly connect to our streaming server control plane instead of going through the Connectware ingress.

This improves performance and reduces failure points, so if you are running a heavy, critical load, it may be worth the extra configuration.

**Configuring Your Agents to Target the Streaming Server**

Next, you must configure your agents to target the streaming server directly by using the `CYBUS_STREAMSERVER_HOST` environment variable. The default internal name is "nats".

**Docker Compose Example**

To add a Docker Composition to an existing network, you must add it as external network. For this, you need to know the name of the network.

This example assumes the name is `connectware_cybus`. However, you can find it using this command (NAME column):

{% code lineNumbers="true" %}

```bash
docker network ls -f "label=com.docker.compose.network=cybus"
```

{% endcode %}

{% code lineNumbers="true" %}

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: connectware
      CYBUS_STREAMSERVER_HOST: nats
    volumes:
      - protocol-mapper-agent:/data
      - ./cybus_combined_ca.crt:/connectware/certs/ca/ca-chain.pem
    restart: unless-stopped
    hostname: my-docker-compose-agent
    networks:
      - connectware_cybus # name from previous step
    extra_hosts:
      - 'connectware:host-gateway' # this extra host ensures the agent is still able to make HTTP API calls
volumes:
  protocol-mapper-agent:
networks:
  connectware_cybus: # name from previous step
    external: true
```

{% endcode %}

The TCP port used for this connection is automatically determined by other configuration like mTLS settings. However, if for some reason you need to override this, use the environment variable `CYBUS_STREAMSERVER_PORT`.

{% hint style="info" %}
If you are not using the `cybus_combined_ca.crt` for your agents, targeting the streaming server requires you to add the `shared_yearly_ca.crt`, not the `cybus_ca.crt`.
{% endhint %}

</details>

### 6. Upgrading Agents

#### What You Need to Do

{% hint style="info" %}
This guide explains how to update agents which use Docker Compose. If you are using agents via the `connectware-agent` Helm chart, follow the [Kubernetes upgrade guide](/deployment/upgrading-connectware/on-kubernetes/to-2-0-0-on-kubernetes) for this part.
{% endhint %}

1. Ensure you followed the previous step to prepare the agents, by adjusting their configuration to the changes made with Connectware 2.0.0.
2. Enter the directory in which the `docker-compose.yaml` file for your agents is stored.
3. Modify the agents `docker-compose.yaml` file and replace the image tag with `2.0.0`.

**Example**

```yaml
services:
  protocol-mapper-agent:
    image: registry.cybus.io/cybus/protocol-mapper:2.0.0 # update the image tag
    environment:
      CYBUS_AGENT_MODE: distributed
      CYBUS_AGENT_NAME: my-docker-compose-agent
      CYBUS_HOSTNAME_INGRESS: connectware
    volumes:
      - protocol-mapper-agent:/data
      - ./cybus_combined_ca.crt:/connectware/certs/ca/ca-chain.pem
    restart: unless-stopped
    network_mode: host
    hostname: my-docker-compose-agent
volumes:
  protocol-mapper-agent:
```

4. Run `docker compose up`.

### 7. Reinstalling Services

#### Why the Change?

With Connectware 2.0.0, your services and resources are no longer stored on the service-manager volume, but inside the PostgreSQL database.

#### What You Need to Do

<details>

<summary><strong>Reinstalling Your Services</strong></summary>

After completing the upgrade, you must reinstall all previously used services. You can do this using your preferred method:

* Via the Admin UI, see [Installing Services](/data-flows/services/managing/installing).
* Automatically through a CI pipeline.

Additionally, there have been changes to the relationships between services. Understanding how these interdependencies behave at runtime is crucial for correct deployment and maintenance.

**Install parent services first (recommended)**: If the service depends on another service (parent/child relationship), install the parent service first. This ensures:

* Service relations are created during installation.
* Each service can be installed with `targetState=enabled`.

**Install child services first (alternative)**: It is possible to install the dependent (child) service first, but this comes with limitations:

* Service relations are only established when the service is enabled.
* The dependent (child) service can **only** be installed with `targetState=disabled`.

For more details, see [Service Dependency Behavior](/data-flows/services/inter-service-referencing#service-dependency-behavior) and [targetState](/data-flows/service-commissioning-files/resources/cybus-endpoint#targetstate).

</details>

## Feature-Specific Upgrade Steps

Only follow these if you use the related features, so they continue working after the upgrade.

### 1. Permissions and Roles

#### Why the Change?

Permissions allow administrators to define who can access what resources and what actions they can perform. Each permission represents a specific access right to a resource.

Connectware 2.0.0 introduces new and permissions. Because of this, custom roles or specific permissions you have set up might not allow users to do everything they could before the 2.0.0 upgrade.

#### What You Need To Do

<details>

<summary><strong>Verifying Permissions</strong></summary>

* Check the permissions of your users. Compare them with the default roles in Connectware 2.0.0 and make any updates needed so your users can continue working without interruptions.

For more information on managing permissions, see [Permissions](/access/user-management/permissions).

</details>

### 2. Custom Connectors

#### Why the Change?

Connectware has evolved its architecture, removing dependencies like VRPC and improving protocol handling. To ensure compatibility, you must update your custom connector implementations.

#### What You Need To Do

If you are using [custom connectors](/connectors/custom-connectors/using-custom-connectors), follow these steps to make your custom connector compatible with Connectware 2.0.0.

<details>

<summary><strong>1. Remove VRPC</strong></summary>

VRPC is no longer supported in the custom connector environment.

* Remove all VRPC references in the custom connector code. This includes the import and any usage of `VrpcAdapter`:

**Example**

{% code lineNumbers="true" %}

```javascript
// const { VrpcAdapter } = require('vrpc') <- REMOVE THIS
const Connection = require('./FoobarConnection')
const Endpoint = require('./FoobarEndpoint')

// VrpcAdapter.register(Endpoint, { schema: Endpoint.getSchema() }) <- REMOVE THIS
// VrpcAdapter.register(Connection, { schema: Connection.getSchema() }) <- REMOVE THIS
```

{% endcode %}

</details>

<details>

<summary><strong>2. Follow the Directory Naming Conventions</strong></summary>

* When defining the Dockerfile, ensure that the destination path for the copied source files ends in a protocol-specific directory name written entirely in lowercase.

**Example**

{% code lineNumbers="true" %}

```yaml
# protocol directory must be lowercase
COPY ./src ./src/protocols/foobar
```

{% endcode %}

</details>

<details>

<summary><strong>3. Follow the Schema Naming Conventions</strong></summary>

* The schema `$id` must match the file name (without the `.json`).
* The schema must start with a capital letter, like `Foobar`.

**Example**

* In `FoobarConnection.json`, the class must be like:

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarConnection"
  ...
}
```

{% endcode %}

* In `FoobarEndpoint.json`, the class must be like:

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarEndpoint"
  ...
}
```

{% endcode %}

</details>

<details>

<summary><strong>4. Schema Versioning</strong></summary>

Schemas support versioning through the additional `version` property, which must be a positive integer greater than zero. If this property is omitted, the default value is `1`.

Versioning ensures that only the latest version of a schema is considered active and valid. This means that even though all custom connector instances should run the same version of schemas, the latest version will overwrite any previous version in the CW control plane.

**Example**

* `FoobarConnection.json` supporting versioning.

{% code lineNumbers="true" %}

```json
{
  ...
  "$id": "FoobarConnection",
  "version": 3
  ...
}
```

{% endcode %}

</details>

<details>

<summary><strong>5. Follow the Source Directory Naming Conventions</strong></summary>

Follow the case-sensitive naming conventions based on the protocol name.

* File names must start with an uppercase protocol name (e.g., `Foobar`).
* Connection and endpoint suffixes are mandatory.
* JS files define classes.
* JSON files define schemas.

**Example**

{% code lineNumbers="true" %}

```yaml
src/
├── FoobarConnection.js
├── FoobarConnection.json
├── FoobarEndpoint.js
└── FoobarEndpoint.json
```

{% endcode %}

</details>

<details>

<summary><strong>6. Follow the Class Naming Conventions</strong></summary>

* The class name must match the file name, excluding the `.js` extension.
* The class name must start with a capital letter, such as `Foobar`.

**Example**

* In `FoobarConnection.js`, the class must be:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection extends Connection { ... }
```

{% endcode %}

* In `FoobarEndpoint.js`, the class must be:

{% code lineNumbers="true" %}

```javascript
class FoobarEndpoint extends Endpoint { ... }
```

{% endcode %}

</details>

<details>

<summary><strong>7. Class Constructors</strong></summary>

Unless you need a specific constructor, there is no need to specify one because it is inherited from the parent class. However, if you need to implement a custom constructor for the `Connection` or `Endpoint` classes, preserve the following format:

* In `FoobarConnection.js`, the class constructor must be like:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection extends Connection {
---
constructor (params) {
super(params)
---
// custom code
---
}
---
}
```

{% endcode %}

* In `FoobarEndpoint.js`, the class constructor must be like:

{% code lineNumbers="true" %}

```javascript
class FoobarEndpoint extends Endpoint {
---
constructor (params, dataPlaneConnectionInstance, parentConnectionInstance) {
super(params, dataPlaneConnectionInstance, parentConnectionInstance)
---
// custom code
---
}
---
}
```

{% endcode %}

</details>

<details>

<summary><strong>8. Do not Set the _topic Property Manually</strong></summary>

The `_topic` property is now handled automatically. Manually assigning it will cause errors.

The following code is invalid and must be removed since topics are now built internally.

{% code lineNumbers="true" %}

```javascript
// this is invalid, remove it
this._topic = 'this/is/a/topic'
```

{% endcode %}

</details>

<details>

<summary><strong>9. ES Modules Not Supported</strong></summary>

The standard JavaScript environment of custom connectors is based on CommonJS modules. ES modules are not supported.

</details>

<details>

<summary><strong>10. TypeScript Configuration</strong></summary>

TypeScript is not officially supported in development workflows. However, if you want to use TypeScript and compile it to JavaScript, make sure to configure your `tsconfig.json` file as follows:

{% code lineNumbers="true" %}

```json
{
  "compilerOptions": {
    ....
    "target": "es2022",    /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "lib": ["es6"],        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    "module": "commonjs",  /* Specify what module code is generated. */
    ....
  },
  "include": ["src/**/*.ts", "src/**/*.json", "src/**/*.js", "src/**/*.d.ts", "test/**/*"]
}
```

{% endcode %}

Additionally, the compiled JavaScript output must include an `exports.default` assignment and the exported class itself. This ensures interoperability with our CommonJS-based module system. The compiled `.js` file should result in:

{% code lineNumbers="true" %}

```javascript
class FoobarConnection { ... }
exports.default = FoobarConnection;
```

{% endcode %}

</details>

### 3. Systemstate Protocol

#### Why the Change?

To improve performance and reduce unnecessary messaging load, the Systemstate protocol no longer supports whole-service tracking or redundant status events. This simplifies agent responsibilities and avoids misleading lifecycle signals.

#### What You Need to Do

If you are using the [Systemstate protocol](/connectors/enterprise-connectors/systemstate), do the following:

<details>

<summary><strong>1. Stop Tracking Whole Services</strong></summary>

* Tracking the entire service object is no longer allowed. You must update your connector configuration to track individual resources only (like specific endpoints or connections).

**Example**

{% code lineNumbers="true" %}

```yaml
# Before (no longer supported)
serviceEndpoint:
  type: Cybus::Endpoint
  properties:
    protocol: Systemstate
    connection: !ref systemStateConnection
    subscribe:
      resourceId: !sub '${Cybus::ServiceId}'
```

{% endcode %}

</details>

<details>

<summary><strong>2. Update Event Handling Logic</strong></summary>

The following status events have been removed from Systemstate. If your implementation depends on them (e.g., for health monitoring or automation), you must refactor that logic:

* `subscribed`/`unsubscribed`
* `online`/`offline`

</details>

### 4. Log Monitoring

#### Why the Change?

With version 2.0.0, several log messages have been corrected to fix spelling mistakes. These changes may affect existing log monitoring configurations.

#### What You Need to Do

<details>

<summary><strong>Updating Your Log Monitoring</strong></summary>

If you rely on log monitoring, review whether your setup references any of the updated log messages and adjust accordingly.

| Type          | Log Level | Original (with typo)                                                                                | Corrected line                                                                                      |
| ------------- | --------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Log message   | info      | MS Entra Login was succesful, redirecting to                                                        | MS Entra Login was successful, redirecting to                                                       |
| Log message   | debug     | DELETE /:id/tokens sucess for user: '\<req.params.id>'                                              | DELETE /:id/tokens success for user: '\<req.params.id>'                                             |
| Error message |           | Views are found, the restore implenetation do not support views!                                    | Views are found, the restore implementation do not support views!                                   |
| Error message |           | query paramter error is not a valid HTTP error code (\<req.query.code>)                             | query parameter error is not a valid HTTP error code (\<req.query.code>)                            |
| Log message   | debug     | Cleared persistance of:                                                                             | Cleared persistence of:                                                                             |
| Error message | warn      | HttpNode is configured with method 'GET' but operation 'serverRecieves' (instead of serverProvides) | HttpNode is configured with method 'GET' but operation 'serverReceives' (instead of serverProvides) |
| Log message   |           | Error when trying to recieve OPC-UA Method details from nodeId : \<err.message>                     | Error when trying to receive OPC-UA Method details from nodeId : \<err.message>                     |
| Log message   | warn      | tried to pass the value as an INT64 and found no matching convertion                                | tried to pass the value as an INT64 and found no matching conversion                                |
| Log message   | warn      | tried to pass the value as an UINT64 and found no matching convertion                               | tried to pass the value as an UINT64 and found no matching conversion                               |
| Log message   | debug     | Sucessfully subscribed to topic: \<mqttOpts.topic>.                                                 | Successfully subscribed to topic: \<mqttOpts.topic>.                                                |
| Log message   | error     | error occured during shutting down the server                                                       | error occurred during shutting down the server                                                      |
| Log message   | error     | expected payload convertion to fail because given payload was not a JSON notation, but 'err == nil' | expected payload conversion to fail because given payload was not a JSON notation, but 'err == nil' |

</details>

### 5. Heidenhain Agents (Windows)

#### Why the Change?

For Connectware 2.0.0, the Heidenhain protocol has been updated.

#### What You Need to Do

<details>

<summary><strong>Installing the Heidenhain Agent</strong></summary>

You must upgrade the Windows-based [Cybus Heidenhain Agent](/connectors/shop-floor-connectors/heidenhain-dnc) to work with Connectware 2.0.0.

1. Uninstall the existing Heidenhain agent installation from your Windows system.
2. Install the updated Heidenhain agent. You can find the download link at [Heidenhain DNC](/connectors/shop-floor-connectors/heidenhain-dnc).

</details>

### 6. Auto-Generated MQTT Topics of Resources

#### Why the Change?

With Connectware 2.0.0, auto-generated MQTT topics no longer include resource-specific properties. This makes the topic generation more unified and explicit. You must update any service commissioning file that hardcodes those old auto-generated topics.

**Example of old behavior**

Some auto-generated topics contained property-specific parts:

* S7: `services/myService/pressure/address:DB1,REAL6`
* Modbus: `services/myService/current/fc:3/address:7`
* HTTP: `services/myService/myEndpoint/get[object Object]`

These paths might have been referenced inside `Cybus::Mapping` resources. Using auto-generated topics inside `Cybus::Mapping` is **not** recommended. Instead, use references via `!ref, “Reference Method”`.

#### What You Need to Do

<details>

<summary><strong>Updating Auto-Generated Topic References</strong></summary>

Auto-generated topics no longer include resource-specific properties. They always follow:

{% code lineNumbers="true" %}

```bash
<Cybus::MqttRoot>/<serviceId>/<resourceName>
```

{% endcode %}

**Example of new behavior**

* S7: `services/myService/pressure`
* Modbus: `services/myService/current`
* HTTP: `services/myService/myEndpoint`

**Procedure**

1. Scan your service commissioning files for any usage of auto-generated topics.
2. Adapt those references by replacing direct topic strings with `!ref` references.

For more details, see [Reference Method (!ref)](/data-flows/service-commissioning-files/parameters#reference-method-ref).

</details>

### 7. Auto-Generated MQTT Users

#### Why the Change?

Before 2.0.0, Connectware created a hidden MQTT user for every installed service. These auto-generated users were only used when the service commissioning file explicitly referenced the pseudo parameter [Cybus::MqttUser](/data-flows/service-commissioning-files/parameters#cybus-mqttuser).

With Connectware 2.0.0, hidden users and groups are created only when the service commissioning file uses the `Cybus::MqttUser` pseudo parameter. This reduces unused accounts and makes credential usage explicit.

#### What You Need to Do

<details>

<summary><strong>Verify Your Service Commissioning Files</strong></summary>

If you are using auto-generated MQTT users outside of services (e.g., scripts, dashboards, or other non-commissioning references), migrate to explicit identities:

* Create dedicated users with the required roles/permissions. See [User Management](/access/user-management).
* Update your external systems to use the new explicit credentials.

</details>


# Upgrading Connectware to 1.11.0 (Docker)

Follow the step-by-step procedure to upgrade a Docker-based Connectware installation to version 1.11.0.

{% hint style="danger" %}
We have streamlined the upgrade procedure for version 1.11.0 with version 2.0.0. If you are on 1.7.0 or above, skip 1.11.0 and upgrade directly to 2.0.0. For more information, see [Upgrading Connectware to 2.0.0 (Docker)](/deployment/upgrading-connectware/on-docker/to-2-0-0-on-docker).
{% endhint %}


# Upgrading Connectware to 1.7.0 (Docker)

How to upgrade Connectware to version 1.7.0 on Docker.

Connectware 1.7.0 affects the backward compatibility of the Connectware broker. Older broker data volumes are not compatible with brokers of Connectware 1.7.0 and newer. Upgrading to Connectware 1.7.0 requires additional upgrade procedures.

Additionally, multi-factor authentication (MFA) is now controlled via a dedicated configuration switch.

{% hint style="warning" %}

## Check your upgrade path

This upgrade is one step of a longer upgrade path. Before you continue, check [Connectware Upgrade Paths](/deployment/upgrading-connectware/upgrade-paths) to determine which steps apply to your installation.
{% endhint %}

## Important Notes

This upgrade will delete all persisted data of the Connectware broker. This includes client sessions, subscriptions, and retained data. If your configuration relies on any type of data persisted by the broker, make sure to properly initialize your applications after the upgrade.

If you rely on persisted data, create a backup or snapshot of the broker data volumes. This allows you to roll back in case of complications.

## Upgrading Procedure

1. To stop Connectware, go to the Connectware installation directory (default: `/opt/connectware`) and run `docker compose down`.
2. Delete the broker data volume of Connectware. Find the broker data volume in the list of volumes with `docker volume ls` and delete it with `docker volume rm <connectware_brokerData>`.
3. If you are using multi-factor authentication (MFA), set the environment variable `CYBUS_MFA_ENABLED` to `true` inside your .env file.
4. Download and install the new Connectware version. For more information, see [Upgrading Connectware (Docker)](/deployment/upgrading-connectware/on-docker).


# Licensing

Connectware operates based on your license specifications, which determine available features and validity period.

Connectware requires a valid license key to operate. Each license key is uniquely tied to your instance and enables specific features based on your subscription. This section covers everything you need to know about obtaining, managing, and implementing your Connectware license.

For more information about available Connectware licenses, visit the [Cybus website](https://www.cybus.io/en/product/licenses/).

## License View

The **License View** displays information of your active Connectware license. Each time you start Connectware, the license is automatically validated over the Internet. If your Connectware installation does not have Internet access, you can upload a valid license file manually.

* To open the **License View**, select **System** > **System Status**, and click the **License** tab.

<figure><img src="/files/QNUVv0D1ecVcYIZIVcia" alt=""><figcaption></figcaption></figure>

The following information are available:

* **License Name**
* **License Account**
* **Expiration Date**
* **License Class**
* **License ID**
* **License Status**

You can manually [refresh your license](#manually-refreshing-licenses-in-connectware) via the **Refresh License** button. You can [upload a new license file](#uploading-license-files-to-connectware) via the **Upload License File** button.

## Acquiring License Keys

The [Cybus Portal](https://portal.cybus.io/) allows you to generate and manage license keys for your Connectware installations. This page walks you through accessing the portal and generating new license keys. Once generated, you'll use this key during the Connectware installation process.

**Prerequisites**

* Access to the Cybus Portal. Contact our [Sales team](mailto:sales@cybus.io) to obtain portal credentials if needed.

**Procedure**

1. Go to the [Cybus Portal](https://portal.cybus.io/).
2. Enter your **Username** and **Password**, and click **Sign in**.
3. Click **Licenses** in the menu to view all your available Connectware licenses.

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/Connectware-Licenses.png" alt="Available Connectware Licenses"><figcaption></figcaption></figure>

4. To obtain a new license key, click a license. We recommend to look for licenses marked as **No license key created yet**. You can use the **No license key** filter option to show only licenses without keys.

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/SelectLicense.png" alt="Select Licenses Connectware"><figcaption></figcaption></figure>

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/NoLicenseKey.png" alt="No License Key Connectware"><figcaption></figcaption></figure>

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/AllLicenses.png" alt="Download License Key Button"><figcaption></figcaption></figure>

4. Click **Download License Key** in the upper right corner.

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/Download-License.png" alt="Download License Key Button"><figcaption></figcaption></figure>

5. Add a description for your license and click **Generate License Key**.

{% hint style="warning" %}
Your new license key will appear on screen. Make sure to copy and save it somewhere secure, as you won't be able to view it again after closing this window. If you lose the key, you'll need to generate a new one, which will invalidate the previous key - even if it's already in use.
{% endhint %}

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/GenerateLicenseKey1.png" alt="Description of License Connectware"><figcaption></figcaption></figure>

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/GenerateLicenseKey2.png" alt="Generate License Key Connectware"><figcaption></figcaption></figure>

<figure><img src="https://www.cybus.io/wp-content/uploads/2024/05/GenerateLicenseKey3.png" alt="Output of License Key Connectware"><figcaption></figcaption></figure>

**Result:** Once you have your license key safely stored, you can proceed with Connectware installation.

## Online License Validation

Connectware automatically validates your license during startup if it can reach the [Cybus Portal](https://portal.cybus.io/)) backend (`graphql-server.cybus.io`). When this connection is available, license updates occur automatically in the background. If the server cannot be reached, you must [manually update](#manually-refreshing-licenses-in-connectware) your Connectware license by uploading a new license file.

## Offline License Activation

If Connectware is not connected to the Internet, you must activate your license manually through an offline process. This requires:

1. Downloading a license file from the [Cybus Portal](https://portal.cybus.io/) via one of the following options:
   * [Downloading License Files via Installer Script](#downloading-license-files-via-installer-script)
   * [Downloading License File via Cybus Portal Website](#downloading-license-file-via-cybus-portal-website)
2. Uploading the license file into your offline Connectware installation.

### Downloading License Files

You can download license files via the installer script or via the [Cybus Portal](https://portal.cybus.io/).

#### Downloading License Files via Installer Script

If you installed Connectware using the `connectware-online-installer.sh` script, you can use the same script to download your license file by adding the `--download-license-file` command.

To download the license file, you'll need either:

1. Your original license key, which can be passed directly as a command-line option.
2. The path to your existing Connectware installation directory.

Once executed, the script will download your license file and display its filename. You can then use this file to activate your offline Connectware installation.

**Procedure**

* To download the license via the script with the license key (e.g. `ABCABCABC`,), do the following:

{% code lineNumbers="true" %}

```
./connectware-online-installer.sh --download-license-file -k ABCABCABC
```

{% endcode %}

* To download the license via the script using the Connectware installation directory (e.g. `/opt/connectware`), do the following:

{% code lineNumbers="true" %}

```
./connectware-online-installer.sh --download-license-file -d /opt/connectware
```

{% endcode %}

**Next step**: Transfer the downloaded license file to your Connectware host machine for activation. See [Uploading License Files to Connectware](#uploading-license-files-to-connectware).

#### Downloading License Files via the Cybus Portal

**Prerequisites**

* Login credentials for the [Cybus Portal](https://portal.cybus.io/).
* A running instance of Connectware that you want to activate.
* A valid license key that matches the one used during installation.

**Procedure**

1. Log in to portal.cybus.io. If you don't have login credentials, contact [sales@cybus.io](mailto:sales%40cybus.io).
2. Click **Licenses** and select your license.
3. Click the **Download License File** icon.

<figure><img src="/files/cAE1YgCxeVlNgXtdaApJ" alt=""><figcaption></figcaption></figure>

3. In the **Download License File** dialog, do the following:
   1. In the **Connectware License Key** field, enter the license key of your Connectware instance.
   2. Click **Download License File**.

<figure><img src="/files/zDQoEdSfuVzRJp8guCVD" alt=""><figcaption></figcaption></figure>

**Next step**: Transfer the downloaded license file to your Connectware host machine for activation. See [Uploading License Files to Connectware](#uploading-license-files-to-connectware).

### Uploading License Files to Connectware

You can activate your Connectware installation by uploading your license file through either:

1. The `Cybus Connectware License Check` dialog at Connectware startup
2. The `Upload License File` option in Connectware
3. A REST endpoint with a command line client
4. Adding the license file via the `CYBUS_LICENSE_FILE` environment variable

#### Uploading License Files at the First Connectware Startup

When you first access a not yet activated Connectware through your web browser, the `Cybus Connectware License Check` dialog opens.

1. In the **Cybus Connectware License Check** dialog, click **Upload License File**.

<figure><img src="/files/MSyO4K5WP2mq8cGaRoGO" alt=""><figcaption></figcaption></figure>

2. Select the license file you [downloaded earlier](#downloading-license-files).

**Result:** After a refresh the license file has been uploaded and validated. Your Connectware is now ready for productive use.

#### Updating your Connectware License

If your Connectware instance has already a running license that you want to update, you can do this via the Connectware user interface.

1. On the navigation panel, click **System**.
2. On the **System Status View**, click the **License** tab.

<figure><img src="/files/YB6Y35TgB9jGp79V3fqx" alt=""><figcaption></figcaption></figure>

3. Click **Upload License File** and select the license file that you want to upload.

<figure><img src="/files/k4jYOqxzJ2wtqnYPAceT" alt=""><figcaption></figcaption></figure>

**Result:** After a refresh the license file has been uploaded and validated. Your Connectware is now ready for productive use.

#### Uploading Licenses via REST API

You can upload your license using a REST API call from the command line. This method requires a REST client - we recommend using `curl`.

Here's how to make the request:

{% code lineNumbers="true" %}

```yaml
curl -X PUT --insecure -u <USERNAME>:<PASSWORD> -d 'payload=<LICENSE-FILE-CONTENT>' https://<HOSTNAME>:443/api/system/licensefile
```

{% endcode %}

Key details for the request:

* Replace `<USERNAME>:<PASSWORD>` with your credentials
* Insert your license file content as the `payload` value
* Update `<HOSTNAME>` to your server's address
* The endpoint is available at `/api/system/licensefile`

You can use this method both for initial license activation and for subsequent license updates.

#### Setting Up Your License Using Environment Variables

You can configure your license by setting the `CYBUS_LICENSE_FILE` environment variable in the `system-control-server` service.

To do this, you need the license file that you have downloaded via [one of these options](#downloading-license-files).

**Example**

Here's how to configure your `docker-compose.yml` file:

{% code lineNumbers="true" %}

```yaml
# [...]
system-control-server:
environment:
  CYBUS_LICENSE_FILE: 'Zm9vYmFyZm9vYmFyZm9vYmFyZm9vYmFyZm9vYmFyZm9v...'
  CYBUS_REGISTRY_PASS: ${CYBUS_REGISTRY_PASS}
  NODE_ENV: production
hostname: system-control-server
image: registry.cybus.io/cybus/system-control-server:1.0.58
# [...]
```

{% endcode %}

## Manually Refreshing Licenses in Connectware

You may need to manually refresh if your license has been upgraded on the [Cybus Portal](https://portal.cybus.io/) but the changes are not reflected in Connectware.

**Prerequisites**

* Internet connectivity is required for both automatic and manual license management.

**Procedure**

1. On the navigation panel, click **System**.
2. On the **System Status View**, click the **License** tab.

<figure><img src="/files/YB6Y35TgB9jGp79V3fqx" alt=""><figcaption></figcaption></figure>

3. Click **Refresh License** to sync with the Cybus Portal.

<figure><img src="/files/Cg83ZmZzQRtBDuC8NldJ" alt=""><figcaption></figcaption></figure>

## License Information via REST API

The system status API allows you to retrieve information about your license. For more information, see [System Status API](/reference/api-reference/system-status-api).


# Restarting Connectware

Learn how to safely restart Connectware.

This section explains how to restart Connectware. Restarting may be necessary when applying configuration changes, troubleshooting issues, or performing maintenance tasks.

{% tabs %}
{% tab title="Kubernetes" %}

## Restarting Connectware on Kubernetes

In Kubernetes environments, restarting Connectware requires scaling down all controller resources to zero before scaling them back up. The following procedure ensures a proper restart without data loss.

### Prerequisites

* [Helm version 4](https://helm.sh/docs/intro/quickstart/#install-helm) is installed on your system.
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed on your system.
* A shell capable of storing variables (e.g. bash).

### Procedure

1. Store the namespace that is used for Connectware in a variable:

{% code lineNumbers="true" %}

```bash
CONNECTWARE_NS=<namespace here>
```

{% endcode %}

2. Store the name and version of the Helm installation that is used for Connectware in a variable:

{% code lineNumbers="true" %}

```bash
CONNECTWARE_HELM_NAME=<helm installation name here>
CONNECTWARE_HELM_VERSION=<helm installation version here>
```

{% endcode %}

If you do not know the name or version of your Connectware installation, you can look for them by listing all Helm installations in your namespace:

{% code lineNumbers="true" %}

```bash
helm list -n $CONNECTWARE_NS
```

{% endcode %}

4. Verify your settings.

To verify that you set the correct variables, run the following command. It should display the Connectware core services:

{% code lineNumbers="true" %}

```bash
kubectl get deploy,sts -lapp.kubernetes.io/part-of=connectware -lapp.kubernetes.io/instance=$CONNECTWARE_HELM_NAME -n $CONNECTWARE_NS
```

{% endcode %}

5. Scale down all StatefulSets and Deployments in your installation:

{% code lineNumbers="true" %}

```bash
kubectl get deploy,sts -lapp.kubernetes.io/part-of=connectware -lapp.kubernetes.io/instance=$CONNECTWARE_HELM_NAME -n $CONNECTWARE_NS -o name | xargs -I % kubectl scale -n $CONNECTWARE_NS % --replicas 0
```

{% endcode %}

6. Wait until all pods have been terminated. You can monitor the termination process with the following command (press <kbd>Ctrl</kbd>+<kbd>C</kbd> once no pods are listed):

{% code lineNumbers="true" %}

```bash
while [ True ]; do clear; kubectl get pod -lapp.kubernetes.io/part-of=connectware -lapp.kubernetes.io/instance=$CONNECTWARE_HELM_NAME -n $CONNECTWARE_NS ; sleep 5; done
```

{% endcode %}

{% hint style="info" %}
If you want to stop Connectware (rather than restart it), or if you need to perform maintenance tasks while it remains stopped, you can end the procedure at this step.
{% endhint %}

7. Reapply the Helm values to start Connectware.

{% code lineNumbers="true" %}

```bash
 helm upgrade $CONNECTWARE_HELM_NAME oci://repo.cybus.io/charts/connectware --version $CONNECTWARE_HELM_VERSION --reuse-values
```

{% endcode %}

8. Monitor the pods and confirm that all transition to the `Running` state and show as `Ready`:

{% code lineNumbers="true" %}

```bash
while [ True ]; do clear; kubectl get pod -lapp.kubernetes.io/part-of=connectware -lapp.kubernetes.io/instance=$CONNECTWARE_HELM_NAME -n $CONNECTWARE_NS ; sleep 5; done
```

{% endcode %}
{% endtab %}

{% tab title="Docker" %}

## Restarting Connectware on Docker

1. Access the system that hosts your Connectware instance via SSH.
2. Navigate to your Connectware installation directory. If you have used the default values during installation, the installation directory is `/opt/connectware`.
3. Stop the current Connectware services:

{% code lineNumbers="true" %}

```bash
docker compose down
```

{% endcode %}

4. Restart Connectware:

{% code lineNumbers="true" %}

```bash
docker compose up -d
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Verifying after Restarting

After restarting Connectware, verify that all services are running correctly:

1. Check the service status via the Admin UI. For more information, see [System Status](/monitoring/system-status) and [Service Logs](/data-flows/services/service-logs).
2. Verify that the connections to the data sources are reestablished.
3. Confirm that any previously configured mappings or workflows are functioning.

## Troubleshooting when Restarting Fails

If Connectware does not start properly after restart:

1. Check logs for errors.
   * For Kubernetes: `kubectl logs -n $CONNECTWARE_NS <podname>`
   * For Docker: `docker compose logs <your-connectware-container>`
2. Verify network connectivity between components.
3. Ensure that the configuration files are valid and correctly formatted.

If problems persist, contact Cybus support at <support@cybus.io>.


# Admin UI

The web-based interface for managing, monitoring, and interacting with Connectware.

The Admin User Interface (**Admin UI**) is the central web-based management console for interacting with your Connectware deployment. It provides a unified platform for configuring, monitoring, and managing all aspects of the system.

While administrators can use the Admin UI to [manage users](/access/user-management), configure services, and [register clients](/access/client-registry), other users also benefit from role-specific capabilities.

For example, depending on assigned roles and permissions:

* Engineers can [deploy or update](/data-flows/services/managing) service commissioning files to define data flows and resource configurations.
* Operators can monitor live production data using tools like the [Data Explorer](/monitoring/data-explorer) and view [system status](/monitoring/system-status) metrics.
* IT and security personnel can review [logs](/data-flows/services/service-logs).

Role-based access control ensures that each user only sees the features and settings relevant to their responsibilities, maintaining both usability and security.

Additionally, all Admin UI functions are also accessible via [REST APIs](/reference/api-reference), allowing seamless integration into enterprise systems and automation pipelines.

## Logging Into the Admin UI

1. Open your browser and enter the IP address of your host (**https\://\<HOST-IP>**).

<figure><img src="/files/H1aeQP16Z6u8AbDsOZvK" alt=""><figcaption></figcaption></figure>

2. Enter your **Username** and **Password**. When setting up Connectware initially, you can use the [default admin user](/access/user-management/users/default-admin-user) to log in.
3. Click **Sign in**.

Now you can explore Connectware.

<figure><img src="/files/Vef1emSDGworSjaZGaqE" alt=""><figcaption></figcaption></figure>

## Finding Your Way Around

The navigation panel groups the Admin UI into the following areas. Which areas you see depends on your [permissions](/access/user-management/permissions).

| Area         | What you find there                                                                                                                                                                                                                                                                                                                                                                             |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Data**     | The [Data Explorer](/monitoring/data-explorer) for browsing the MQTT topic tree and monitoring [live data](/monitoring/live-data).                                                                                                                                                                                                                                                              |
| **Services** | The [service views](/data-flows/services) for installing and managing services, inspecting [resources](/data-flows/services/service-resources-view) such as connections, endpoints, and mappings, reviewing [deviations](/data-flows/services/deviations) and [service logs](/data-flows/services/service-logs), and testing rules in the [Rule Sandbox](/data-flows/rule-engine/rule-sandbox). |
| **User**     | [User Management](/access/user-management) for users, roles, and permissions, the [Client Registry](/access/client-registry), and the [Certificates view](/access/security/tls-certificates/ca-certificates/certificates-view).                                                                                                                                                                 |
| **System**   | The [System Status](/monitoring/system-status) views: container status, Internet connectivity, metrics, [agents](/data-flows/agents/agents-view), license, and system information.                                                                                                                                                                                                              |

## Next Steps

* Change the password of the [default admin user](/access/user-management/users/default-admin-user) before doing anything else in a production environment.
* Create [users and roles](/access/user-management/users) so that every person works with their own account and permissions.
* Strengthen login security with [Multi-Factor Authentication](/access/user-management/multi-factor-authentication) or [Single Sign-On (SSO)](/access/user-management/single-sign-on-sso).
* Install a sample service and watch live machine data arrive in [Connect Your First Machine](/discover/connect-your-first-machine).
* Automate anything you can do in the Admin UI through the [REST APIs](/reference/api-reference).


# User Management

Controlling Connectware access through secure identity management and permissions.

User management in Connectware allows you to control access to your systems through well-defined identities and permissions. This chapter explains how to manage users, roles, and permissions.

{% hint style="info" %}
Managing users and roles requires admin role privileges or corresponding permissions.
{% endhint %}

## Users, Roles, and Permissions

The main concept of managing access in Connectware is done via users, roles, and permissions:

* **Users**: A known identity (person or software/hardware agent) with associated data permissions and/or administrative access. See [Users](/access/user-management/users).
* **Roles**: A group of permissions that can be assigned to multiple users. See [Roles](/access/user-management/roles).
* **Permissions**: Specific access rights to resources (via MQTT topics or HTTP endpoints). See [Permissions](/access/user-management/permissions).

<figure><img src="/files/xJWJR2cNZtcLu6MnvFLj" alt="Users, roles, and permissions"><figcaption><p>Example of users, roles, and permissions</p></figcaption></figure>

## Hardware Devices

For hardware devices connecting to Connectware, we recommend using the [Client Registry](/access/client-registry). Instead of manually creating user accounts through the Admin UI, the Client Registry enables:

* **Self-registration**: Devices can self-register using either MQTT or REST API approaches.
* **Secure credential handling**: Eliminates risks associated with manual password sharing.
* **Certificate support**: Advanced registration with certificate signing requests (CSR) for enhanced security.
* **Controlled approval**: Administrator review of all registration requests before granting access.
* **Granular permission management**: Newly registered devices have no permissions by default, allowing precise control over device capabilities.


# Users

Create and manage users, their roles, and permissions.

In Connectware, users are a known identity (person or software/hardware agent) with associated data permissions and/or administrative access. This chapter guides you through the user management in Connectware, from creating new users to assigning permissions.

Each permission represents a specific access right to a resource, whether it is an MQTT topic or an HTTP endpoint, with clearly defined read and/or write capabilities.

{% hint style="info" %}
Before creating individual users, establish a clear role-based access control strategy by defining roles that correspond to job functions within your organization. This approach simplifies user management and ensures consistent application of security policies.
{% endhint %}

During installation, Connectware creates a default administrator user to ensure immediate system access. This user is named `admin` and has the `connectware-admin` role assigned to provide comprehensive permissions. For more information, see [Default Admin User](/access/user-management/users/default-admin-user).

## Users View

The **Users View** provides a comprehensive view of all users in Connectware, including their assigned roles and permissions.

* To open the **Users View**, click **User** in the navigation panel.

<figure><img src="/files/fWpqr75xHGGeGKqD39Pv" alt=""><figcaption></figcaption></figure>

## Adding New Users

1. In the **Users View**, click **Add User** to open the **Create User** dialog.

<figure><img src="/files/Ybq0XBkR6addre69Yz09" alt=""><figcaption></figcaption></figure>

2. Do one of the following:
   * To add users with pre-defined roles quickly, use the [default mode](#default-mode).
   * To define roles and permissions more granularly, use the [advanced mode](#advanced-mode).

### Default Mode

1. In the **Create User** dialog, enter the username, password, and password confirmation.
2. Optional: To assign a set of pre-defined roles to the user, click the **Roles** field and select a role. You can repeat this step to assign multiple roles.
3. Click **Create**. The dialog will close, and the new user will appear in the overview table.

### Advanced Mode

In the advanced mode, you can assign a set of pre-defined roles to the user and/or individual permissions.

{% hint style="info" %}
We recommend to manage permissions through roles rather than individual user permissions for easier maintenance. For more information, see [Roles](/access/user-management/roles).
{% endhint %}

1. In the **Create User** dialog, enter the username, password, and password confirmation.
2. Activate **Advanced Mode**.

<figure><img src="/files/4T3h91nJl2SJcbaAZ9VU" alt="Advanced Mode in Create User dialog"><figcaption><p>Advanced Mode in Create User dialog</p></figcaption></figure>

3. Optional: To assign a set of pre-defined roles to the user, click the **Roles** field, select a role, and click **Add**. You can repeat this step to assign multiple roles.
4. Optional: To assign individual permissions, click the **+** button to open the **Add Permission** dialog.
   * Select the permission type: **HTTP** for accessing the REST API using HTTP clients or **MQTT** for accessing MQTT topics on CybusMQ.
   * In the **Endpoint** field, enter the resource path, which follows MQTT topic conventions. The specified topic can be a single topic or a wildcard. HTTP permissions for the resource path follow an MQTT topic structure. This means that you can use wildcards (**#** and **+**) in valid expressions, and paths must start with a leading slash (**/**).
   * Select the access type: **read**, **write**, or **both**.
   * Click **Add** to add the permission.

<figure><img src="/files/z0JuZv5gNeJbjFWxPIul" alt="Add Permission button"><figcaption><p>Add Permission button</p></figcaption></figure>

<figure><img src="/files/xsNP7QyHLnUKFYPdl1Ij" alt="Add Permission modal"><figcaption><p>Add Permission modal</p></figcaption></figure>

5. Click **Create**. The dialog will close, and the new user will appear in the overview table.

## Deleting Users

You can delete users that are no longer needed.

{% hint style="warning" %}
Deleting a user is permanent and cannot be undone. Before proceeding, ensure that you have backed up any important user-specific configurations or transferred necessary permissions to other users.
{% endhint %}

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user that you want to delete. This opens the **Edit User** dialog.

<figure><img src="/files/sTK77MSj5w5TBNpzIq9L" alt=""><figcaption></figcaption></figure>

3. Click the **Delete** button in the top right of the **Edit User** dialog.

<figure><img src="/files/WW2vVkb6eRifTC0T3Hnf" alt="Delete button"><figcaption><p>Delete button</p></figcaption></figure>

4. Click **Delete** again to confirm. The user will be deleted.

<figure><img src="/files/XOW7yfteUa8YyDJGBgU8" alt="Delete confirmation"><figcaption><p>Delete confirmation</p></figcaption></figure>

## Changing Usernames

1. In the **Users View**, click the user that you want to edit. This opens the **Edit User** dialog.
2. In the **Edit User** dialog, enter a new username in the **Username** field.
3. Click **Update** to apply the changes. The dialog will close, and the username will be updated.

## Adding Roles to Users

Roles provide a convenient way to assign multiple permissions at once. By adding roles to users, you can quickly grant them access to specific system functions without configuring individual permissions.

{% hint style="info" %}
Assign roles based on job functions or responsibilities rather than individual users to maintain consistent access control across your organization.
{% endhint %}

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user to whom you want to add roles. This opens the **Edit User** dialog.
3. In the **Edit User** dialog, click the **Roles** field to open the list of available roles.

<figure><img src="/files/qzEXHpOZ5IorxytwDylB" alt="Add Role dropdown options"><figcaption><p>Add Role dropdown options</p></figcaption></figure>

4. Click the **Roles** field and select a role. You can repeat this step to assign multiple roles.
5. Click **Update**. The dialog will close and the user will be updated with the selected roles.

<figure><img src="/files/SF6MGPwk7tiVCnp6PoxK" alt=""><figcaption></figcaption></figure>

## Removing Roles from Users

When a user's responsibilities change, you may need to remove roles from them to adjust their access permissions.

{% hint style="warning" %}
Removing a role removes all associated permissions from the user.
{% endhint %}

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user from whom you want to remove roles. This opens the **Edit User** dialog.
3. In the **Edit User** dialog, click the **x** next to the role name in the **Roles** field to remove the role.

<figure><img src="/files/SvJnBhFjAJLn6I3wgYmg" alt="Remove role from user"><figcaption><p>Remove role from user</p></figcaption></figure>

4. Click **Update**. The dialog will close and the user will be updated.

<figure><img src="/files/MbrkTbCd52nEusxFzGZQ" alt=""><figcaption></figcaption></figure>

## Assigning Permissions to Users

While roles are the recommended way to manage permissions, there may be cases where you need to grant specific permissions to individual users without creating a new role.

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user to whom you want to assign individual permissions. This opens the **Edit User** dialog.
3. In the **Edit User** dialog, activate **Advanced Mode**.

<figure><img src="/files/HLKWqYO0cmv2vZHD7Ov7" alt="Activating Advanced Mode in Edit User dialog"><figcaption><p>Activating Advanced Mode in Edit User dialog</p></figcaption></figure>

4. To assign individual permissions, click the **+** button to open the **Add Permission** dialog.
   * Select the permission type: **HTTP** for accessing the REST API using HTTP clients or **MQTT** for accessing MQTT topics on CybusMQ.
   * In the **Endpoint** field, enter the resource path, which follows MQTT topic conventions. The specified topic can be a single topic or a wildcard. HTTP permissions for the resource path follow an MQTT topic structure. This means that you can use wildcards (**#** and **+**) in valid expressions, and paths must start with a leading slash (**/**).
   * Select the access type: **read**, **write**, or **both**.
   * Click **Add** to add the permission.

<figure><img src="/files/s7cOMWKxJmI2rAgrwTuE" alt="Add Permission dialog"><figcaption><p>Add Permission dialog</p></figcaption></figure>

<figure><img src="/files/r4hgc4WdRNe5tym5XWZz" alt="Add Permission modal"><figcaption><p>Add Permission modal</p></figcaption></figure>

5. Click **Update**. The dialog will close, and the user will be updated with the new permissions.

## Removing Permissions from Users

When specific permissions are no longer needed, you can remove them while keeping other permissions intact.

{% hint style="warning" %}
Removing individual permissions does not affect permissions granted through roles. To completely remove access to a resource, ensure the user doesn't have access through any assigned roles.
{% endhint %}

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user to whom you want to assign individual permissions. This opens the **Edit User** dialog.
3. In the **Edit User** dialog, activate **Advanced Mode**.

<figure><img src="/files/HLKWqYO0cmv2vZHD7Ov7" alt="Activating Advanced Mode in Edit User dialog"><figcaption><p>Activating Advanced Mode in Edit User dialog</p></figcaption></figure>

4. To remove a permission, click its **Remove** button in the **Action** column of the permissions list.

<figure><img src="/files/0J5N9c31B4ABjEYXckM4" alt="Remove permission from user"><figcaption><p>Remove permission from user</p></figcaption></figure>

5. Click **Update**. The dialog will close, and the user will be updated.

## Changing User Passwords

Regularly updating passwords is an important security practice.

1. In the navigation panel, click **User**.
2. In the **Users View**, click the user for whom you want to change the password. This opens the **Edit User** dialog.
3. In the **Edit User** dialog, click **Change Password**.

<figure><img src="/files/eqrnEeqIKzY1fqsGRN06" alt="Change Password button"><figcaption><p>Change Password button</p></figcaption></figure>

4. In the **Password** field, enter the new password and confirm it in the **Confirm Password** field.
5. To apply the changes, click **Update**. The dialog will close and the user will be updated with changes.

<figure><img src="/files/7arxbZsfE20VVfjA2Pnm" alt="Change Password dialog"><figcaption><p>Change Password dialog</p></figcaption></figure>


# Default Admin User

Manage the default admin user credentials and access settings.

During installation, Connectware creates a default administrator user to ensure immediate system access. This user is named `admin` and has the `connectware-admin` role assigned to provide comprehensive permissions.

{% hint style="warning" %}
We strongly recommend changing the initial admin username and password after the first login. The configuration parameters described below only set the password during initial installation and cannot be used to change it afterwards. See [Changing Usernames](/access/user-management/users#changing-usernames) and [Changing User Passwords](/access/user-management/users#changing-user-passwords).
{% endhint %}

## Admin User Parameters

The following [configuration parameters](/reference/environment-variables) are available for configuring the admin user.

Parameters differ between Kubernetes and Docker deployments. An important difference is that Kubernetes Helm installations generate a random password when `initialPassword` is not set, whereas Docker installations use the static default password `admin`.

{% tabs %}
{% tab title="Kubernetes Parameters" %}

## Admin User Parameters (Kubernetes)

| Parameter                                         | Description                                                                                                                                                                                                                                                                                                                    | Default value   |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
| `global.authentication.adminUser.initialPassword` | Sets the initial password for the admin user. Must be a plain-text string.                                                                                                                                                                                                                                                     | Random Password |
| `global.authentication.adminUser.existingSecret`  | Name of an existing Kubernetes Secret containing the initial password. The Secret must have a key named `initialPassword` with a Base64-encoded password value. See [Using an Existing Kubernetes Secret for the Initial Admin Password](#using-an-existing-kubernetes-secret-for-the-initial-admin-password-kubernetes-only). | Not set         |
| `global.authentication.adminUser.enabled`         | Enables/disables the admin user. Accepts a boolean value (`true` or `false`). See [Disabling the Default Admin User](#disabling-the-default-admin-user).                                                                                                                                                                       | `true`          |
| {% endtab %}                                      |                                                                                                                                                                                                                                                                                                                                |                 |

{% tab title="Docker Parameters" %}

## Admin User Parameters (Docker)

| Parameter                           | Description                                                                                                                                              | Default value |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `CYBUS_INITIAL_ADMIN_USER_PASSWORD` | Sets the initial password for the admin user. Must be a Base64-encoded string.                                                                           | `admin`       |
| `CYBUS_ADMIN_USER_ENABLED`          | Enables/disables the admin user. Accepts a boolean value (`true` or `false`). See [Disabling the Default Admin User](#disabling-the-default-admin-user). | `true`        |
| {% endtab %}                        |                                                                                                                                                          |               |
| {% endtabs %}                       |                                                                                                                                                          |               |

## Disabling the Default Admin User

{% hint style="warning" %}
Before disabling the default admin user, ensure you have created at least one other user with full administrative permissions. Otherwise, you may lose administrative access to your Connectware installation.
{% endhint %}

You can disable the default admin user after creating custom users that have admin permissions.

If the `global.authentication.adminUser.enabled` Helm value (Kubernetes) or the `CYBUS_ADMIN_USER_ENABLED` environment variable (Docker) is not set, or if it has a value other than `false`, the default admin user is enabled and can log in with suitable credentials.

{% tabs %}
{% tab title="Kubernetes" %}

### Disabling the Default Admin User (Kubernetes)

1. Open the `values.yaml` file.
2. Set the `global.authentication.adminUser.enabled` Helm value to `false`.

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    adminUser:
      enabled: false
```

{% endcode %}

3. Upgrade your Helm chart to apply the Helm configuration changes. For details, see [Applying Helm Configuration Changes](/cybus-helm-charts/working-with-cybus-helm-charts#applying-helm-configuration-changes).

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}

4. Try logging in with the admin user credentials to verify that the account has been disabled. You should receive a "wrong password" error.
   {% endtab %}

{% tab title="Docker" %}

### Disabling the Default Admin User (Docker)

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`. The directory contains an `.env` file that is loaded when starting Connectware.
2. Open the `.env` file.
3. Set the `CYBUS_ADMIN_USER_ENABLED` environment variable to `false`.

{% code lineNumbers="true" %}

```yaml
environment:
  - CYBUS_ADMIN_USER_ENABLED=false
```

{% endcode %}

4. Start or restart Connectware. For more information, see [Restarting Connectware](/deployment/restarting-connectware).
5. Try logging in with the admin user credentials to verify that the account has been disabled. You should receive a "wrong password" error.
   {% endtab %}
   {% endtabs %}

## Using an Existing Kubernetes Secret for the Initial Admin Password (Kubernetes only)

As an alternative to providing the initial admin password using the `global.authentication.adminUser.initialPassword` Helm value, you can specify the name of an existing Kubernetes Secret in the `global.authentication.adminUser.existingSecret` Helm value.

The Secret must contain a key named `initialPassword`. Unlike the `global.authentication.adminUser.initialPassword` Helm value which accepts plain-text passwords, the Secret value must be Base64-encoded. We recommend using an immutable Secret, as the password is only read during initial installation. Changing the Secret later will not update the admin user's password.

1. Create the Kubernetes Secret using your preferred method. The following example creates a Secret with the password `Super_S3cret_Password`, using `echo -n ${MY_PASSWORD} | base64` to encode the password before storing it in the Secret:

{% code lineNumbers="true" %}

```bash
kubectl create secret -n ${NAMESPACE} generic my-initial-admin-password --from-literal="initialPassword=$(echo -n "Super_S3cret_Password" | base64)"
```

{% endcode %}

2. Open the `values.yaml` file.
3. Set the `global.authentication.adminUser.existingSecret` Helm value to the name of the Kubernetes Secret you created.

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    adminUser:
      existingSecret: my-initial-admin-password
```

{% endcode %}

4. Install Connectware using the Helm chart. For more information, see [Install Connectware on Kubernetes](/deployment/installing-connectware/on-kubernetes).

{% code lineNumbers="true" %}

```bash
helm install -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}

5. Try logging in with the admin user credentials to verify that your initial admin user password was applied.


# User Session Expiration

Configure how long user sessions remain valid before re-authentication is required.

You can configure the session expiration time to determine how long a user stays signed in before a new login is required. When the session is close to expiring, the Admin UI shows a ten minute countdown in the top right corner and users receive a warning message.

## Session Expiration Parameters

You can set the session expiration time through the following parameters. The parameter differs between Kubernetes and Docker deployments.

{% tabs %}
{% tab title="Kubernetes Parameters" %}

## Kubernetes Parameter

| Parameter                                | Description                                                                                                                                                                                                                                                                                                                                        | Default |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `global.authentication.tokenExpiryHours` | <p>Defines how long (in hours) a user stays signed in before being logged out for security reasons. After the configured time has passed, the user session expires and a new login is required.<br><br>The Admin UI displays a ten-minute countdown in the top right corner, and users receives a warning ten minutes before the session ends.</p> | `12`    |
| {% endtab %}                             |                                                                                                                                                                                                                                                                                                                                                    |         |

{% tab title="Docker Parameters" %}

## Docker Parameter

| Parameter                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Default |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `CYBUS_AUTH_TOKEN_EXPIRE_TIME_IN_HOURS` | <p>Defines how long (in hours) a user stays signed in before being logged out for security reasons. After the configured time has passed, the user session expires and a new login is required.<br><br>The Admin UI displays a ten-minute countdown in the top right corner, and users receives a warning ten minutes before the session ends. If the variable is not set, or if the value is negative or not a valid number, the system uses the default duration of 12 hours.</p> | `12`    |
| {% endtab %}                            |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |         |
| {% endtabs %}                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |         |

## Setting the Session Expiration Time

You can adjust the session duration by modifying the corresponding parameter for your deployment.

{% tabs %}
{% tab title="Kubernetes" %}

## Changing the Session Expiration Time (Kubernetes)

1. Open the `values.yaml` file.
2. Set the `global.authentication.tokenExpiryHours` Helm value to the desired number of hours.

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    tokenExpiryHours: 8
```

{% endcode %}

3. Upgrade your Helm chart to apply the Helm configuration changes. For details, see [Applying Helm Configuration Changes](/cybus-helm-charts/working-with-cybus-helm-charts#applying-helm-configuration-changes).
   {% endtab %}

{% tab title="Docker" %}

## Changing the Session Expiration Time (Docker)

If the configured value is invalid (e.g. negative or not a valid number), the system reverts to the default duration of twelve hours.

1. Navigate to your Connectware installation directory. The default installation directory is `/opt/connectware`. This directory contains the `.env` file used when starting Connectware.
2. Open the `docker-compose.yml` file.
3. Set the `CYBUS_AUTH_TOKEN_EXPIRE_TIME_IN_HOURS` environment variable to the desired number of hours.

{% code lineNumbers="true" %}

```yaml
environment:
  - CYBUS_AUTH_TOKEN_EXPIRE_TIME_IN_HOURS=8
```

{% endcode %}

4. Start or restart Connectware. For details, see [Restarting Connectware](/deployment/restarting-connectware).
   {% endtab %}
   {% endtabs %}


# Roles

Define permission groups based on job functions and responsibilities.

In Connectware, roles are groups of permissions that can be assigned to multiple users. This simplifies user management by allowing administrators to define standard permission sets based on job functions or responsibilities, rather than configuring permissions individually for each user.

Each permission represents a specific access right to a resource, whether it is an MQTT topic or an HTTP endpoint, with clearly defined read and/or write capabilities.

## Roles View

The **Roles View** provides a comprehensive dashboard of all defined roles in your Connectware system and their associated permissions. This makes it easy to audit your access control structure and identify which permissions are assigned to each role.

* To open the **Roles View**, click **User** and then click the **Roles** tab.

<figure><img src="/files/HedpmGlW0pX6rNso7zWu" alt="Roles View in Connectware"><figcaption><p>Roles View in Connectware</p></figcaption></figure>

In this view, you can quickly identify:

* All available roles in the system.
* The specific permissions assigned to each role.
* Which roles might need modifications based on your security requirements.

## Creating New Roles and Permissions

Creating roles allows you to define permission sets once and apply them to multiple users.

1. In the **Roles View**, click **Add Role** to open the **Create Role** dialog.

<figure><img src="/files/qi670lJUa9PV9l1n6bFw" alt="Add Role button"><figcaption><p>Add Role button</p></figcaption></figure>

2. Enter a name for the new role.
3. Optional: To assign a set of pre-defined permissions to the role, click the **Copy Permissions** field, select a permission, and click **Add**. You can repeat this step to assign multiple permission sets.
4. Optional: To assign individual permissions, click the **+** button to open the **Add Permission** dialog.

* Select the permission type: **HTTP** for accessing the REST API using HTTP clients or **MQTT** for accessing MQTT topics on CybusMQ.
* In the **Endpoint** field, enter the resource path, which follows MQTT topic conventions. The specified topic can be a single topic or a wildcard. HTTP permissions for the resource path follow an MQTT topic structure. This means that you can use wildcards (**#** and **+**) in valid expressions, and paths must start with a leading slash (**/**).
* Select the access type: **read**, **write**, or **both**.
* Click **Add** to add the permission.

5. Click **Create**. The dialog will close, and the new role will appear in the overview table.

## Changing Role Names

To change the name of an existing role:

1. In the **Roles View**, click a role to open the **Edit Role** dialog.
2. In the **Edit Role** dialog, enter a new role name in the **Name** field.

<figure><img src="/files/48qC3DQUYMEM8wihvp63" alt="Edit Role dialog"><figcaption><p>Edit Role dialog</p></figcaption></figure>

3. Click **Update** to apply the changes. The dialog will close and the role name will be updated.

## Adding Permissions to Roles

You can add individual permissions directly to a role as needed.

1. In the navigation panel, click **User**.
2. In the **Users and Roles View**, click the **Roles** tab.
3. In the **Roles View**, click the role to which you want to assign permissions. This opens the **Edit Role** dialog.
4. In the **Edit Role** dialog, click the **+** button to open the **Add Permission** dialog.

* Select the permission type: **HTTP** for accessing the REST API using HTTP clients or **MQTT** for accessing MQTT topics on CybusMQ.
* In the **Endpoint** field, enter the resource path, which follows MQTT topic conventions. The specified topic can be a single topic or a wildcard. HTTP permissions for the resource path follow an MQTT topic structure. This means that you can use wildcards (**#** and **+**) in valid expressions, and paths must start with a leading slash (**/**).
* Select the access type: **read**, **write**, or **both**.
* Click **Add** to add the permission.

4. Click **Update**. The dialog will close and the role is updated with the new permissions.

The updated role will immediately reflect the change, and all users assigned to this role will have the new permissions.

## Removing Permissions from Roles

When specific permissions are no longer needed, you can remove the corresponding endpoint them while keeping other permissions intact.

1. In the navigation panel, click **User**.
2. In the **Users and Roles View**, click the **Roles** tab.
3. In the **Roles View**, click the role you want to modify to open the **Edit Role** dialog.
4. Permissions are organized into tabs for **HTTP** and **MQTT**. Use the tabs to switch between and manage permissions for each protocol.
5. In the list of assigned permissions, locate the permission you want to remove.
6. To remove a permission, click its **Remove** button in the **Action** column of the permissions list.
7. Click **Update**. The dialog will close and the role is updated.

The updated role will immediately reflect the change, and all users assigned to this role will lose the removed permission.

## Deleting Roles

To delete a role:

1. In the **Roles View**, click the role that you want to delete to open the **Edit Role** dialog.
2. Click the **Delete** button in the top right of the **Edit Role** dialog.

<figure><img src="/files/HTA4ymIEuKuSTUPGkQcC" alt="Delete Role button"><figcaption><p>Delete Role button</p></figcaption></figure>

3. Click **Delete** again to confirm. The role is deleted.

<figure><img src="/files/f6c8IElB7dYL0Ubm0xHO" alt="Delete confirmation"><figcaption><p>Delete confirmation</p></figcaption></figure>


# Permissions

Granular access control through resource-specific authorization settings.

In Connectware, permissions are specific access rights to resources. Permissions allow administrators to define who can access which resources and what actions they can perform. Each permission represents a specific access right to a resource, whether it is an MQTT topic or an HTTP endpoint, with clearly defined read and/or write capabilities.

Understanding permissions is crucial for:

* **Security**: Implementing the principle of least privilege across your system.
* **Granularity**: Defining access control at a highly detailed level when necessary.
* **Transparency**: Clearly seeing who has access to specific resources.
* **Compliance**: Meeting regulatory requirements for data access control.

## Configuring Permissions

You can manage permissions via [roles](/access/user-management/roles).

## Permissions View

The **Permissions View** provides a comprehensive overview of all permissions configured in your Connectware environment. This centralized dashboard shows each permission's details, including:

The resource path it controls access to:

* The type of permission (MQTT or HTTP)
* The access level granted (read, write, or both)
* Which users and roles have this permission assigned

This view is particularly valuable for auditing your system's security posture and for troubleshooting access issues that users might encounter.

* To open the **Permissions View**, click **User** in the navigation panel, then click the **Permissions** tab.

<figure><img src="/files/k81RS8do3VWPPdm245kK" alt="Permissions overview"><figcaption><p>Permissions overview</p></figcaption></figure>

## Permission Details

While permissions cannot be edited directly from the Permissions View, you can access detailed information about any permission by clicking on it. This information is valuable for understanding exactly what access a permission grants and which users and roles are affected by it.

When you click on a permission in the **Permissions View**, the **Permission Details** dialog opens, showing:

* The permission's complete resource path
* The permission type (MQTT or HTTP)
* The access level (read, write, or both)
* All users who have this permission directly assigned
* All roles that include this permission

<figure><img src="/files/cyTXqxnFw6uiGUamvTkb" alt="Permission Details dialog"><figcaption><p>Permission Details dialog</p></figcaption></figure>


# MQTT Client Authentication

Configure authentication for MQTT clients connecting to Connectware.

MQTT clients connecting to Connectware authenticate as Connectware users. Connectware supports two authentication methods for MQTT clients: username/password and X.509 certificate-based Mutual TLS (mTLS).

| Method            | Client requirements                         |
| ----------------- | ------------------------------------------- |
| Username/Password | Client must provide username and password   |
| Mutual TLS        | Client must provide valid X.509 certificate |

## Username/Password Authentication

MQTT clients can authenticate using a username and password. This authentication method works with all MQTT connection schemes (TCP, WebSocket, SSL/TLS).

### LDAP Authentication for MQTT Clients

If LDAP is enabled, MQTT clients can authenticate with their LDAP credentials over username/password. On the first MQTT connection attempt, Connectware performs the LDAP lookup, creates the corresponding Connectware user, and assigns roles based on your LDAP configuration.

LDAP-based MQTT authentication works with MQTT 3.1, 3.1.1, and 5. If LDAP is unreachable or the credentials are invalid, Connectware denies the connection and logs the failure.

Successful authentications are cached and do not expire when LDAP roles or group memberships change. To force re-authentication, see [Revoking Access After LDAP Changes (MQTT Clients Only)](/access/user-management/single-sign-on-sso/sso-with-ldap#revoking-access-after-ldap-changes-mqtt-clients-only).

For configuration details, see [Single Sign-On with LDAP](/access/user-management/single-sign-on-sso/sso-with-ldap).

## Mutual TLS Authentication

With mTLS, clients authenticate by presenting a valid X.509 certificate instead of a username and password. Connectware reads the certificate's Common Name (CN) as a username and matches it against a user configured with the certificate grant type. That user's roles and permissions govern which topics the client can access.

The client certificate must be signed by a Certificate Authority that Connectware trusts.

{% hint style="warning" %}
Each Connectware user can authenticate with either username/password or certificate-based authentication, not both. Configure the grant type per user in the Admin UI.
{% endhint %}

### Setting Up Mutual TLS

To use mTLS, complete the following steps in Connectware:

1. **Add your CA to the `cybus_ca.crt` certificate bundle** so that Connectware can verify client certificates issued by your organization. See [CA Certificates](/access/security/tls-certificates/ca-certificates).
2. **Enable certificate-based authentication for each user** by setting the grant type to certificate in the user's settings in the Admin UI. See [Client Certificates](/access/security/tls-certificates/client-certificates) for the full setup procedure, including CSR generation and certificate signing.

## MQTT Permissions

Once authenticated, MQTT clients can interact with topics based on the permissions assigned to their corresponding Connectware user:

| Permission  | Allowed actions            |
| ----------- | -------------------------- |
| `read`      | Subscribe to topics        |
| `write`     | Publish to topics          |
| `readWrite` | Both subscribe and publish |

{% hint style="info" %}
To manage MQTT user permissions efficiently, create specific roles with appropriate topic permissions and assign them to users rather than configuring permissions individually. For more information, see [Permissions](/access/user-management/permissions).
{% endhint %}


# Adding an MQTT Publish Prefix

Configure a per-user topic prefix that Connectware adds to every MQTT message the user publishes.

In Connectware it is possible to configure specific users so that every MQTT message published by this user gets an additional prefix added to its MQTT topic. That is, if a user *UserA* has a configured MQTT publish prefix *topicA/*, and once this user publishes a message to topic *some/values*, the message will be published on the topic *topicA/some/values*.

This feature simplifies the configuration for use cases where a fixed routing to a downstream application is required. This could be achieved just as well by using Mapping resources, but those would require an additional MQTT message transfer per topic mapping, which can be skipped by the prefix feature. Hence this feature is particularly suited for high-throughput installations with high performance in the MQTT message delivery.

Note: The required MQTT write permissions for this user must be specified *including* the MQTT prefix, because the permissions should specify the eventual locations on the global MQTT topic tree. In the above example, an *UserA* with prefix *topicA/* would need the MQTT write permission for *topicA/some/values* in order to be allowed to write to that target topic. If it is needed to omit the prefix in the permission specification, MQTT wildcards might be a useful placeholder instead of the publish prefix, for example by specifying *+/some/values*.

The configuration of the MQTT prefix can be done either by HTTP requests at the REST endpoint `/api/users/<userId>`, or in the Admin-UI when editing users in the user management.

## Admin-UI Configuration

In the Admin-UI, to add an MQTT prefix to an existing user, edit the `MQTT Publish Prefix` text field in the *Edit User* dialog.

1. Toggle the `Advanced mode` switch in the top right of the dialog.

<figure><img src="/files/HLKWqYO0cmv2vZHD7Ov7" alt=""><figcaption><p>This will extend the dialog with an <code>Additional permissions</code> section.</p></figcaption></figure>

<figure><img src="/files/hdpHmVgVQNJ5QfS4e5H4" alt=""><figcaption></figcaption></figure>

2. Edit the MQTT Publish Prefix

<figure><img src="/files/Zd7ty55XXs4Z7cPPxBk9" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
The configured MQTT prefix should include the trailing topic level separator `/` at the end! The topic prefixing feature will not insert any separator automatically, hence the trailing separator must be part of the configuration here.
{% endhint %}

## Example

As an example for setting up and validating a publishing prefix for user `newuser`:

1. Add the MQTT prefix `route-to-downstream/` using the *Edit User* dialog as explained above.
2. Add an MQTT write permission for the topic ‘route-to-downstream/my-topic’ (i.e. including the prefix) for this user on the user’s management screen.

To validate that this setting works as expected, one can send some MQTT message with some MQTT client, for example the `mosquitto_sub` and `mosquitto_pub` command line tools (need to be installed before).

3. Subscribe for a topic `route-to-downstream/my-topic` with the following command:

{% code lineNumbers="true" %}

```yaml
mosquitto_sub -h 127.0.0.1 -p 1883 -u admin -P <ADMIN PASSWORD> \
-t 'route-to-downstream/my-topic'
```

{% endcode %}

4. Publish a message on the topic `my-topic` with the following command:

{% code lineNumbers="true" %}

```yaml
mosquitto_pub -h 127.0.0.1 -p 1883 -u newuser -P <PASSWORD NEW USER> \
-t 'my-topic' -m 'Hello World'
```

{% endcode %}

The subscribed client should then receive the published message ‘Hello World’ on the prefixed topic *route-to-downstream/my-topic*.


# Multi-Factor Authentication

Add an extra layer of security to Connectware accounts with one-time codes from an authentication app.

Multi-factor authentication (MFA), also known as 2-factor authentication, allows you to add an extra layer of security to your Connectware account. With MFA, you need a one-time code generated by an authentication app in addition to your main Connectware password to sign in.

If you do not have access to your authentication device, you can use backup codes to sign in or ask a Connectware admin to disable your MFA. Connectware admins can disable MFA for each user individually.

## Prerequisites for Multi-Factor Authentication

### General

* **Offline access**: Multi-factor authentication can be used even without an internet connection.
* **Microsoft Entra ID limitation**: Multi-factor authentication is not available when using [Microsoft Entra ID](/access/user-management/single-sign-on-sso/sso-with-microsoft-entra-id) for authentication.

### For Administrators (MFA Implementation)

To configure multi-factor authentication, administrators need to modify the Connectware configuration file:

* **Kubernetes**: Modify the `values.yaml` file.
* **Docker**: Modify the `.env` file.

### For Users (MFA Usage)

* **MFA enabled**: Your organization has enabled multi-factor authentication for your Connectware account.
* **Usage**: Multi-factor authentication can be optional or mandatory depending on your organization's settings.
* **Authentication apps**: You have installed a time-based one-time password (TOTP) authentication app such as:
  * Google Authenticator
  * Microsoft Authenticator
  * Authy
  * FreeOTP

## Configuration Parameters (Multi-Factor Authentication)

Configure the following environment variables to enable multi-factor authentication.

{% tabs %}
{% tab title="Helm Values" %}

## Helm Values (Multi-Factor Authentication)

| Helm value                                   | Description                                                                                                           | Status                                         |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `global.authentication.mfa.enabled`          | If set to `true`, multi-factor authentication is enabled. If set to `false`, multi-factor authentication is disabled. | **Required**                                   |
| `global.authentication.mfa.encryptionSecret` | Primary encryption key that secures MFA.                                                                              | **Required**<mark style="color:red;">\*</mark> |
| `global.authentication.mfa.encryptionSalt`   | Random value added to strengthen the encryption process.                                                              | **Required**<mark style="color:red;">\*</mark> |
| `global.authentication.mfa.existingSecret`   | The name of your existing Kubernetes secret that contains the `encryptionSecret` and `encryptionSalt` values.         | **Required**<mark style="color:red;">\*</mark> |
| `global.authentication.mfa.issuer`           | The entity name displayed in the MFA app for authentication.                                                          | Optional                                       |
| `global.authentication.mfa.label`            | The identifier shown in the MFA app, typically the username or account name.                                          | Optional                                       |

{% hint style="danger" %} <mark style="color:red;">Important \*</mark> You must provide either `encryptionSecret` and `encryptionSalt` or provide the `existingSecret`. For enhanced security, use `existingSecret`. For more information, see [Using Kubernetes Secrets (Recommended)](#using-kubernetes-secrets-recommended).
{% endhint %}
{% endtab %}

{% tab title="Environment Variables" %}

## Environment Variables (Multi-Factor Authentication)

| Environment variable                  | Description                                                                                                                                                      | Status       |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `CYBUS_MFA_ENABLED`                   | If set to `true`, multi-factor authentication is enabled. If set to `false`, multi-factor authentication is disabled.                                            | **Required** |
| `CYBUS_MFA_ENCRYPTION_SECRET`         | Primary encryption key that secures MFA.                                                                                                                         | **Required** |
| `CYBUS_MFA_ENCRYPTION_SALT`           | Random value added to strengthen the encryption process. Must be base64-encoded.                                                                                 | **Required** |
| `CYBUS_MFA_MAX_INVALID_OTPS_PER_USER` | Sets how many times a user can enter an incorrect one-time password when logging in with multi-factor authentication before their account is temporarily locked. | Optional     |
| `CYBUS_MFA_BAN_DURATION_MINUTES`      | Sets the lockout period (in minutes) after too many failed one-time password attempts when logging in with multi-factor authentication.                          | Optional     |
| `CYBUS_MFA_ISSUER`                    | The entity name displayed in the MFA app for authentication.                                                                                                     | Optional     |
| `CYBUS_MFA_LABEL`                     | The identifier shown in the MFA app, typically the username or account name.                                                                                     | Optional     |
| {% endtab %}                          |                                                                                                                                                                  |              |
| {% endtabs %}                         |                                                                                                                                                                  |              |

### Encryption Secrets and Salt

The multi-factor authentication system uses two critical security components:

* **Secret**: An encryption key for securing MFA tokens.
* **Salt**: A random value that enhances encryption strength.

You must specify both values as base64-encoded strings.

{% hint style="warning" %}
Changing the encryption secret or salt will invalidate all existing MFA configurations, requiring users to reconfigure their MFA settings. Keep these values secure. If compromised, an attacker could potentially bypass authentication.
{% endhint %}

## Configuring Connectware to Support Multi-Factor Authentication

To use multi-factor authentication with a new Connectware installation or with your existing Connectware setup, you must update your Connectware configuration file. The update procedure depends on your current installation method.

* **Kubernetes**: Modify the `values.yaml` file.
* **Docker**: Modify the `.env` file.

{% tabs %}
{% tab title="Kubernetes Configuration" %}

## Multi-Factor Authentication Configuration for Kubernetes

There are two ways to configure multi-factor authentication encryption settings in your Kubernetes deployment. You must choose one of these methods:

* **Kubernetes secrets (recommended)**: Use [Kubernetes secrets](#using-kubernetes-secrets-recommended) to store your encryption values.
* **Clear text values**: Write the encryption values directly in your `values.yaml` file [in clear text](#using-clear-text-values).

### Using Kubernetes Secrets (Recommended)

1. Create a Kubernetes secret. The values in Kubernetes secrets must be base64-encoded strings.

{% code lineNumbers="true" %}

```bash
kubectl create secret generic my-mfa-secret --from-literal=encryptionSecret=$(echo -n "18473274-5073-11ee-be56-0242ac120002" | base64)  --from-literal=encryptionSalt=$(echo -n "229c75c2-5073-11ee-be56-0242ac120002" | base64)
```

{% endcode %}

2. Open the `values.yaml` file.
   * Now you must configure the helm file to enable multi-factor authentication.
3. Configure the following helm values to enable and configure multi-factor authentication.

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    mfa:
      # Enable multi-factor authentication
      enabled: true
      # The name of your existing Kubernetes secret that contains the encryptionSecret and encryptionSalt values
      existingSecret: my-mfa-secret
```

{% endcode %}

4. Optional: Specify the allowed number of invalid one-time password attempts and the lockout period after too many failed one-time password attempts.

{% code lineNumbers="true" %}

```yaml
authServer:
  env:
    # Specify the allowed number of invalid one-time password attempts
    - name: CYBUS_MFA_MAX_INVALID_OTPS_PER_USER
      value: '5'
    # Specify the lockout period after too many failed one-time password attempts in minutes
    - name: CYBUS_MFA_BAN_DURATION_MINUTES
      value: '10'
```

{% endcode %}

5. After configuring your `values.yaml` file, deploy or update Connectware by running the following Helm command:

{% hint style="info" %}
Make sure to adjust the command parameters based on your specific setup:

* Installation name (currently set to `connectware`)
* Namespace (currently set to `cybus`)
* Path and filename of your values file (currently set to `values.yaml`)
  {% endhint %}

{% code lineNumbers="true" %}

```bash
helm upgrade --install connectware -n cybus oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}

### Using Clear Text Values

{% hint style="warning" %}
Storing encryption secrets and salt values in clear text within your `values.yaml` file is not recommended for production environments. Instead, use Kubernetes secrets to manage these sensitive values securely. The clear text configuration shown below should only be used for development or testing purposes.
{% endhint %}

1. Open the `values.yaml` file.
   * Now you must configure the helm file to enable multi-factor authentication.
2. Configure the following helm values to enable and configure multi-factor authentication.

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    mfa:
      # Enable multi-factor authentication
      enabled: true
      # Clear text secret key for encrypting MFA secrets
      encryptionSecret: '18473274-5073-11ee-be56-0242ac120002'
      # Clear text salt value for encrypting MFA secrets
      encryptionSalt: '229c75c2-5073-11ee-be56-0242ac120002'
```

{% endcode %}

3. Optional: Specify the allowed number of invalid one-time password attempts and the lockout period after too many failed one-time password attempts.

{% code lineNumbers="true" %}

```yaml
authServer:
  env:
    # Specify the allowed number of invalid one-time password attempts
    - name: CYBUS_MFA_MAX_INVALID_OTPS_PER_USER
      value: '5'
    # Specify the lockout period after too many failed one-time password attempts in minutes
    - name: CYBUS_MFA_BAN_DURATION_MINUTES
      value: '10'
```

{% endcode %}

4. After configuring your `values.yaml` file, deploy or update Connectware by running the following Helm command:

{% hint style="info" %}
Make sure to adjust the command parameters based on your specific setup:

* Installation name (currently set to `connectware`)
* Namespace (currently set to `cybus`)
* Path and filename of your values file (currently set to `values.yaml`)
  {% endhint %}

{% code lineNumbers="true" %}

```bash
helm upgrade --install connectware oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}
{% endtab %}

{% tab title="Docker Configuration" %}

## Multi-Factor Authentication Configuration for Docker

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`. The directory contains an `.env` file that is loaded when starting Connectware.
2. Open the `.env` file.
   * Now you must configure the `.env` file to enable multi-factor authentication.
3. Configure the following environment variables to enable and configure multi-factor authentication.

{% code lineNumbers="true" %}

```yaml
environment:
    # Enable multi-factor authentication
    CYBUS_MFA_ENABLED=true

    # Multi-factor authentication encryption credentials
    CYBUS_MFA_ENCRYPTION_SECRET=18473274-5073-11ee-be56-0242ac120002
    CYBUS_MFA_ENCRYPTION_SALT=229c75c2-5073-11ee-be56-0242ac120002
```

{% endcode %}

4. Optional: Specify the allowed number of invalid one-time password attempts and the lockout period after too many failed one-time password attempts.

{% code lineNumbers="true" %}

```yaml
environment:
    # Specify the allowed number of invalid one-time password attempts
    CYBUS_MFA_MAX_INVALID_OTPS_PER_USER=5

    # Specify the lockout period after too many failed one-time password attempts in minutes
    CYBUS_MFA_BAN_DURATION_MINUTES=10
```

{% endcode %}

5. After configuring the environment variables, restart Connectware by running `docker compose up -d` in your installation directory.

For a list of all environment variables for Docker Compose, see [Docker Compose](/reference/environment-variables#docker-compose).
{% endtab %}
{% endtabs %}

## Setting up Multi-Factor Authentication

1. On the navigation panel, click **Settings**.
2. Click **Enable Multi-Factor Authentication**.
3. Open your authentication app and do one of the following:

* Scan the QR code.
* Enter your secret key.

The authentication app generates a one-time 6-digit code.

4. Enter the one-time 6-digit code in the **Register Device** fields and click **Enable Multi-Factor Authentication**. Connectware displays a list of backup codes. If you do not have access to your authentication device, you can use a backup code instead of a one-time 6-digit code. You can use each backup code only once. Alternatively, you can ask a Connectware admin to disable your MFA.
5. Copy and paste the backup codes to a safe location.

## Signing in with Multi-Factor Authentication

1. On the Connectware login screen, enter your **Username** and **Password**.
2. Click **Sign In**.
3. Open the authentication app and select your Connectware account.
4. Enter the one-time 6-digit code displayed on the authentication app.

## Signing in with Multi-Factor Authentication Backup Codes

If you have no access to your multi-factor authentication app, you can use backup codes instead of a one-time 6-digit code to sign in to Connectware. Backup codes are displayed when you set up multi-factor authentication.

This gives you access to Connectware in case you have misplaced your authentication device, uninstalled your authentication app or removed Connectware from your authentication app.

{% hint style="warning" %}
You can use each backup code only once.
{% endhint %}

1. On the Connectware login screen, enter your **Username** and **Password**.
2. Click **Sign In**.
3. Click **Use backup code**.
4. In the **Backup Code** field, enter your backup code and click **Sign In**.

## Disabling Multi-Factor Authentication (User)

You must have access to your authentication app to disable multi-factor authentication.

{% hint style="warning" %}
If you do not have access to your authentication app, ask a Connectware admin to disable your multi-factor authentication.
{% endhint %}

1. On the navigation panel, click **Settings**.
2. In the **Multi-Factor Authentication** section, click **Disable Multi-Factor Authentication**.
3. Open the authentication app and select your Connectware account.
4. Enter the one-time 6-digit code displayed on the authentication app.
5. Click **Disable Multi-Factor Authentication**.

## Disabling Multi-Factor Authentication (Admin)

As a Connectware admin, you can disable multi-factor authentication for each user individually.

1. On the navigation panel, select **User Management > Users and Roles**.
2. Click the user for which you want to disable the multi-factor authentication.
3. In the **MFA** row, click **Disable**.
4. Click **Update**.

## Regenerate Backup Codes

You must have access to your authentication app to regenerate multi-factor authentication backup codes.

1. On the navigation panel, click **Settings**.
2. In the **Multi-Factor Authentication** section, click **Regenerate Backup Codes**.
3. Open the authentication app and select your Connectware account.
4. Enter the one-time 6-digit code displayed on the authentication app in the text field.
5. Click **Regenerate Backup Codes**.

## Making Multi-Factor Authentication Mandatory for Individual Users (Admin)

As a Connectware admin, you can set multi-factor authentication to be the mandatory login method for individual users.

{% hint style="warning" %}
For LDAP users, you can set `CYBUS_LDAP_AUTO_ENFORCE_MFA` to `true` to make multi-factor authentication the mandatory login method for all new LDAP users. For more information, see [Connectware LDAP Parameters](/access/user-management/single-sign-on-sso/sso-with-ldap#connectware-ldap-parameters).
{% endhint %}

1. On the navigation panel, select **User Management > Users and Roles**.
2. Click the user for which you want to make multi-factor authentication mandatory.
3. In the **MFA (Required)** row, click **Enable**.
4. Click **Update**.


# Single Sign-On (SSO)

Let users sign in to Connectware with a single set of credentials via Microsoft Entra ID or LDAP.

Single sign-on (SSO) is an authentication mechanism that enables users to access multiple applications and services with a single set of credentials. Instead of managing separate usernames and passwords for each application, users can authenticate once and gain access to all connected systems without having to log in again.

Connectware supports the following single sign-on authentication providers:

* [Microsoft Entra ID](/access/user-management/single-sign-on-sso/sso-with-microsoft-entra-id)
* [LDAP](/access/user-management/single-sign-on-sso/sso-with-ldap)


# Single Sign-On with Microsoft Entra ID

Configure Microsoft Entra ID as the identity provider for single sign-on in Connectware.

{% hint style="info" %}
Entra ID integration requires a Connectware Enterprise license.
{% endhint %}

You can configure Microsoft Entra ID (formerly Azure Active Directory) as the identity provider for single sign-on in Connectware.

## Configuring Single Sign-On with Entra ID

In order to set up single sign-on with Entra ID, you must complete the following tasks:

1. Configure Entra ID in the Microsoft Entra admin center for Connectware authentication.
2. Update the Connectware configuration with the Entra ID information.
   * **Kubernetes**: Modify the `values.yaml` file.
   * **Docker**: Modify the `.env` file.
3. Configure Connectware to use Entra ID as the identity provider.

For more information on Microsoft Entra, see the [Microsoft Entra documentation](https://learn.microsoft.com/en-us/entra/).

## Prerequisites

* **License**: Connectware Enterprise license required. For more information, see [cybus.io](https://www.cybus.io/en/product/licenses/).
* **Microsoft Entra admin center**: Access to the Microsoft Entra admin center (<https://entra.microsoft.com>).
* **Configuration**: Access to the Connectware configuration file.
  * **Kubernetes**: Modify the `values.yaml` file.
  * **Docker**: Modify the `.env` file.

{% hint style="warning" %}
[Multi-factor authentication](/access/user-management/multi-factor-authentication) is not available when using Entra ID as your authentication provider.
{% endhint %}

## Entra ID Information to Provide to Connectware

When configuring Entra ID, you will obtain the following information that you must note down for configuring the Entra ID setup in Connectware at a later stage of the setup procedure.

| Information             | Description                                                                                                                                                                                                                                                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Application (client) ID | The application (client) ID in Entra ID is a unique identifier that is assigned to Connectware when you register it in Entra ID. It is used to identify Connectware to Entra ID when users sign in.                                                                                                                    |
| Directory (tenant) ID   | The directory (tenant) ID in Entra ID is a unique identifier that represents your organization's directory instance.                                                                                                                                                                                                   |
| Client secret           | The client secret in Entra ID is a confidential key that Connectware uses together with the Application (client) ID to authenticate itself with Entra ID when requesting tokens.                                                                                                                                       |
| Redirect URI            | A URI (Uniform Resource Identifier) that specifies the Connectware URL that users will be redirected to after authenticating with Entra ID. When configuring Connectware for Entra, you'll set this URI via the `callBackDomain` parameter (Kubernetes) or the `CYBUS_MS_ENTRA_ID_CALLBACK_DOMAIN` parameter (Docker). |

## Connectware Entra ID Parameters

Configure the following environment variables to enable Entra ID authentication. Parameters differ between Kubernetes and Docker deployments.

{% tabs %}
{% tab title="Kubernetes Parameters" %}

## Kubernetes Entra ID Parameters

| Helm value                                           | Description                                                                                                                                                                                                                                       | Status                                         |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `global.authentication.entraId.enabled`              | <p>If set to <code>true</code>, Entra ID is enabled. If set to <code>false</code>, Entra ID is disabled.<br><br>Default: <code>false</code><br>Schema type: boolean</p>                                                                           | **Required**                                   |
| `global.authentication.entraId.clientId`             | <p>Your Application (client) ID as provided by Entra ID<br><br>Schema type: string</p>                                                                                                                                                            | **Required**                                   |
| `global.authentication.entraId.tenantId`             | <p>Your Directory (tenant) ID as provided by Entra ID<br><br>Schema type: string</p>                                                                                                                                                              | **Required**                                   |
| `global.authentication.entraId.clientSecret`         | <p>Confidential key (in plain text) for authenticating with Entra ID. <code>clientSecret</code> is ignored if <code>existingClientSecret</code> is defined.<br><br>Schema type: string</p>                                                        | **Required**<mark style="color:red;">\*</mark> |
| `global.authentication.entraId.existingClientSecret` | <p>Name of an existing Kubernetes secret containing the client secret<br><br>Schema type: base64-encoded string</p>                                                                                                                               | **Required**<mark style="color:red;">\*</mark> |
| `global.authentication.entraId.callbackDomain`       | <p>Specifies the Connectware URL that users will be redirected to after authenticating with their Entra ID credentials<br>Schema type: string</p>                                                                                                 | **Required**                                   |
| `global.authentication.entraId.issuerUrl`            | <p>Identity provider's token issuing URL<br><br>Schema type: string</p>                                                                                                                                                                           | Optional                                       |
| `global.authentication.entraId.usernameMappingField` | <p>User attribute to use as username. If not set, the default value is used.<br><br>Default: <code>preferred\_username</code><br>Allowed values:<code>name</code> , <code>oid</code>, <code>preferred\_username</code><br>Schema type: string</p> | Optional                                       |

{% hint style="danger" %} <mark style="color:red;">Important \*</mark> You must provide either `clientSecret` or `existingClientSecret`. For enhanced security, use `existingClientSecret` instead of `clientSecret`. When you use `existingClientSecret`, you must base64-encode the string value of the secret before storing it in the Kubernetes Secret. This results in a double base64-encoded value.
{% endhint %}
{% endtab %}

{% tab title="Docker Parameters" %}

## Docker Entra ID Parameters

| Environment variable                       | Description                                                                                                                                                                                                                                       | Status       |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `CYBUS_MS_ENTRA_ID_ENABLED`                | <p>If set to <code>true</code>, Entra ID is enabled. If set to <code>false</code>, Entra ID is disabled.<br><br>Default: <code>false</code><br>Schema type: boolean</p>                                                                           | **Required** |
| `CYBUS_MS_ENTRA_ID_CLIENT_ID`              | <p>Your Application (client) ID as provided by Entra ID<br><br>Schema type: string</p>                                                                                                                                                            | **Required** |
| `CYBUS_MS_ENTRA_ID_TENANT_ID`              | <p>Your Directory (tenant) ID as provided by Entra ID<br><br>Schema type: string</p>                                                                                                                                                              | **Required** |
| `CYBUS_MS_ENTRA_ID_CLIENT_SECRET`          | <p>Confidential key (in plain text) for authenticating with Entra ID. To use the client secret in your <code>.env</code> file, you must encode it to base64.<br><br>Schema type: string</p>                                                       | **Required** |
| `CYBUS_MS_ENTRA_ID_CALLBACK_DOMAIN`        | <p>Specifies the Connectware URL that users will be redirected to after authenticating with their Entra ID credentials<br>Schema type: string</p>                                                                                                 | **Required** |
| `CYBUS_MS_ENTRA_ID_ISSUER_URL`             | <p>Identity provider's token issuing URL<br><br>Schema type: string</p>                                                                                                                                                                           | Optional     |
| `CYBUS_MS_ENTRA_ID_USERNAME_MAPPING_FIELD` | <p>User attribute to use as username. If not set, the default value is used.<br><br>Default: <code>preferred\_username</code><br>Allowed values:<code>name</code> , <code>oid</code>, <code>preferred\_username</code><br>Schema type: string</p> | Optional     |
| {% endtab %}                               |                                                                                                                                                                                                                                                   |              |
| {% endtabs %}                              |                                                                                                                                                                                                                                                   |              |

## Redirect URIs in Microsoft Entra Authentication

When authenticating users, you must configure a redirect URI for Microsoft Entra authorization. This redirect URI serves as a critical security mechanism that ensures authentication codes and tokens reach only their intended destination.

A redirect URI (or response URL) specifies where Microsoft Entra will send users after authenticating with their Entra ID credentials. For Connectware, the redirect URI must point to the endpoint where your Connectware instance is running.

## Configuring Entra ID

This section guides you through the required configuration steps in the Microsoft Entra admin center.

{% stepper %}
{% step %}

### Registering Connectware in Entra ID

1. Go to the Microsoft Entra admin center (<https://entra.microsoft.com>) and log in.
2. In the sidebar, select **Identity** > **Applications** > **App registrations**.
3. Click **New registration**.
4. Enter the **Name** of your registration. For example, `connectware`.
5. Click **Register**.
6. In the **Overview** section, note down the following values. You will need these values for configuring your Connectware setup. For more information, see [Entra ID Information to Provide to Connectware](#entra-id-information-to-provide-to-connectware).
   * **Application (client) ID**
   * **Directory (tenant) ID**
     {% endstep %}

{% step %}

### Defining the Redirect URI

You must define a redirect URI (Uniform Resource Identifier). This is the Connectware URL that users will be redirected to after authenticating with their Entra ID credentials. When configuring Connectware for Entra ID in a later step, you will need to enter the redirect URI as the value for the `callBackDomain` parameter (Kubernetes) or the `CYBUS_MS_ENTRA_ID_CALLBACK_DOMAIN` parameter (Docker).

1. Click **Authentication**.
2. In the **Platform configurations** section, click **Add platform**.
3. In the **Configure platforms** section, click **Web**.
4. In the **Redirect URIs** field, enter your redirect URI. This is the Connectware URL that users will be redirected to after authenticating with their Entra ID credentials.
5. Click **Configure**.
6. In the **Implicit grant and hybrid flows** section, activate **ID tokens (used for implicit and hybrid flows)**.
7. Click **Save**.
   {% endstep %}

{% step %}

### Creating Client Secrets

Credentials enable confidential applications to identify themselves to the authentication service when receiving tokens at a web addressable location.

1. Click **Certificates & secrets**.
2. In the **Client secrets** section, click **New client secret**.
3. In the **Add a client secret** section, enter a description and the expiration time period.
4. Click **Add**.
5. Note down the client secret key displayed in the **Value** column.

{% hint style="danger" %}
After initial setup, you cannot see the client secret key. If you did not record the client secret key, you must generate a new one.
{% endhint %}
{% endstep %}

{% step %}

### Changing the Token Configuration

You must configure optional claims in Entra ID. Optional claims are used to configure additional information which is returned in one or more tokens.

1. Click **Token configuration**.
2. In the **Optional claims** section, click **Add groups claim**.
3. In the **Select group types** section, select your group type. We suggest to use **Security groups**. Depending on your Entra ID setup, you may need to select **Groups assigned to the application**. This option is recommended for large enterprise companies to avoid exceeding the limit on the number of groups a token can emit. If you are unsure which group type to select, consult your Entra ID administrator.
4. In the **Customize token properties by type** section, click **ID** and select **Group ID**.
5. Click **Add**.
   {% endstep %}
   {% endstepper %}

## Configuring Connectware to Support Entra ID

This section shows you how to update your Connectware configuration files to integrate with Entra ID.

To use Entra ID with a new Connectware installation or with your existing Connectware setup, you must update your Connectware configuration file. The update procedure depends on your current installation method.

* If you're running Connectware on Docker, you must update your `.env` file.
* If you're running Connectware on Kubernetes, you must update your `values.yaml` file.

{% hint style="info" %}
During the following update procedure, you need to enter the [Entra ID information](#entra-id-information-to-provide-to-connectware) that you have noted down during the [Entra ID configuration](#configuring-entra-id) in the Microsoft Entra admin center.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes Configuration" %}

## Entra ID Configuration for Kubernetes

1. Open the `values.yaml` file.
   * Now you must configure the helm file to enable Entra ID. For this, you need the [Entra ID information](#entra-id-information-to-provide-to-connectware) that were provided when [configuring Entra ID](#configuring-entra-id).
2. Configure the following helm values to enable and configure Entra ID. For a list of all Kubernetes Entra ID parameters, see [Kubernetes Entra ID Parameters](#kubernetes-entra-id-parameters):

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    entraId:
      enabled: true
      clientId: <your-client-id>
      tenantId: <your-tenant-id>
      existingClientSecret: <your-kubernetes-secret> # must be double base64-encoded
      callbackDomain: <your-redirect-uri>
```

{% endcode %}

{% hint style="danger" %}
You must provide either `clientSecret` or `existingClientSecret`. For enhanced security, use `existingClientSecret` instead of `clientSecret`. When you use `existingClientSecret`, you must base64-encode the string value of the secret before storing it in the Kubernetes Secret. This results in a double base64-encoded value.
{% endhint %}

3. Optional: Customize the username mapping field via the following Helm value:

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    entraId:
      enabled: true
      # Specify custom field mappings (optional)
      usernameMappingField: <mapping-fields>
```

{% endcode %}

4. After configuring your `values.yaml` file, deploy or update Connectware using the following command:

{% code lineNumbers="true" %}

```bash
helm upgrade --install connectware oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}
{% endtab %}

{% tab title="Docker Configuration" %}

## Entra ID Configuration for Docker

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`. The directory contains an `.env` file that is loaded when starting Connectware.
2. Open the `.env` file.
   * Now you must configure the `.env` file to enable Entra ID. For this you need the [Entra ID information](#entra-id-information-to-provide-to-connectware) that were provided when [configuring Entra ID](#configuring-entra-id).
3. Configure the following environment variables to enable and configure Entra ID. Make sure that you have encoded your client secret as base64. For a list of all Docker Entra ID parameters, see [Docker Entra ID Parameters](#docker-entra-id-parameters):

{% code lineNumbers="true" %}

```yaml
environment:
    # Enable Entra ID authentication
    CYBUS_MS_ENTRA_ID_ENABLED=true

    # Entra ID application credentials
    CYBUS_MS_ENTRA_ID_CLIENT_ID=<your-client-id>
    CYBUS_MS_ENTRA_ID_CLIENT_SECRET=<your-client-secret-encoded-as-base64>
    CYBUS_MS_ENTRA_ID_TENANT_ID=<your-tenant-id>

    # Authentication callback URL
    CYBUS_MS_ENTRA_ID_CALLBACK_DOMAIN=<your-redirect-uri>
```

{% endcode %}

4. Optional: Customize the username mapping field via the following environment variable:

{% code lineNumbers="true" %}

```yaml
environment:
  # Specify custom field mappings (optional)
  CYBUS_MS_ENTRA_ID_USERNAME_MAPPING_FIELD=<mapping-fields>
```

{% endcode %}

5. After configuring the environment variables, [restart Connectware](/deployment/restarting-connectware).

For a list of all environment variables for Docker Compose, see [Docker Compose](/reference/environment-variables#docker-compose).
{% endtab %}
{% endtabs %}

## Configuring User Groups

This section explains how to configure user group permissions through the [Admin UI](/access/admin-ui).

In order to use user groups with Entra ID, you must create user groups in the Microsoft Entra admin center that match their intended Connectware roles. These groups enable role synchronization between Entra ID and Connectware, ensuring users have appropriate permissions when accessing the system.

You can create flexible mappings between Entra ID groups and Connectware roles through a many-to-many relationship:

* You can assign a single Entra ID group to multiple Connectware roles
* You can link a single Connectware role to multiple Entra ID groups

**Example:** For Connectware, you want to give your IT department admin permissions and your engineering department restricted permissions. In Entra ID, you have defined the groups `it` and `engineering`. In Connectware, you then assign the `it` ID to the `connectware-admin` role and the `engineering` ID to the `minimum-access` role. Now, when someone from the IT department logs into Connectware, the Connectware admin permissions are granted. If someone from engineering logs into Connectware, minimum access permissions are granted.

{% stepper %}
{% step %}

### Creating Groups in Entra ID

You can create new groups in Entra ID for each Connectware role that you need. Changes in Entra ID group membership are reflected in Connectware upon next user login.

If you already have existing groups in Entra ID that you want to use with Connectware, you can skip this section and proceed to [Configuring Roles in Connectware](#configuring-roles-in-connectware).

1. In the Microsoft Entra admin center, select **Identity** > **Groups** > **Overview**.
2. Click **New group**.
3. Enter a **Group type**, **Group name**, and **Membership type**.
4. Click **Create**.
5. Repeat these steps for each group that you need to create for your Connectware roles.
   {% endstep %}

{% step %}

### Configuring Roles in Connectware

1. In Connectware, click **User** on the navigation panel.
2. Select the **Roles** tab.
3. Click the role that you want to synchronize with an Entra ID group.
4. In the **Edit Role** dialog, enter the ID of the Entra ID group in the **ObjectID of Entra** field and press **Enter**. To link multiple Entra ID groups to a role, enter the group IDs of the Entra ID groups as a comma-separated list without spaces. Example: `id-1,id-2,id-3`
5. Click **Update**.
   {% endstep %}

{% step %}

### Verifying the Group Setup

* After configuring user groups, make sure to verify the permissions by testing with users from different departments.
  {% endstep %}
  {% endstepper %}

## Signing in with Entra ID

After [Entra ID configuration](#configuring-single-sign-on-with-microsoft-entra-id) is complete, you can access Connectware using your Entra ID credentials.

* To log in with your Entra ID login, click **Sign in with Entra ID** on the Connectware login screen.

<figure><img src="/files/8nLD1UcTIzZE0xpNJS23" alt=""><figcaption></figcaption></figure>

## Configuring Entra ID in Connectware via API

Besides configuring Entra ID via the Connectware UI, you can also configure Entra ID in Connectware via the Connectware API. For more information, see the [Auth-Server API](/reference/api-reference/auth-server-api) for user management configurations.


# Single Sign-On with LDAP

Configure LDAP Single Sign-On authentication and authorization for Connectware users with Active Directory or OpenLDAP integration.

{% hint style="info" %}
LDAP integration requires a Connectware Enterprise license.
{% endhint %}

LDAP (Lightweight Directory Access Protocol) is a standardized protocol for accessing directory services. In Connectware, LDAP can be used to authenticate users and MQTT clients and to assign permissions based on information from your directory service, such as Microsoft Active Directory or OpenLDAP.

This page shows how to enable LDAP login in Connectware, choose an authorization model, and configure your directory so users receive the correct roles.

## Prerequisites

* Connectware Enterprise license required. For more information, see [cybus.io](https://www.cybus.io/en/product/licenses/).
* Active Directory or OpenLDAP server reachable from Connectware.
* LDAP user and group structure prepared according to the configuration steps on this page.

## How LDAP Works in Connectware

Connectware uses LDAP in two steps:

1. **Authentication**: When a user signs in or an MQTT client connects, Connectware verifies the username and password against your LDAP directory.
2. **Authorization**: After successful authentication, Connectware assigns Connectware roles to the user based on your LDAP configuration.

Connectware creates a corresponding user in its internal user database on the first successful authentication, whether that happens through the Admin UI, the REST API, or an MQTT client connection. On each subsequent successful authentication, role assignments are synchronized from LDAP. If the LDAP lookup or synchronization fails, authentication is denied and the failure is logged.

You can choose between the following authorization modes:

* **Group mode**: Roles are assigned based on LDAP group membership.
* **Attribute mode**: Roles are assigned based on LDAP user attributes.

In both cases, role management happens in LDAP, not in Connectware.

## Choose Your LDAP Authentication Method

Decide how Connectware authenticates users against your LDAP directory. This choice depends on how your directory is structured and how users are organized within it.

Connectware provides the following methods for LDAP authentication:

* Authentication with a dedicated bind user
* Authentication without a dedicated bind user (direct user authentication)

A bind user is common in LDAP setups with complex directory structures. It is a limited user that you create in your LDAP directory. This user is usually read-only and has permission to search the LDAP directory tree.

You use it when users do not share a single LDAP base DN (i.e., when they are not in the same group). If your users are spread throughout the directory tree, you will likely want to use a bind user.

### Direct Authentication Without a Dedicated Bind User

You can authenticate without a dedicated bind user when your LDAP structure meets the following requirements:

* All user entries are located in the same branch of the LDAP Directory Information Tree (DIT)
* All users share the same base DN
  * Example: The base DN is `ou=users,dc=corp,dc=com` and the DN of all users follows the pattern `<RDN_OF_USER>,ou=users,dc=corp,dc=com`
* Groups are not nested
  * Example of unsupported nesting: A user is a member of `group A`, `group A` is a member of `group B`, and `group B` is the group linked with a Connectware role.

When no dedicated bind user is used, Connectware takes the given `bindDn`, adds the `userRdn`, and binds with the user credentials to the LDAP server. Binding with user credentials is the actual authentication step with an LDAP server.

### Authentication Using a Dedicated Bind User

A dedicated bind user is required when your LDAP structure requires searches or involves complex group relationships. Configure this by setting the `CYBUS_LDAP_BIND_PASSWORD` environment variable.

You need this authentication method when:

* User entries are distributed across different DIT locations
  * Example:
    * User 1: `cn=user1,ou=production,dc=corp,dc=com`
    * User 2: `cn=user2,ou=operations,dc=corp,dc=com`
  * In this case, Connectware needs to search from a common base DN (`dc=corp,dc=com`) to locate user entries
* Your setup uses nested groups
  * The search base must be the common DN shared by all groups and users

If your directory needs additional constraints (e.g., multiple branches), configure a custom LDAP search filter. See [LDAP Search Filters](#ldap-search-filter).

## Choose Your LDAP Authorization Mode

Connectware supports the following LDAP authorization modes:

* **Group mode**: Sets permissions based on LDAP group membership.
* **Attribute mode**: Sets permissions based on LDAP user attributes.

### Group Mode

Connectware roles can be associated with LDAP groups. When an LDAP user successfully logs in for the first time, a Connectware user is created. Depending on the LDAP group memberships of the LDAP user, corresponding roles are assigned to the Connectware user automatically. This way, permissions can be easily managed by adding or removing LDAP users to or from the related LDAP groups.

**Example**

You can link the Connectware role `LDAP-Admin` to an LDAP group `cn=cw-admin,ou=connectware,dc=corp,dc=com`. Users in this group automatically receive the role when logging in.

For more information, see [Example Setup for Group Mode](#example-setup-for-group-mode).

### Attribute Mode

When an LDAP user successfully logs in for the first time, a Connectware user is created. A custom attribute in the LDAP user entry specifies which roles should be automatically assigned to the Connectware user. Authorization is controlled by adding or removing Connectware role names in the LDAP user's attributes.

**Example**

If the custom attribute `employeeType` contains the value `connectware-admin`, the admin role is assigned to the user.

For more information, see [Example Setup for Attribute Mode](#example-setup-for-attribute-mode).

## Enable LDAP Authentication

{% tabs %}
{% tab title="Kubernetes" %}

### Enabling LDAP Authentication (Kubernetes)

1. To enable the LDAP feature in Connectware, set the `global.authentication.ldap.enabled` Helm value to `true`.
2. Additionally, provide the following Helm values within the `global.authentication.ldap` context:

| Value    | Example                    | Description                                                                                                                      |
| -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `bindDn` | `ou=users,dc=corp,dc=com`  | Base DN for direct authentication **or** full DN of a dedicated bind user. See [parameter table](#helm-values-ldap) for details. |
| `url`    | `ldap://ldap.corp.com:389` | URL of the LDAP server in format `scheme://hostname:port`.                                                                       |

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: ou=users,dc=corp,dc=com
      url: ldap://ldap.corp.com:389
```

{% endcode %}

If you are using a bind user to search through the directory tree, you must specify the full DN of the bind user as `bindDn` and provide the following additional values:

| Value          | Example           | Description                                                   |
| -------------- | ----------------- | ------------------------------------------------------------- |
| `bindPassword` | `ANc97WCO"!xcC=(` | Password for the bind user as defined in your LDAP server.    |
| `searchBase`   | `dc=corp,dc=com`  | Base DN for searching users when using a dedicated bind user. |

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: cn=binduser,ou=users,dc=corp,dc=com
      bindPassword: <password of binduser>
      url: ldap://ldap.corp.com:389
      searchBase: dc=corp,dc=com
```

{% endcode %}

If you do not want to provide the bind user and its password through Helm values (for example, when following a GitOps approach), you can reference an existing Kubernetes secret via `existingBindSecret`. For more information, see [Bind User Credentials via Existing Kubernetes Secret](#bind-user-credentials-via-existing-kubernetes-secret).

3. After enabling LDAP authentication, you must configure how Connectware derives user roles from LDAP. This is controlled through the `mode` setting in the `global.authentication.ldap` context. Connectware supports `group` mode and `attribute` mode.

For more information, see [Choose Your LDAP Authorization Mode](#choose-your-ldap-authorization-mode).
{% endtab %}

{% tab title="Docker Compose" %}

### Enabling LDAP Authentication (Docker Compose)

For a list of all environment variables for Docker, see [Environment Variables](/reference/environment-variables).

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`.
2. The directory contains an `.env` file that is loaded when starting Connectware. Open the `.env` file in a text editor of your choice.
3. Locate the LDAP settings section in the `.env` file. By default, the settings look like this:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=false
CYBUS_LDAP_URL=
CYBUS_LDAP_MODE=
CYBUS_LDAP_BIND_DN=
CYBUS_LDAP_BIND_PASSWORD=
CYBUS_LDAP_SEARCH_BASE=
CYBUS_LDAP_ROLES_ATTRIBUTE=
CYBUS_LDAP_MEMBER_ATTRIBUTE=
CYBUS_LDAP_USER_RDN=
```

{% endcode %}

4. Set the individual parameters according to your local directory service configuration.
5. To set up a configuration with direct authentication (no dedicated bind user), do the following:

Example configuration for LDAP mode `attribute`:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=attribute
CYBUS_LDAP_BIND_DN=ou=users,dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_USER_RDN=cn
CYBUS_LDAP_ROLES_ATTRIBUTE=employeeType
```

{% endcode %}

Example configuration for LDAP mode `group`:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=group
CYBUS_LDAP_BIND_DN=ou=users,dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_USER_RDN=cn
CYBUS_LDAP_MEMBER_ATTRIBUTE=memberOf
```

{% endcode %}

This configuration would look for users matching the LDAP query `cn=username,ou=users,dc=corp,dc=com`.

{% hint style="warning" %}
Do not use quotation marks to encapsulate the variable values.
{% endhint %}

6. To set up a configuration with a dedicated bind user, do the following:

Example configuration for LDAP mode `attribute`:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=attribute
CYBUS_LDAP_BIND_DN=cn=binduser,ou=users,dc=corp,dc=com
CYBUS_LDAP_BIND_PASSWORD=<password of binduser>
CYBUS_LDAP_SEARCH_BASE=dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_USER_RDN=cn
CYBUS_LDAP_ROLES_ATTRIBUTE=employeeType
```

{% endcode %}

Example configuration for LDAP mode `group`:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=group
CYBUS_LDAP_BIND_DN=cn=binduser,ou=users,dc=corp,dc=com
CYBUS_LDAP_BIND_PASSWORD=<password of binduser>
CYBUS_LDAP_SEARCH_BASE=dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_USER_RDN=cn
CYBUS_LDAP_MEMBER_ATTRIBUTE=memberOf
```

{% endcode %}

Make sure to change the RDN prefix (`cn`) if needed for `CYBUS_LDAP_BIND_DN=cn=binduser,ou=users,dc=corp,dc=com`.

7. After saving the new configuration, do one of the following:

* If your Connectware instance is running as a system service, run `systemctl restart connectware` to restart it.
* Otherwise, run `docker compose up -d` from within the installation folder to restart it.

The new configuration is now loaded. The next step is to supply your directory service users with Connectware roles (LDAP mode `attribute`) or link LDAP groups with Connectware roles (LDAP mode `group`).
{% endtab %}
{% endtabs %}

## Configure LDAP Parameters

Once the authentication method and authorization model are defined, configure the LDAP parameters required by Connectware. The available parameters depend on the deployment type and the chosen configuration path.

The following tables list all supported LDAP parameters for Kubernetes and Docker Compose deployments.

{% tabs %}
{% tab title="Helm Values" %}

### Helm Values (LDAP)

| Helm value                                                                                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `global.authentication.ldap.enabled`                                                                                                                 | `true/false`. Enables LDAP integration.                                                                                                                                                                                                                                                                                                                                       |
| `global.authentication.ldap.bindDn`                                                                                                                  | <p><strong>Without <code>bindPassword</code>:</strong> Base DN where all user entries are located (e.g., <code>ou=users,dc=corp,dc=com</code>).<br><strong>With <code>bindPassword</code>:</strong> Full DN of a dedicated bind user (e.g., <code>cn=binduser,ou=users,dc=corp,dc=com</code>).</p>                                                                            |
| <p><code>global.authentication.ldap.bindPassword</code><br><strong>or</strong> <code>global.authentication.ldap.existingBindSecret</code></p>        | <p>Password for the dedicated bind user <strong>or</strong> reference a Secret with keys <code>bindDn</code> and <code>bindPassword</code>. When provided, <code>bindDn</code> must contain the full DN of the bind user, and <code>searchBase</code> becomes required.<br><strong>Note:</strong> If both are provided, <code>existingBindSecret</code> takes precedence.</p> |
| `global.authentication.ldap.searchBase`                                                                                                              | Base DN for searching users. **Required only when using a dedicated bind user** (i.e., when `bindPassword` is set).                                                                                                                                                                                                                                                           |
| `global.authentication.ldap.searchFilter`                                                                                                            | Optional custom user search filter; overrides default username-based lookup. See [LDAP Search Filters](#ldap-search-filter).                                                                                                                                                                                                                                                  |
| `global.authentication.ldap.url`                                                                                                                     | LDAP/AD server URL, e.g., `ldap://host:389` or `ldaps://host:636`.                                                                                                                                                                                                                                                                                                            |
| `global.authentication.ldap.mode`                                                                                                                    | `group` or `attribute`.                                                                                                                                                                                                                                                                                                                                                       |
| `global.authentication.ldap.rolesAttribute`                                                                                                          | LDAP attribute containing Connectware roles. Used only with `mode: attribute`.                                                                                                                                                                                                                                                                                                |
| `global.authentication.ldap.memberAttribute`                                                                                                         | LDAP attribute indicating group memberships (often `memberOf`). Used only with `mode: group`.                                                                                                                                                                                                                                                                                 |
| `global.authentication.ldap.userRdn`                                                                                                                 | LDAP user property (e.g., `cn`) used as the username at login.                                                                                                                                                                                                                                                                                                                |
| `global.authentication.ldap.caChain.trustAllCertificates`                                                                                            | `true` accepts all certificates (not recommended). Default is `false`.                                                                                                                                                                                                                                                                                                        |
| <p><code>global.authentication.ldap.caChain.cert</code><br><strong>or</strong> <code>global.authentication.ldap.caChain.existingConfigMap</code></p> | <p>Provide full CA chain in PEM via <code>cert:</code> <strong>or</strong> reference a ConfigMap (file must be <code>ca.crt</code>). No file path option.<br><strong>Note:</strong> If both are provided, <code>existingConfigMap</code> takes precedence.</p>                                                                                                                |
| `global.authentication.ldap.autoEnforceMfa`                                                                                                          | Enforce MFA for LDAP users after first login. Requires `global.authentication.mfa.enabled: true` and keys configured.                                                                                                                                                                                                                                                         |
| {% endtab %}                                                                                                                                         |                                                                                                                                                                                                                                                                                                                                                                               |

{% tab title="Environment Variables" %}

### Environment Variables (LDAP)

| Parameter                     | Description                                                                                                                                                                                                                                                                                                                      |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CYBUS_LDAP_ENABLED`          | Enables LDAP integration when set to `true`. If `false`, LDAP is disabled and all other LDAP parameters are ignored.                                                                                                                                                                                                             |
| `CYBUS_LDAP_BIND_DN`          | <p><strong>Without <code>CYBUS\_LDAP\_BIND\_PASSWORD</code>:</strong> Base DN where all user entries are located (e.g., <code>ou=users,dc=corp,dc=com</code>).<br><strong>With <code>CYBUS\_LDAP\_BIND\_PASSWORD</code>:</strong> Full DN of a dedicated bind user (e.g., <code>cn=binduser,ou=users,dc=corp,dc=com</code>).</p> |
| `CYBUS_LDAP_BIND_PASSWORD`    | Password for the dedicated bind user. When provided, `CYBUS_LDAP_BIND_DN` must contain the full DN of the bind user, and `CYBUS_LDAP_SEARCH_BASE` becomes required.                                                                                                                                                              |
| `CYBUS_LDAP_SEARCH_BASE`      | Base DN for searching users. **Required only when using a dedicated bind user** (i.e., when `CYBUS_LDAP_BIND_PASSWORD` is set). Example: `dc=corp,dc=com`.                                                                                                                                                                       |
| `CYBUS_LDAP_SEARCH_FILTER`    | Optional custom filter for user search requests. Only valid with a dedicated bind user. See [LDAP Search Filters](#ldap-search-filter).                                                                                                                                                                                          |
| `CYBUS_LDAP_URL`              | The URL of the LDAP/AD server.                                                                                                                                                                                                                                                                                                   |
| `CYBUS_LDAP_MODE`             | Specifies the LDAP mode: Either `group` or `attribute`.                                                                                                                                                                                                                                                                          |
| `CYBUS_LDAP_ROLES_ATTRIBUTE`  | LDAP attribute containing user roles. Only valid with `CYBUS_LDAP_MODE=attribute`.                                                                                                                                                                                                                                               |
| `CYBUS_LDAP_MEMBER_ATTRIBUTE` | LDAP attribute for group memberships. Only valid with `CYBUS_LDAP_MODE=group`. Usually set to `memberOf`.                                                                                                                                                                                                                        |
| `CYBUS_LDAP_USER_RDN`         | LDAP user property (e.g., `cn`) containing the username used for Connectware login.                                                                                                                                                                                                                                              |
| `CYBUS_LDAPS_TRUST_ALL_CERTS` | When `true`, accepts all servers without certificate verification for Secure LDAP. Default is `false`.                                                                                                                                                                                                                           |
| `CYBUS_LDAPS_CA_FILE`         | <p>Path to CA file for LDAP server validation. Used with Secure LDAP when <code>CYBUS\_LDAPS\_TRUST\_ALL\_CERTS</code> is <code>false</code>.<br><strong>Note:</strong> The CA file must be mounted into the container for this path to be accessible.</p>                                                                       |
| `CYBUS_LDAP_AUTO_ENFORCE_MFA` | When `true`, enforces MFA for LDAP users after their first login.                                                                                                                                                                                                                                                                |
| {% endtab %}                  |                                                                                                                                                                                                                                                                                                                                  |
| {% endtabs %}                 |                                                                                                                                                                                                                                                                                                                                  |

## Example LDAP Setups

This section shows a complete Docker example setup for both authorization models.

Each example follows the same structure: LDAP preparation, Connectware configuration, and role assignment behavior. You can use these examples as a reference and adapt them to your own directory structure.

### Example Setup for Group Mode

In order to assign permissions to Connectware users by grouping their LDAP user entries with LDAP groups, you need to perform the following steps:

1. Define LDAP groups according to Connectware roles that you want to use.
2. Configure Connectware with LDAP parameters.
3. Link LDAP groups with Connectware roles.
4. Assign LDAP users to these LDAP groups.

{% stepper %}
{% step %}

#### Define LDAP Groups According to Connectware Roles

In this example, additional groups are created and associated with Connectware roles. This is not a mandatory practice, but is intended to demonstrate the concept.

We assume that we have the following DIT structure:

{% code lineNumbers="true" %}

```
dc=corp,dc=com
├ ou=users
│  ├ cn=user1
│  ├ cn=user2
│  └ cn=user3
└ ou=connectware
```

{% endcode %}

1. Create the groups `cw-admin` and `cw-minimal` as follows:

{% code lineNumbers="true" %}

```
dc=corp,dc=com
├ ou=users
│  ├ cn=user1
│  ├ cn=user2
│  └ cn=user3
└ ou=connectware
   ├ cn=cw-minimal
   └ cn=cw-admin
```

{% endcode %}

2. Now add `user1` to `cw-minimal`.
3. Run the following command to retrieve and display all attributes for `user1`. Make sure to change `PASSWORD` to the actual password of `user1`.

{% code lineNumbers="true" %}

```bash
ldapsearch -LLL -b "cn=user1,ou=users,dc=corp,dc=com" -D "cn=user1,ou=users,dc=corp,dc=com" -w PASSWORD
```

{% endcode %}

Result of the command:

{% code lineNumbers="true" %}

```
dn: cn=user1,ou=users,dc=corp,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: user1
...
memberOf: cn=cw-minimal,ou=connectware,dc=corp,dc=com
...
```

{% endcode %}

4. If you are using OpenLDAP and you do not see the `memberOf` attribute, run the following command:

{% code lineNumbers="true" %}

```bash
ldapsearch -LLL -b "cn=user1,ou=users,dc=corp,dc=com" -D "cn=user1,ou=users,dc=corp,dc=com" -w PASSWORD +
```

{% endcode %}

* If you can see the `memberOf` attribute, your LDAP is correctly configured for group operations. You can proceed with the next configuration steps.
* If the `memberOf` attribute is not visible, your OpenLDAP installation lacks the required `memberOf` module. In this case, your OpenLDAP instance needs additional configuration.
  {% endstep %}

{% step %}

#### Configure Connectware with LDAP Parameters

* Edit the `.env` file as follows:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=group
CYBUS_LDAP_BIND_DN=ou=users,dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_MEMBER_ATTRIBUTE=memberOf
CYBUS_LDAP_USER_RDN=cn
```

{% endcode %}

Make sure to adjust the LDAP URL to match your environment.
{% endstep %}

{% step %}

#### Linking LDAP Groups with Connectware Roles

1. Log into Connectware as administrator and select **User** > **User Management**. Select the **Roles** tab and click **Add Role**.
2. In the **Create Role** dialog, do the following:

   1. In the **Name** field, enter `LDAP-Admin`.
   2. To associate this role with the LDAP group `cw-admin`, copy the DN of that LDAP group to the field **DN of AD Group**. In this example, this will be `cn=cw-admin,ou=connectware,dc=corp,dc=com`.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>The field is labeled "DN of AD Group" in the UI, but it accepts the DN of any LDAP group, whether from Active Directory or OpenLDAP.</p></div>

   3. In the **Copy Permissions** field, select **connectware-admin** and click **Add**.
   4. Click **Create** to add your new role.
3. Click **Add Role** again to add another role with the following configuration:
   1. In the **Name** field, enter `LDAP-Minimal`.
   2. In the **DN of AD Group** field, add the DN of the related LDAP group (`cn=cw-minimal,ou=connectware,dc=corp,dc=com`).
   3. In the **Copy Permissions** field, select **minimum-access** and click **Add**.
   4. Click **Create** to add your new role.

<figure><img src="/files/xlX8UBFN24cE5rmsvBn6" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Assigning LDAP Users to LDAP Groups

1. You can assign different Connectware roles to your users `user1`, `user2`, and `user3` by adding them to or removing them from the groups `cw-minimal` or `cw-admin`.
2. When you add `user1` to the group `cw-admin` and log into Connectware, `user1` will be created (if it is the first login) and the role `LDAP-Admin` will be assigned automatically.
3. Log out from Connectware, remove `user1` from group `cw-admin`, and add it to `cw-minimal`.
4. Log into Connectware with `user1` again. `user1` has limited access and you cannot navigate to the user section. Permissions of `user1` changed according to the LDAP group membership.

If you log in as `user2` and `user2` is not assigned to any LDAP group yet, `user2` will be created but you will see an error dialog saying that no permission was added and thus you will be forced to log out again.
{% endstep %}
{% endstepper %}

### Example Setup for Attribute Mode

1. LDAP setup.
2. Configure Connectware with LDAP parameters.
3. Assign roles to the LDAP user entry.

{% stepper %}
{% step %}

#### LDAP Setup

The following examples assume that you have an LDAP DIT structure like the following:

{% code lineNumbers="true" %}

```
dc=corp,dc=com
└ ou=users
   ├ cn=user1
   └ cn=user2
```

{% endcode %}

This structure is not mandatory, but be aware to adjust the following examples according to your LDAP setup in the next steps.
{% endstep %}

{% step %}

#### Configuring Connectware with LDAP Parameters

* Edit your `.env` file as follows:

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_MODE=attribute
CYBUS_LDAP_BIND_DN=ou=users,dc=corp,dc=com
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_ROLES_ATTRIBUTE=employeeType
CYBUS_LDAP_USER_RDN=cn
```

{% endcode %}

Make sure to replace the `CYBUS_LDAP_URL` with your actual LDAP server address and port.
{% endstep %}

{% step %}

#### Assigning Roles to LDAP User Entry

1. To assign roles to LDAP users, you have to add the Connectware role names as values to the user's **CYBUS\_LDAP\_ROLES\_ATTRIBUTE** that you defined in the `.env` file. In our example, we will use the attribute name `employeeType`.
2. To add the Connectware role `connectware-admin` to the LDAP user `user1`, add the attribute `employeeType` (defined as the roles attribute in the `.env` file) with the value `connectware-admin` to the LDAP user `user1`.
3. Add the Connectware role `minimum-access` to `user2` by adding the attribute `employeeType` with the value `minimum-access` to the LDAP user `user2`.
4. Check if the attributes have been set correctly by running the following command:

{% code lineNumbers="true" %}

```bash
ldapsearch -LLL -b "cn=user1,ou=users,dc=corp,dc=com" -D "cn=user1,ou=users,dc=corp,dc=com" -w PASSWORD
```

{% endcode %}

Result of the command:

{% code lineNumbers="true" %}

```
dn: cn=user1,ou=users,dc=corp,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: user1
...
employeeType: connectware-admin
...
```

{% endcode %}

5. If you now log into Connectware as `user1`, the Connectware role `connectware-admin` will be assigned to user `user1`.
6. To revoke access to Connectware for a certain user, the Connectware roles just have to be removed from the LDAP user by deleting the corresponding attribute `employeeType`.

Connectware comes with predefined user roles like `connectware-admin` and `minimum-access`, but additional roles can be created and assigned to users in the same way.
{% endstep %}
{% endstepper %}

## User Management for LDAP Users in Connectware

When LDAP authentication is enabled, user management in Connectware differs from local user accounts. These differences are important to understand when operating and troubleshooting an LDAP-based setup.

<figure><img src="/files/cxUk2pnniM4jarDsyiZM" alt=""><figcaption></figcaption></figure>

When using LDAP authentication, Connectware user management differs from regular local user accounts in several aspects. The following sections detail these differences and explain how LDAP users are handled within Connectware.

<figure><img src="/files/JBHFG3JgPt3b80NpcGhd" alt=""><figcaption></figcaption></figure>

### Roles

You cannot add or remove roles from within Connectware. All roles have to be assigned in the user details of the directory user. Modified user roles are synchronized to the Connectware user on each successful login.

### Grant Types

Every LDAP user defaults to token authentication. This property is not modifiable.

### LDAP User Password

You cannot change the password from within Connectware as it uses the LDAP directory service for authentication.

### Deleting LDAP Users

You can still remove LDAP users from the Connectware user database. Note that this only deletes the Connectware internal user information. Deleting this local user information will not prevent the user from logging into Connectware again.

To fully revoke access, you must either remove their Connectware roles in LDAP or remove them from LDAP groups associated with Connectware roles, depending on your integration mode.

### Revoking Access After LDAP Changes (MQTT Clients Only)

MQTT authentications are cached in Connectware and do not expire automatically when you change LDAP roles or group memberships. To force re-authentication against LDAP, do the following:

1. Delete or update the affected Connectware user in the [Admin UI](/access/user-management/users#deleting-users).
2. [Restart Connectware](/deployment/restarting-connectware).

## Advanced LDAP Configuration

### Customizing the User RDN

The user RDN (relative distinguished name) defines which LDAP attribute is used to identify a user during authentication.

By default, Connectware uses the `cn` attribute as the user identifier during login. This means the username entered at the Connectware login screen is mapped to an LDAP distinguished name constructed with `cn=<username>`.

You may need to change the user RDN if your directory uses a different attribute to identify users, for example, `uid`, `sn`, or `sAMAccountName`. In such cases, you must configure Connectware to use the appropriate LDAP attribute as the user RDN.

* The configured user RDN must match the directory schema used for user entries.
* When using direct authentication without a dedicated bind user, the user RDN is combined with the base DN to form the bind DN.
* When using a dedicated bind user, the user RDN is used during the search operation to locate the user entry.

Make sure the chosen attribute uniquely identifies users within the configured search scope.

Configuration examples for Kubernetes and Docker Compose are provided in the following sections.

{% tabs %}
{% tab title="Kubernetes Configuration" %}

#### Customizing the User RDN (Kubernetes)

1. In the `values.yaml` file, configure the `global.authentication.ldap.userRdn` Helm value.

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: ou=users,dc=corp,dc=com
      url: ldap://ldap.corp.com:389
      userRdn: uid
```

{% endcode %}

With this configuration, Connectware uses `uid=<username>` instead of `cn=<username>` when authenticating users.

2. Apply the configuration changes by running the `helm upgrade` command.

**Example**

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware -f values.yaml
```

For details, see [Applying Helm Configuration Changes](/cybus-helm-charts/working-with-cybus-helm-charts#applying-helm-configuration-changes).
{% endtab %}

{% tab title="Docker Compose Configuration" %}

#### Customizing the User RDN (Docker Compose)

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`.
2. The directory contains an `.env` file that is loaded when starting Connectware. Open the `.env` file in a text editor of your choice.
3. Locate the LDAP settings section in the `.env` file and configure the `CYBUS_LDAP_USER_RDN` environment variable.

**Example**

{% code lineNumbers="true" %}

```bash
CYBUS_LDAP_ENABLED=true
CYBUS_LDAP_URL=ldap://ldap.corp.com:389
CYBUS_LDAP_BIND_DN=ou=users,dc=corp,dc=com
CYBUS_LDAP_USER_RDN=uid
```

{% endcode %}

With this configuration, Connectware constructs user DNs using `uid=<username>`.
{% endtab %}
{% endtabs %}

### TLS for LDAP Authentication

You can secure LDAP communication by using LDAPS. When TLS is enabled, Connectware validates the certificate presented by the LDAP server.

You can choose from the following options:

* Use a certificate signed by a trusted root CA.
* Provide a custom CA certificate chain to Connectware.
* Disable certificate validation for non-production environments.

{% tabs %}
{% tab title="Kubernetes" %}

#### Enabling TLS for LDAP Authentication (Kubernetes)

1. To enable TLS for LDAP, set a valid `ldaps://` URL for the Helm value `url` in the `global.authentication.ldap` context.
2. Adjust the TCP port number. By default, LDAPS uses port 636.
   {% endtab %}

{% tab title="Docker Compose" %}

#### Enabling TLS for LDAP Authentication (Docker Compose)

1. To enable TLS for LDAP, set a valid `ldaps://` URL for `CYBUS_LDAP_URL`.
2. Adjust the TCP port number. By default, LDAPS uses port 636.
   {% endtab %}
   {% endtabs %}

#### Providing the CA Certificate

{% tabs %}
{% tab title="Kubernetes" %}
**Providing the CA Certificate through Helm Values**

* To provide the CA certificate, set the Helm value `caChain.cert` in the `global.authentication.ldap` context. Provide the complete certificate chain necessary to validate the LDAP server's certificate.

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: ou=users,dc=corp,dc=com
      url: ldaps://ldap.corp.com:636
      caChain:
        cert: |
          -----BEGIN CERTIFICATE-----
          MIIFpTCCA40CFGFL86145m7JIg2RaKkAVCOV1H71MA0GCSqGSIb3DQEBCwUAMIGN
          [skipped for brevity - include whole certificate]
          SKnBS1Y1Dn2e
          -----END CERTIFICATE-----
```

{% endcode %}

As an alternative, you can provide the CA certificate through a manually created [Kubernetes ConfigMap](#providing-the-ca-certificate-through-a-kubernetes-configmap).

**Providing the CA Certificate through a Kubernetes ConfigMap**

To provide the CA certificate necessary to validate the certificate used by your LDAP server, you can manually create a Kubernetes ConfigMap that contains the certificate as a file named ca.crt. You will then provide the name of this ConfigMap in the Helm value `caChain.existingConfigMap` in the `global.authentication.ldap` context.

**Example**

* Create the Kubernetes ConfigMap from a file named ca.crt in your current directory:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} create cm cw-ldap-ca-cert --from-file=ca.crt
```

{% endcode %}

* Specify the name of the ConfigMap:

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: ou=users,dc=corp,dc=com
      url: ldaps://ldap.corp.com:636
      caChain:
        existingConfigMap: cw-ldap-ca-cert
```

{% endcode %}
{% endtab %}

{% tab title="Docker Compose" %}
**Providing the CA Certificate through Environment Variables**

* To provide the CA certificate, set `CYBUS_LDAPS_CA_FILE` to the path where the certificate will be available inside the container. Provide the complete certificate chain necessary to validate the LDAP server's certificate.
* The CA certificate file must be mounted into the Connectware container.
  {% endtab %}
  {% endtabs %}

#### Disabling Certificate Validation

While we do not recommend skipping certificate validation for production use, it is possible to tell Connectware to accept any certificate the LDAP server presents.

{% tabs %}
{% tab title="Kubernetes" %}
**Disabling Certificate Validation (Kubernetes)**

* To disable certificate validation, set the Helm value `caChain.trustAllCertificates` in the `global.authentication.ldap` context to `true`.

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: ou=users,dc=corp,dc=com
      url: ldaps://ldap.corp.com:636
      caChain:
        trustAllCertificates: true
```

{% endcode %}
{% endtab %}

{% tab title="Docker Compose" %}
**Disabling Certificate Validation (Docker Compose)**

* To disable certificate validation, set `CYBUS_LDAPS_TRUST_ALL_CERTS` to `true`.
  {% endtab %}
  {% endtabs %}

### LDAP Search Filter

Connectware uses an LDAP search filter to locate a user entry during authentication. The filter is constructed dynamically based on the configured user RDN, the username entered during login, and an optional custom filter extension.

#### Filter Format and Construction

By default, Connectware constructs the LDAP search filter as:

{% code lineNumbers="true" %}

```txt
(<userRdn>=<username>)
```

{% endcode %}

Where:

* `CYBUS_LDAP_USER_RDN` (Docker Compose) or `userRdn` (Kubernetes) is configured in Connectware.
* `username` is the value entered by the user during login.

If you configure an additional search filter extension, Connectware combines both parts using an AND condition. The resulting filter has the following structure:

{% code lineNumbers="true" %}

```txt
(&(<userRdn>=<username>)(<searchFilter>))
```

{% endcode %}

#### RFC 4515 Encoding Requirements

LDAP search filters must follow RFC 4515. Certain special characters in filter values must be escaped using hexadecimal notation.

See the official RFC for full details: <https://datatracker.ietf.org/doc/rfc4515/>

**Characters Requiring Escaping**

The following characters must be escaped when used in LDAP filter values:

| Character | Hex Escape | Description       |
| --------- | ---------- | ----------------- |
| `*`       | `\2a`      | Asterisk          |
| `(`       | `\28`      | Left parenthesis  |
| `)`       | `\29`      | Right parenthesis |
| `\`       | `\5c`      | Backslash         |
| NUL       | `\00`      | Null character    |

**Non-ASCII Characters**

Non-ASCII characters (such as international characters) should be encoded as hex-escaped UTF-8 bytes. Each byte of the UTF-8 representation must be escaped individually.

**Example:** The German character `ü` is represented in UTF-8 as bytes `0xC3 0xBC`, which must be escaped as `\c3\bc` in an LDAP filter.

**Encoding Example**

{% code lineNumbers="true" %}

```txt
Clear text search filter: (cn=*)
Escaped search filter: (cn=\2a)
```

{% endcode %}

When used as an extension, only the escaped expression is added.

#### When to Use a Custom Search Filter

Extending the search filter is useful in scenarios such as:

* Users are not uniquely identifiable by their username alone.
* Multiple entries share the same RDN within a large search base.
* You want to restrict authentication to a specific subtree or object type.

#### Example Scenario

Given the following directory structure, we have two entries with the same RDN `cn=a.smith`:

{% code lineNumbers="true" %}

```txt
dc=corp,dc=com
├── ou=customers
│   └── cn=a.smith
└── ou=employees
    └── cn=a.smith
```

{% endcode %}

If the search base is set to `dc=corp,dc=com`, the username alone is not sufficient to uniquely identify the entry.

To restrict authentication to employees only, you can extend the filter to match entries whose DN contains `ou=employees`.

**Testing the Custom Search Filter**

You can validate the filter using `ldapsearch` before applying it to Connectware:

{% code lineNumbers="true" %}

```bash
ldapsearch -L \
  -b "dc=corp,dc=com" \
  -D "cn=admin,dc=corp,dc=com" \
  -w admin_pass \
  "(&(cn=a.smith)(ou:dn:=employees))"
```

{% endcode %}

#### Configuring the Filter Extension

{% tabs %}
{% tab title="Kubernetes Configuration" %}
**Configuring the Filter Extension (Kubernetes)**

* In the `values.yaml` file, configure the `global.authentication.ldap.searchFilter` Helm value.

**Example**

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      bindDn: cn=binduser,ou=users,dc=corp,dc=com
      bindPassword: <password of binduser>
      searchBase: dc=corp,dc=com
      userRdn: cn
      searchFilter: ou:dn:=employees
      url: ldap://ldap.corp.com:389
```

{% endcode %}

{% hint style="warning" %}
Be aware that no surrounding brackets are used for the additional expression. Brackets within your expression can be used, e.g., `&(objectClass=iNetOrgPerson)(ou:dn:=employees)`.
{% endhint %}
{% endtab %}

{% tab title="Docker Compose Configuration" %}
**Configuring the Filter Extension (Docker Compose)**

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`.
2. The directory contains an `.env` file that is loaded when starting Connectware. Open the `.env` file in a text editor of your choice.
3. Locate the LDAP settings section in the `.env` file and configure the `CYBUS_LDAP_SEARCH_FILTER` environment variable.
   {% endtab %}
   {% endtabs %}

### Bind User Credentials via Existing Kubernetes Secret

If you do not want to provide the bind user for LDAP authentication through the Helm values `bindDn` and `bindPassword` within the `global.authentication.ldap` context, you can also manually create a Kubernetes secret in Connectware's namespace through your preferred method of managing secrets in Kubernetes. You will then need to provide the name of this secret in the Helm value `existingBindSecret`.

This secret needs to contain two keys, `bindDn` and `bindPassword`, containing the parameters that you did not specify directly as Helm values. If you want to use different keys, you can customize these as shown below.

**Example**

1. Create your Kubernetes secret:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} create secret generic my-ldap-user --from-literal=bindDn="cn=binduser,ou=users,dc=corp,dc=com" --from-literal=bindPassword="S3cretPassword"
```

{% endcode %}

2. Specify the name of the secret in your `values.yaml` file:

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      existingBindSecret: my-ldap-user
      searchBase: dc=corp,dc=com
      url: ldap://ldap.corp.com:389
```

{% endcode %}

#### Customizing Kubernetes Secret Keys

If you want to customize the keys used in the Kubernetes secret, you can do so and specify the keys you want to use instead in the Helm value `existingBindSecretDnKey` and `existingBindSecretPasswordKey` within the `global.authentication.ldap` context.

**Example**

1. Create your Kubernetes secret:

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} create secret generic custom-ldap-user --from-literal=username="cn=binduser,ou=users,dc=corp,dc=com" --from-literal=password="S3cretPassword"
```

{% endcode %}

2. Specify the name of the secret in your `values.yaml` file:

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    ldap:
      enabled: true
      existingBindSecret: custom-ldap-user
      existingBindSecretDnKey: username
      existingBindSecretPasswordKey: password
      searchBase: dc=corp,dc=com
      url: ldap://ldap.corp.com:389
```

{% endcode %}


# Access Permissions for Admin UI

Configure fine-grained access permissions for Admin UI features and operations.

You can control which Admin UI features are available to different users by assigning permissions to roles. This allows you to restrict access so users can only view (read) or modify (write) specific features.

## Default Roles

Two default roles are available:

* **`connectware-admin`** - Full access to all features and operations. Users with this role can view and modify everything.
* **`minimum-access`** - Limited access for users who only need to view specific information. See the full list of accessible features:

{% content-ref url="/pages/3N9uF4J9BiPH1DI2CxVu" %}
[Admin UI Pages Available to Minimum Access Users](/access/user-management/access-permissions-for-admin-ui/minimum-access-role-pages)
{% endcontent-ref %}

## Custom Permissions

You can create custom permission sets beyond the default roles. To do this, assign specific HTTP and MQTT paths to a role, then assign that role to your users.

For a complete reference of which permissions are needed for each Admin UI page and operation, see:

{% content-ref url="/pages/jAN45T9pb93Zauil9AKX" %}
[Admin UI Permissions](/access/user-management/access-permissions-for-admin-ui/ui-access)
{% endcontent-ref %}


# Admin UI Pages Available to Minimum Access Users

These are the pages that users with the `minimum-access` permissions are allowed to see:

* Data
  * [Data Explorer](/access/user-management/access-permissions-for-admin-ui/ui-access#data-greater-than-data-explorer)
* Services
  * [Deviated Services](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-deviated-services)
  * [Rule Sandbox](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-rule-sandbox)
  * [Service Overview](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview)
    * [Service Details](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview-greater-than-service-details)
      * [Connection](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview-greater-than-service-details-greater-than-connection)
      * [Endpoint](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview-greater-than-service-details-greater-than-endpoint)
      * [Mapping](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview-greater-than-service-details-greater-than-mapping)
      * [Server](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-overview-greater-than-service-details-greater-than-server)
  * Service Resources
    * [Connections](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-connections)
      * [Connection](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-connections-greater-than-connection)
    * [Endpoints](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-endpoints)
      * [Endpoint](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-endpoints-greater-than-endpoint)
    * [Mappings](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-mappings)
      * [Mapping](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-mappings-greater-than-mapping)
    * [Nodes](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-nodes)
    * [Servers](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-servers)
      * [Server](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-servers-greater-than-server)
    * [Service Links](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-service-links)
      * [Service Details](/access/user-management/access-permissions-for-admin-ui/ui-access#services-greater-than-service-resources-greater-than-service-links-greater-than-service-details)
* Settings
  * [Login](/access/user-management/access-permissions-for-admin-ui/ui-access#settings-greater-than-login)
* System
  * System Status
    * [Internet Connectivity](/access/user-management/access-permissions-for-admin-ui/ui-access#system-greater-than-system-status-greater-than-internet-connectivity)
    * [License](/access/user-management/access-permissions-for-admin-ui/ui-access#system-greater-than-system-status-greater-than-license)
    * [System Information](/access/user-management/access-permissions-for-admin-ui/ui-access#system-greater-than-system-status-greater-than-system-information)


# Admin UI Permissions

## Pages

Below you can find the list of pages available on the Admin-UI along side the optional and required permissions to access them.

### Data > Data Explorer

`/data/explorer`

**Required permissions**

* [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)

**Optional permissions**

* [Loading Connectware’s topics](#loading-connectwares-topics)

### Services > Deviated Services

`/services/deviated`

**Required permissions**

* [Detecting and listing deviations](#detecting-and-listing-deviations)

**Optional permissions**

* [Loading service’s details](#loading-services-details)

### Services > Rule Sandbox

`/services/rule-engine-sandbox`

**Required permissions**

* [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)

**Optional permissions**

* [Listing CW’s resources on the Rule Sandbox](#listing-cws-resources-on-the-rule-sandbox)

### Services > Service Catalog

`/services/catalog`

**Required permissions**

* [Creating or updating services](#creating-or-updating-services)
* [Loading service’s catalog metadata](#loading-services-catalog-metadata)

### Services > Service Logs

`/services/logs`

**Required permissions**

* [Loading logs](#loading-logs)

### Services > Service Overview

`/services/overview`

**Required permissions**

* [Loading services](#loading-services)

**Optional permissions**

* [Creating or updating services](#creating-or-updating-services)
* [Loading service’s details](#loading-services-details)
* [Managing services](#managing-services)

### Services > Service Overview > Service Details

`/services/overview/:serviceId`

**Required permissions**

* [Loading service’s details](#loading-services-details)

**Optional permissions**

* In order to **create and update services** the following permissions are required:
  * [Creating or updating services](#creating-or-updating-services)
  * [Load service’s commissioning file](#load-services-commissioning-file)
* In order to **use service\`s Live Data** the following permissions are required:
  * [Loading service’s Live Data](#loading-services-live-data)
  * [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)
* [Load service’s commissioning file](#load-services-commissioning-file)
* [Loading connections](#loading-connections)
* [Loading endpoints](#loading-endpoints)
* [Loading logs](#loading-logs)
* [Loading mappings](#loading-mappings)
* [Loading nodes](#loading-nodes)
* [Loading servers](#loading-servers)
* [Loading service containers](#loading-service-containers)
* [Loading volumes](#loading-volumes)
* [Managing services](#managing-services)

### Services > Service Overview > Service Details > Connection

`/services/overview/:serviceId/connections/:resourceId`

**Required permissions**

* [Loading connection’s details](#loading-connections-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing connections](#managing-connections)

### Services > Service Overview > Service Details > Container

`/services/overview/:serviceId/containers/:resourceId`

**Required permissions**

* [Loading service container’s details](#loading-service-containers-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing service containers](#managing-service-containers)

### Services > Service Overview > Service Details > Endpoint

`/services/overview/:serviceId/endpoints/:resourceId`

**Required permissions**

* [Loading endpoint’s details](#loading-endpoints-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing endpoints](#managing-endpoints)

### Services > Service Overview > Service Details > Mapping

`/services/overview/:serviceId/mappings/:resourceId`

**Required permissions**

* [Loading mapping’s details](#loading-mappings-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing mappings](#managing-mappings)
* [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)

### Services > Service Overview > Service Details > Server

`/services/overview/:serviceId/servers/:resourceId`

**Required permissions**

* [Loading server’s details](#loading-servers-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Loading nodes](#loading-nodes)
* [Managing servers](#managing-servers)

### Services > Service Overview > Service Details > Volume

`/services/overview/:serviceId/volumes/:resourceId`

**Required permissions**

* [Loading volume’s details](#loading-volumes-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing volumes](#managing-volumes)

### Services > Service Resources > Connections

`/services/resources/connections`

**Required permissions**

* [Loading connections](#loading-connections)

**Optional permissions**

* [Loading connection’s details](#loading-connections-details)
* [Managing connections](#managing-connections)

### Services > Service Resources > Connections > Connection

`/services/resources/connections/:resourceId`

**Required permissions**

* [Loading connection’s details](#loading-connections-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing connections](#managing-connections)

### Services > Service Resources > Containers

`/services/resources/containers`

**Required permissions**

* [Loading service containers](#loading-service-containers)

**Optional permissions**

* [Loading service container’s details](#loading-service-containers-details)
* [Managing service containers](#managing-service-containers)

### Services > Service Resources > Containers > Container

`/services/resources/containers/:resourceId`

**Required permissions**

* [Loading service container’s details](#loading-service-containers-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing service containers](#managing-service-containers)

### Services > Service Resources > Endpoints

`/services/resources/endpoints`

**Required permissions**

* [Loading endpoints](#loading-endpoints)

**Optional permissions**

* [Loading endpoint’s details](#loading-endpoints-details)
* [Managing endpoints](#managing-endpoints)

### Services > Service Resources > Endpoints > Endpoint

`/services/resources/endpoints/:resourceId`

**Required permissions**

* [Loading endpoint’s details](#loading-endpoints-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing endpoints](#managing-endpoints)

### Services > Service Resources > Mappings

`/services/resources/mappings`

**Required permissions**

* [Loading mappings](#loading-mappings)

**Optional permissions**

* [Loading mapping’s details](#loading-mappings-details)
* [Managing mappings](#managing-mappings)

### Services > Service Resources > Mappings > Mapping

`/services/resources/mappings/:resourceId`

**Required permissions**

* [Loading mapping’s details](#loading-mappings-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing mappings](#managing-mappings)
* [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)

### Services > Service Resources > Nodes

`/services/resources/nodes`

**Required permissions**

* [Loading nodes](#loading-nodes)

### Services > Service Resources > Servers

`/services/resources/servers`

**Required permissions**

* [Loading servers](#loading-servers)

**Optional permissions**

* [Loading server’s details](#loading-servers-details)
* [Managing servers](#managing-servers)

### Services > Service Resources > Servers > Server

`/services/resources/servers/:resourceId`

**Required permissions**

* [Loading server’s details](#loading-servers-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Loading nodes](#loading-nodes)
* [Managing servers](#managing-servers)

### Services > Service Resources > Service Links

`/services/resources/links`

**Required permissions**

* [Loading services](#loading-services)

**Optional permissions**

* [Loading service’s details](#loading-services-details)

### Services > Service Resources > Service Links > Service Details

`/services/resources/service/:resourceId`

**Required permissions**

* [Loading service’s details](#loading-services-details)

**Optional permissions**

* In order to **create and update services** the following permissions are required:
  * [Creating or updating services](#creating-or-updating-services)
  * [Load service’s commissioning file](#load-services-commissioning-file)
* In order to **use service\`s Live Data** the following permissions are required:
  * [Loading service’s Live Data](#loading-services-live-data)
  * [Subscribing to MQTT Topics](#subscribing-to-mqtt-topics)
* [Load service’s commissioning file](#load-services-commissioning-file)
* [Loading connections](#loading-connections)
* [Loading endpoints](#loading-endpoints)
* [Loading logs](#loading-logs)
* [Loading mappings](#loading-mappings)
* [Loading nodes](#loading-nodes)
* [Loading servers](#loading-servers)
* [Loading service containers](#loading-service-containers)
* [Loading volumes](#loading-volumes)
* [Managing services](#managing-services)

### Services > Service Resources > Volumes

`/services/resources/volumes`

**Required permissions**

* [Loading volumes](#loading-volumes)

**Optional permissions**

* [Loading volume’s details](#loading-volumes-details)
* [Managing volumes](#managing-volumes)

### Services > Service Resources > Volumes > Volume

`/services/resources/volumes/:resourceId`

**Required permissions**

* [Loading volume’s details](#loading-volumes-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing volumes](#managing-volumes)

### Settings > Login

`/settings/login`

**Optional permissions**

* In order to **manage your password** the following permissions are required:
  * [Managing your own password](#managing-your-own-password)
  * [Retrieving CW’s password policy](#retrieving-cws-password-policy)
* [Use Multi-factor authentication](#use-multi-factor-authentication)

### System > System Status > Agents

`/system/status/agents`

**Required permissions**

* [Loading agents](#loading-agents)

**Optional permissions**

* [Managing agents](#managing-agents)

### System > System Status > Internet Connectivity

`/system/status/internet-connectivity`

**Required permissions**

* [Loading Connectware’s system information](#loading-connectwares-system-information)

### System > System Status > License

`/system/status/license`

**Required permissions**

* [Loading Connectware’s system information](#loading-connectwares-system-information)

**Optional permissions**

* [Managing Connectware’s license](#managing-connectwares-license)

### System > System Status > Metrics

`/system/status/metrics`

**Required permissions**

* [Loading Connectware’s metrics](#loading-connectwares-metrics)

**Optional permissions**

* [Managing Connectware’s metrics](#managing-connectwares-metrics)

### System > System Status > System Container

`/system/status/container`

**Required permissions**

* [Loading core containers](#loading-core-containers)

**Optional permissions**

* [Loading core container’s details](#loading-core-containers-details)
* [Managing core containers](#managing-core-containers)

### System > System Status > System Container > Container

`/system/status/container/:resourceId`

**Required permissions**

* [Loading core container’s details](#loading-core-containers-details)

**Optional permissions**

* [Loading logs](#loading-logs)
* [Managing core containers](#managing-core-containers)

### System > System Status > System Information

`/system/status/information`

**Required permissions**

* [Loading Connectware’s system information](#loading-connectwares-system-information)

**Optional permissions**

* [Loading services](#loading-services)

### Users > Client Registry

`/user/client-registry`

**Required permissions**

* [Managing the client registry](#managing-the-client-registry)

### Users > User Certificates

`/user/certificates`

**Required permissions**

* [Managing certificates](#managing-certificates)

### Users > User Management > Permissions

`/user/management/permissions`

**Required permissions**

* [Managing permissions](#managing-permissions)

### Users > User Management > Roles

`/user/management/roles`

**Required permissions**

* [Load configuration needed to manage users and roles](#load-configuration-needed-to-manage-users-and-roles)
* [Managing roles](#managing-roles)

### Users > User Management > Users

`/user/management/users`

**Required permissions**

* [Load configuration needed to manage users and roles](#load-configuration-needed-to-manage-users-and-roles)
* [Managing users](#managing-users)
* [Retrieving CW’s password policy](#retrieving-cws-password-policy)
* [Retrieving CW’s username policy](#retrieving-cws-username-policy)

## Permissions

Below you can find the alternative permissions that can be assigned to users and roles in order to enable them to perform actions on the Admin UI.

### Creating or updating services

| Resource                         | Context | Operation |
| -------------------------------- | ------- | --------- |
| `/api/services/parametersSchema` | `http`  | `write`   |
| `/api/services`                  | `http`  | `write`   |
| `/api/v2/services/+`             | `http`  | `write`   |

### Detecting and listing deviations

| Resource                                       | Context | Operation |
| ---------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count`    | `http`  | `read`    |
| `/api/v2/resources/states/deviations/services` | `http`  | `read`    |
| `/api/v2/resources/states/deviations`          | `http`  | `read`    |
| `/api/v2/services/+`                           | `http`  | `read`    |

### Listing CW’s resources on the Rule Sandbox

| Resource            | Context | Operation |
| ------------------- | ------- | --------- |
| `/api/v2/resources` | `http`  | `read`    |

### Load configuration needed to manage users and roles

| Resource         | Context | Operation |
| ---------------- | ------- | --------- |
| `/api/auth/ldap` | `http`  | `read`    |
| `/api/auth/mfa`  | `http`  | `read`    |

### Load service’s commissioning file

| Resource                                      | Context | Operation |
| --------------------------------------------- | ------- | --------- |
| `/api/v2/services/+/serviceCommissioningFile` | `http`  | `read`    |

### Loading agents

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/v2/resource-runners` | `http`  | `read`    |

### Loading connection’s details

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/v2/resources/+`      | `http`  | `read`    |
| `/api/v2/resources/states` | `http`  | `read`    |

### Loading connections

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/resources/states`                  | `http`  | `read`    |
| `/api/v2/resources`                         | `http`  | `read`    |
| `/api/v2/services/+/resources`              | `http`  | `read`    |

### Loading Connectware’s metrics

| Resource                | Context | Operation |
| ----------------------- | ------- | --------- |
| `/api/system/metrics`   | `http`  | `read`    |
| `/api/system/preflight` | `http`  | `read`    |

### Loading Connectware’s system information

| Resource                | Context | Operation |
| ----------------------- | ------- | --------- |
| `/api/system/info`      | `http`  | `read`    |
| `/api/system/preflight` | `http`  | `read`    |

### Loading Connectware’s topics

| Resource                     | Context | Operation |
| ---------------------------- | ------- | --------- |
| `/api/v2/mqtt/topics/levels` | `http`  | `read`    |

### Loading core container’s details

| Resource                         | Context | Operation |
| -------------------------------- | ------- | --------- |
| `/api/core-containers/+/inspect` | `http`  | `read`    |

### Loading core containers

| Resource                            | Context | Operation |
| ----------------------------------- | ------- | --------- |
| `/api/core-containers/+/inspect`    | `http`  | `read`    |
| `/api/core-containers/orchestrator` | `http`  | `read`    |
| `/api/core-containers`              | `http`  | `read`    |

### Loading endpoint’s details

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/v2/resources/+`      | `http`  | `read`    |
| `/api/v2/resources/states` | `http`  | `read`    |

### Loading endpoints

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/resources/states`                  | `http`  | `read`    |
| `/api/v2/resources`                         | `http`  | `read`    |
| `/api/v2/services/+/resources`              | `http`  | `read`    |

### Loading logs

| Resource                            | Context | Operation |
| ----------------------------------- | ------- | --------- |
| `/api/core-containers/+/logs`       | `http`  | `read`    |
| `/api/core-containers/orchestrator` | `http`  | `read`    |
| `/api/core-containers`              | `http`  | `read`    |
| `/api/v2/resources/+`               | `http`  | `read`    |

### Loading mapping’s details

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/v2/resources/+`      | `http`  | `read`    |
| `/api/v2/resources/states` | `http`  | `read`    |

### Loading mappings

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/resources/states`                  | `http`  | `read`    |
| `/api/v2/resources`                         | `http`  | `read`    |
| `/api/v2/services/+/resources`              | `http`  | `read`    |

### Loading nodes

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/resources/states`                  | `http`  | `read`    |
| `/api/v2/resources`                         | `http`  | `read`    |
| `/api/v2/services/+/resources`              | `http`  | `read`    |

### Loading server’s details

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/v2/resources/+`      | `http`  | `read`    |
| `/api/v2/resources/states` | `http`  | `read`    |

### Loading servers

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/resources/states`                  | `http`  | `read`    |
| `/api/v2/resources`                         | `http`  | `read`    |
| `/api/v2/services/+/resources`              | `http`  | `read`    |

### Loading service container’s details

| Resource                    | Context | Operation |
| --------------------------- | ------- | --------- |
| `/api/containers/+/inspect` | `http`  | `read`    |

### Loading service containers

| Resource                       | Context | Operation |
| ------------------------------ | ------- | --------- |
| `/api/containers/+/inspect`    | `http`  | `read`    |
| `/api/containers/orchestrator` | `http`  | `read`    |
| `/api/containers`              | `http`  | `read`    |

### Loading service’s catalog metadata

| Resource                    | Context | Operation |
| --------------------------- | ------- | --------- |
| `/api/marketplace/app/meta` | `http`  | `read`    |
| `/api/marketplace/app`      | `http`  | `read`    |
| `/api/marketplace/apps`     | `http`  | `read`    |

### Loading service’s details

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/services/+/dependencies`              | `http`  | `read`    |
| `/api/services/all-links`                   | `http`  | `read`    |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/services/+`                        | `http`  | `read`    |

### Loading service’s Live Data

| Resource                       | Context | Operation |
| ------------------------------ | ------- | --------- |
| `/api/v2/services/+/resources` | `http`  | `read`    |

### Loading services

| Resource                                    | Context | Operation |
| ------------------------------------------- | ------- | --------- |
| `/api/services/all-links`                   | `http`  | `read`    |
| `/api/v2/resources/states/deviations/count` | `http`  | `read`    |
| `/api/v2/services/stats/count`              | `http`  | `read`    |
| `/api/v2/services`                          | `http`  | `read`    |

### Loading volume’s details

| Resource                 | Context | Operation |
| ------------------------ | ------- | --------- |
| `/api/volumes/+/inspect` | `http`  | `read`    |

### Loading volumes

| Resource       | Context | Operation |
| -------------- | ------- | --------- |
| `/api/volumes` | `http`  | `read`    |

### Managing agents

| Resource                   | Context | Operation |
| -------------------------- | ------- | --------- |
| `/api/resources/runners/+` | `http`  | `write`   |

### Managing certificates

| Resource                    | Context | Operation   |
| --------------------------- | ------- | ----------- |
| `/api/certificates/content` | `http`  | `read`      |
| `/api/certificates`         | `http`  | `readWrite` |

### Managing connections

| Resource                        | Context | Operation |
| ------------------------------- | ------- | --------- |
| `/api/v2/resources/+/operation` | `http`  | `write`   |

### Managing Connectware’s license

| Resource                  | Context | Operation |
| ------------------------- | ------- | --------- |
| `/api/system/licensefile` | `http`  | `write`   |
| `/api/system/refresh`     | `http`  | `read`    |

### Managing Connectware’s metrics

| Resource              | Context | Operation |
| --------------------- | ------- | --------- |
| `/api/system/metrics` | `http`  | `write`   |

### Managing core containers

| Resource                           | Context | Operation |
| ---------------------------------- | ------- | --------- |
| `/api/core-containers/+/operation` | `http`  | `write`   |

### Managing endpoints

| Resource                        | Context | Operation |
| ------------------------------- | ------- | --------- |
| `/api/v2/resources/+/operation` | `http`  | `write`   |

### Managing mappings

| Resource                        | Context | Operation |
| ------------------------------- | ------- | --------- |
| `/api/v2/resources/+/operation` | `http`  | `write`   |

### Managing permissions

| Resource                | Context | Operation |
| ----------------------- | ------- | --------- |
| `/api/permissions/ids`  | `http`  | `read`    |
| `/api/permissions/page` | `http`  | `read`    |

### Managing roles

| Resource           | Context | Operation |
| ------------------ | ------- | --------- |
| `/api/roles/+`     | `http`  | `write`   |
| `/api/roles/names` | `http`  | `read`    |
| `/api/roles/page`  | `http`  | `read`    |
| `/api/roles`       | `http`  | `write`   |

### Managing servers

| Resource                        | Context | Operation |
| ------------------------------- | ------- | --------- |
| `/api/v2/resources/+/operation` | `http`  | `write`   |

### Managing service containers

| Resource                      | Context | Operation |
| ----------------------------- | ------- | --------- |
| `/api/containers/+/operation` | `http`  | `write`   |

### Managing services

| Resource                    | Context | Operation |
| --------------------------- | ------- | --------- |
| `/api/services/+/operation` | `http`  | `write`   |
| `/api/services/+`           | `http`  | `write`   |

### Managing the client registry

| Resource                       | Context | Operation |
| ------------------------------ | ------- | --------- |
| `/api/client-registry/confirm` | `http`  | `write`   |
| `/api/client-registry/lock`    | `http`  | `write`   |
| `/api/client-registry/open`    | `http`  | `write`   |
| `/api/client-registry/status`  | `http`  | `read`    |
| `/api/client-registry`         | `http`  | `read`    |

### Managing users

| Resource                  | Context | Operation |
| ------------------------- | ------- | --------- |
| `/api/listUsers`          | `http`  | `read`    |
| `/api/users/+`            | `http`  | `write`   |
| `/api/users/batch/delete` | `http`  | `write`   |
| `/api/users/batch`        | `http`  | `write`   |
| `/api/users/usernames`    | `http`  | `read`    |

### Managing volumes

### Managing your own password

| Resource                     | Context | Operation |
| ---------------------------- | ------- | --------- |
| `/api/users/change-password` | `http`  | `write`   |

### Retrieving CW’s password policy

| Resource               | Context | Operation |
| ---------------------- | ------- | --------- |
| `/api/policy/password` | `http`  | `read`    |

### Retrieving CW’s username policy

| Resource               | Context | Operation |
| ---------------------- | ------- | --------- |
| `/api/policy/username` | `http`  | `read`    |

### Subscribing to MQTT Topics

| Resource | Context | Operation |
| -------- | ------- | --------- |
| Any      | `mqtt`  | `read`    |

### Use Multi-factor authentication

| Resource                          | Context | Operation |
| --------------------------------- | ------- | --------- |
| `/api/mfa/disable`                | `http`  | `write`   |
| `/api/mfa/enable`                 | `http`  | `write`   |
| `/api/mfa/isenrolled`             | `http`  | `read`    |
| `/api/mfa/regenerate/backupcodes` | `http`  | `write`   |
| `/api/mfa/validate`               | `http`  | `write`   |

### Using the workbench

| Resource       | Context | Operation   |
| -------------- | ------- | ----------- |
| `/workbench/#` | `http`  | `readWrite` |
| `/workbench`   | `http`  | `readWrite` |


# Client Registry

Secure self-registration for simplified device management.

The **Client Registry** in Connectware provides a secure, automated mechanism for registering new clients, users, and hardware devices without manually handling credentials.

Instead of manually adding users through the [Admin UI](/access/admin-ui), this self-registration process allows clients to register themselves or be automatically registered when they connect to Connectware. This eliminates security risks associated with pre-shared credentials while reducing administrative overhead.

## Advantages of Self-Registration

Traditional client authorization methods often rely on manually creating users and sharing passwords, which introduces security vulnerabilities and administrative overhead. The Client Registry solves this by:

* Eliminating the need to manually distribute credentials.
* Enabling secure, automated credential exchange in the background.
* Providing administrator oversight while minimizing manual intervention.
* Supporting certificate-based authentication for enhanced security.

## Self-Registration Methods

| Self-Registration Method                  | Advantages                                                                                                                                                                                                                                                                                           |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Self-Registering Clients via REST API** | <p>• Support for certificate signing requests (CSR)<br>• Ability to request specific roles and permissions<br>• Enhanced control over client configuration<br>• Suitable for distributed Connectware agents and advanced clients<br>• <a href="/pages/OaPGoB0VDANQWvzdzwqw">More information</a></p> |
| **Self-Registering MQTT Clients**         | <p>• Works with any standard MQTT or HTTP client<br>• The client can generate random passwords automatically<br>• Simple process for basic device integration<br>• <a href="/pages/OlZse2rTrhByDx5eZ3f6">More information</a></p>                                                                    |


# Self-Registering MQTT Clients

Simple self-registration for MQTT clients with username and password.

The MQTT client self-registration via authentication attempt process allows you to securely add new MQTT clients to Connectware via self-registration without having to handle passwords manually. This method works with any standard MQTT client and requires minimal configuration because clients generate their own passwords during registration.

{% hint style="warning" %}
New users created through this process have no permissions by default. Administrators must explicitly assign appropriate permissions after registration is complete.

For registering clients including additional information, such as context details, role requests, permission specifications, and certificate signing requests (CSRs), in their registration payload, see [Client Self-Registration via REST API](/access/client-registry/self-registering-clients-via-rest-api).
{% endhint %}

{% hint style="info" %}
The username must follow the Connectware username requirements. The password must be at least five characters long or must adhere to the [Password Policy Configuration](/access/security/password-policy-configuration).
{% endhint %}

## Registration Workflow

The MQTT client self-registration process via authentication attempt follows these steps:

<figure><img src="/files/lyab48exlu1Lc2S8B0sR" alt="Registering MQTT clients in Connectware"><figcaption><p>Registering MQTT clients in Connectware</p></figcaption></figure>

1. The Connectware administrator unlocks the Client Registry from the **Client Registry View**.
2. An MQTT client attempts to connect using credentials for a non-existent user.
3. Connectware logs the attempt, rejects the request, and creates a pending registration entry.
4. The administrator reviews and approves the registration in the **Client Registry View**.
5. Connectware creates a user with the provided credentials.
6. The administrator assigns roles or permissions to the new user.
7. The MQTT client reconnects with the same credentials and successfully authenticates.

## Initiating the Self-Registration (MQTT Client)

{% hint style="info" %}
This section is for MQTT clients that want to initiate the self-registration.
{% endhint %}

**Prerequisite**

* The Client Registry must be unlocked by a Connectware administrator.

**Initiating the Self-Registration**

* To initiate the self-registration, the MQTT client must attempt to connect using basic authentication (username/password).

**Example**

{% code lineNumbers="true" %}

```bash
mosquitto_pub -h <connectware-host> -p 1883 -u "<username>" -P "<password>" -i "<client-id>" -t "devices/sensor3/data" -m "temperature"
```

{% endcode %}

**Once the request is initiated**

1. The MQTT client receives an authentication error.
2. Connectware logs the credentials as a pending registration.
3. A Connectware admin must now review and approve the request.
4. After approval, the MQTT client retries with the same credentials and successfully connects.

{% hint style="info" %}
Client access is limited until the administrator assigns roles or specific permissions.
{% endhint %}

## Approving Self-Registration Requests (Admin)

{% hint style="info" %}
This section is for Connectware admins that want to approve a self-registration request.
{% endhint %}

After an MQTT client attempts registration, the Connectware admin must approve the request before the client can access the system.

### Approving Self-Registration Requests via REST API

* To approve self-registration requests via REST API, refer to the `Confirm a single authentication request` parameter documented in the [Auth-Server API](/reference/api-reference/auth-server-api).

### Approving Self-Registration Requests via Admin UI

To approve the self-registration requests via the Admin UI, do as follows:

1. In the [Client Registry View](/access/client-registry/client-registry-view), click the **Unlock** button to temporarily unlock the self-registration. The registry will remain open for five minutes and will automatically lock again after this period. You can manually lock the registry by clicking the **Lock** button.

<figure><img src="/files/8oF5BlG7xF4c1RyYtLMj" alt=""><figcaption></figcaption></figure>

2. Locate the pending registration request in the registry table.

<figure><img src="/files/phfg24Pk6i9f0mmeE1Py" alt=""><figcaption></figcaption></figure>

3. Click the request to open the **Grant Access** dialog.
4. Review the request details and click **Allow** to approve registration.

<figure><img src="/files/ipPj2oqCe6ugPEsEJ52K" alt=""><figcaption></figcaption></figure>

5. In the navigation panel, click **User** and confirm that the new user appears in the list.
6. Assign appropriate roles or permissions. For more information, see [Adding Roles to Users](/access/user-management/users#adding-roles-to-users).


# Self-Registering Clients via REST API

Flexible and secure client self-registration with role, permission, and certificate configuration.

The REST API registration method enables advanced client configuration during the self-registration process. With this method, clients (e.g. agents) can include additional information, such as context details, role requests, permission specifications, and certificate signing requests (CSRs), in their registration payload.

{% hint style="warning" %}
When using certificate signing requests (CSR), the Common Name (CN) in the CSR must match the username in the payload and must not be empty. Otherwise, the request will be rejected.
{% endhint %}

{% hint style="info" %}
The username must follow the Connectware username requirements. The password must be at least five characters long.
{% endhint %}

## Registration Workflow

The client self-registration process via REST API follows these steps:

<figure><img src="/files/xc8fJ4dcdBOmIgXJtsiQ" alt="Registering clients in Connectware via API"><figcaption><p>Registering clients in Connectware via REST API</p></figcaption></figure>

1. The client sends an initial registration request to Connectware with credentials and optionally requested roles and permissions.
2. If the registry endpoint is locked (default), Connectware returns a `423 Locked` response.
3. The Connectware administrator unlocks the registry endpoint for five minutes.
4. The client resends the registration request and receives a `202 Accepted` (pending) response.
5. The client polls at regular intervals by resending the same request.
6. The Connectware administrator reviews and approves the pending request.
7. Upon the next poll, the client receives a `201 Created` response indicating successful registration.
8. If the registration used a CSR, the signed certificate is included in the response.
9. The client can now authenticate using standard mechanisms.

## Initiating the Self-Registration (Client)

{% hint style="info" %}
This section is for clients that want to initiate the self-registration.
{% endhint %}

**Prerequisite**

* The registration API must be unlocked by a Connectware administrator.

**Initiating the Self-Registration**

* To initiate the self-registration, the client sends a `POST` request to the `/api/client-registry/register` endpoint. The client can include context details, role requests, permission specifications, and certificate signing requests (CSRs) with its registration via the API parameters.

**Example for HTTP clients**

* Example with username, password, and context.

{% code lineNumbers="true" %}

```bash
curl --insecure --location https://localhost/api/client-registry/register --header 'Content-Type: application/json' --data-raw '{
  "username": "sensor-0003",
  "password": "3f9a7b2cTe!rRTt56fT",
  "context": "Temperature sensor for line 53c"
}
```

{% endcode %}

* Example with username, password, role, and context.

{% code lineNumbers="true" %}

```bash
curl --insecure --location https://localhost/api/client-registry/register --header 'Content-Type: application/json' --data-raw '{
  "username": "sensor-0003",
  "password": "3f9a7b2cTe!rRTt56fT",
  "roles": ["minimum"],
  "context": "Serial number 35350"
}
```

{% endcode %}

For detailed information about the Client Registry REST API parameters, see [Auth-Server API](/reference/api-reference/auth-server-api).

### Required and Optional Parameters

* Either a `password` or a `csr` (certificate signing request) must be provided — but not both.
* `roles` and `permissions` define the access permissions that the client is requesting.
* `context` provides optional metadata to help administrators identify the source or purpose of the request.

### Possible Responses

| Status Code                | Meaning                                                |
| -------------------------- | ------------------------------------------------------ |
| `201 Created`              | Registration granted; the client can now authenticate. |
| `202 Accepted`             | Registration is pending admin approval.                |
| `400 Bad Request`          | Malformed or incomplete request.                       |
| `409 Conflict`             | Username already exists or request is duplicated.      |
| `422 Unprocessable Entity` | Username or password violates policy requirements.     |
| `423 Locked`               | Registration endpoint is currently locked.             |

## Approving Self-Registration Requests (Admin)

{% hint style="info" %}
This section is for Connectware admins that want to approve a self-registration request.
{% endhint %}

After a client attempts registration, the Connectware admin must approve the request before the client can access the system.

### Approving Self-Registration Requests via REST API

* To approve self-registration requests via REST API, refer to the `Confirm a single authentication request` parameter documented in the [Auth-Server API](/reference/api-reference/auth-server-api).

### Approving Self-Registration Requests via Admin UI

1. In the [Client Registry View](/access/client-registry/client-registry-view), click the **Unlock** button to temporarily unlock the self-registration. The registry will remain open for five minutes and will automatically lock again after this period. You can manually lock the registry by clicking the **Lock** button.
2. Locate the pending client request in the table.

<figure><img src="/files/phfg24Pk6i9f0mmeE1Py" alt=""><figcaption></figcaption></figure>

3. Click the registration request in the list to open the **Grant Access** dialog.
4. In the **Grant Access** dialog, inspect the client request details, then click **Allow** to approve the registration.

<figure><img src="/files/ipPj2oqCe6ugPEsEJ52K" alt=""><figcaption></figcaption></figure>

5. In the navigation panel, click **User** and verify that the newly created user appears in the users list.


# Client Registry View

Here you can add and manage your certificates within Connectware.

The **Client Registry View** ​​allows the Connectware admin to securely register and monitor new clients and users for data access.

* To open the **Client Registry View**, click **User** > **Client Registry**.

<figure><img src="/files/LW7HsHxdicmQOrTXNR1P" alt="Client Registry View"><figcaption><p>Client Registry View</p></figcaption></figure>

Here is an overview of the functions of the **Client Registry View**.

**Unlock**

* Unlocks the Client Registry to allow clients to make self-registration requests via the following methods:
  * [Self-Registering MQTT Clients](/access/client-registry/self-registering-mqtt-clients)
  * [Self-Registering Clients via REST API](/access/client-registry/self-registering-clients-via-rest-api)

**Pending requests overview**

* Displays all pending registration requests including **Username**, **Context**, **Timestamp**, and **Credentials**.


# Troubleshooting Client Registry

Resolve common issues with client registration, authentication, and connectivity.

The following table addresses common issues you might encounter when registering clients with Connectware. Use these solutions to quickly resolve problems with client registration, authentication, and connectivity.

## Troubleshooting - Self-Registering Clients via REST API

These issues apply to clients registering via the `/api/client-registry/register` REST API. Also see [Self-Registering Clients via REST API](/access/client-registry/self-registering-clients-via-rest-api).

For detailed information about the Client Registry REST API parameters, see [Auth-Server API](/reference/api-reference/auth-server-api).

| Issue                              | Possible Cause                 | Solution                                                                                                                                                     |
| ---------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Client not appearing in registry   | Registry is locked             | Unlock the registry using the lock icon in the Admin Web App.                                                                                                |
| Registration failing               | Username/password too short    | Ensure username ≥ 3 characters, password ≥ 5 characters. Also adhere to the [Password Policy Configuration](/access/security/password-policy-configuration). |
| CSR rejection                      | CN mismatch in CSR             | Ensure CSR's Common Name matches the requested username.                                                                                                     |
| Client stuck in "pending"          | Admin hasn't granted access    | Review and approve from Client Registry interface.                                                                                                           |
| Unexpected "locked" (423) response | Registry timeout               | Registry auto-locks after 5 minutes; unlock it again.                                                                                                        |
| Certificate authentication failing | Invalid or missing certificate | Ensure CSR is valid and the signed certificate is used.                                                                                                      |

## Troubleshooting - Self-Registering MQTT Clients

These issues apply to MQTT clients self-registering via authentication attempts. Also see [Self-Registering MQTT Clients](/access/client-registry/self-registering-mqtt-clients).

| Issue                                            | Possible Cause              | Solution                                                                                                                                                     |
| ------------------------------------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Client not appearing in registry                 | Registry is locked          | Unlock the registry using the lock icon in the Admin Web App.                                                                                                |
| Registration failing                             | Username/password too short | Ensure username ≥ 3 characters, password ≥ 5 characters. Also adhere to the [Password Policy Configuration](/access/security/password-policy-configuration). |
| Client stuck in "pending"                        | Admin hasn't granted access | Review and approve from Client Registry interface.                                                                                                           |
| Connection failures after registration           | Missing permissions         | Assign appropriate roles to the newly created user.                                                                                                          |
| Multiple failed connection attempts              | Incorrect credentials       | Verify credentials match exactly what was registered.                                                                                                        |
| Client disconnecting after successful connection | Permission issues           | Ensure publish/subscribe permissions are correctly assigned.                                                                                                 |


# Security

Security configuration and certificate management.

Connectware prioritizes robust security for your Industrial IoT infrastructure through comprehensive certificate management and secure communications. This chapter guides you through the certificate requirements, supported cipher suites and TLS versions, and the specific implementation of CA certificates, client certificates, and server certificates within your Connectware deployment.


# TLS Certificates

Manage certificates for secure device communication in Connectware.

Connectware manages certificates to ensure secure communication between devices and systems. It verifies the authenticity of certificates during TLS and mTLS connections, allowing only authorized entities to access the system for increased data integrity and security in industrial environments. You can upload certificates to the Connectware certs volume.

Transport Layer Security (TLS) is a widely used protocol that secures communications between two systems, such as a client and a server, by encrypting the data being transmitted. It ensures data privacy and integrity by verifying the server's identity with a digital certificate. In standard TLS, only the server is authenticated, while the client uses mechanisms such as usernames and passwords for authentication.

Mutual TLS (mTLS) requires both the server and client to authenticate each other with digital certificates. The client also presents a certificate, ensuring that both parties are verified. This adds an extra layer of trust and security, especially in environments where strong authentication is required. Connectware's MQTT server automatically identifies whether a connection uses TLS or mutual TLS based on the provided client certificate.

## Certificate Types in Connectware

Connectware uses the following certificate types to secure communication and establish trust between clients, servers, and external systems:

* **CA certificates**

  CA certificates are used to validate other certificates. Connectware uses built-in Cybus CA certificates as well as custom CA certificates added by users to establish trust. CA certificates form the foundation of the public key infrastructure (PKI) and are stored in the certificate bundles `cybus_ca.crt` and `shared_yearly_ca.crt`, which is used for internal connections. See [CA Certificates](/access/security/tls-certificates/ca-certificates).
* **Client certificates**

  Used in mutual TLS (mTLS) configurations, client certificates authenticate devices, agents, or users to Connectware. These certificates are typically signed by a trusted custom CA and linked to user accounts within Connectware. See [Client Certificates](/access/security/tls-certificates/client-certificates).
* **Server certificates**

  These certificates authenticate the Connectware server to clients (e.g., web browsers or MQTT clients) during TLS or mTLS sessions. They ensure that clients are communicating with a trusted and verified Connectware instance. Server certificates must be signed by a trusted CA and are installed into the Connectware certificate volume. See [Server Certificates](/access/security/tls-certificates/server-certificates).

## Certs Volume

The `certs` volume is a dedicated volume that stores all the certificates used for secure TLS communications and authentication through mTLS, as well as the Certificate Authority (CA) to validate these. It ensures that Connectware services can reliably access the certificates they need.

Within the `certs` volume:

* `cybus_ca.crt` - Holds the current list of valid CA certificates.
* `cybus_ca_backup.crt` — Stores a backup of the previous CA certificate list.
* `shared_yearly_ca.crt` — Used internally by Connectware for authenticating inter-service communication. This bundle is managed by the system and typically does not require user modification.
* `cybus_combined_ca.crt` — Contains both the external (`cybus_ca.crt`) and internal (`shared_yearly_ca.crt`) bundles. This file can be provided to agents as a CA bundle, allowing them to connect securely both internally and externally to Connectware.

In addition to certificate bundles, the `certs` volume also stores the keys for Connectware core services. This includes both server and client keys used in mTLS authentication, as well as the associated CA certificates.

{% hint style="info" %}
The `certs` volume is exclusively used by Connectware core services. External clients, including agents, devices, and MQTT-only clients, do not access it.
{% endhint %}


# Certificate Requirements

Create certificates that Connectware accepts, covering validity periods, subject fields, extensions, signature algorithms, and TLS versions.

Connectware accepts certificates that meet specific requirements, helping you create certificates that function properly in your environment. Find details on recommended validity periods, required subject fields (CN), necessary extensions (SAN), signature algorithms, cipher compatibility, and TLS version support.

Following these specifications ensures your certificates are correctly processed by Connectware components, preventing connection issues and security alerts.

For information on the supported TLS ciphers and TLS versions, see [Cipher Suites & TLS Versions](/access/security/tls-certificates/certificate-requirements/cipher-suites-and-tls-versions).

## Certificate File Format (PEM)

All certificate and key files must be in PEM format.

While the examples in this documentation use traditional extensions like `.crt` for certificates and `.key` for private keys, you may prefer using `.pem` extensions to make the format requirement more explicit.

## Certificate Signature Algorithm

Connectware has specific requirements for certificate signature algorithms. Ensure that your certificate's signature algorithm (e.g., SHA-256 with RSA) is compatible with the Connectware components. Modern, secure algorithms like SHA-256 or SHA-384 are recommended for signature generation.

## Key Exchange & Cipher Compatibility

Your client certificates should be issued using key types compatible with Connectware's supported cipher suites. For example, if a component supports ECDHE-ECDSA cipher suites, your client certificate should be issued using an ECDSA key. Similarly, RSA certificates may not work with cipher suites specifically requiring ECDSA keys. Review the supported cipher suites for each Connectware component to ensure compatibility.

## TLS Version Support

Connectware components enforce specific TLS versions (generally TLS 1.2 and 1.3). Certificates using outdated signature algorithms (e.g., SHA-1) may be rejected by Connectware. Ensure your certificates use modern signature algorithms that are compatible with these TLS versions.

## Validity Period

When deploying certificates for Connectware in your enterprise environment, you can define validity periods according to your organization's security policies and certificate lifecycle management practices. While shorter validity periods align with current security best practices and reduce exposure in case of compromise, you may follow your established PKI standards.

Make sure to renew your certificates before they expire to prevent service disruptions.

## Subject Information (CN, etc.)

The Common Name (CN) field in your certificates should identify the specific Connectware component or service. For server certificates, this typically matches the hostname through which clients will access the service. While historically the CN was the primary identifier for certificate validation, modern systems are increasingly moving away from this approach.

## Extensions (SAN, etc.)

Subject Alternative Name (SAN) extensions are now the preferred and recommended method for specifying host identifiers in certificates used with Connectware. Modern clients prioritize SAN entries over the Common Name field during certificate validation. When creating certificates for Connectware components, it is required to including relevant hostnames, IP addresses, and other identifiers as SAN entries to ensure proper connectivity across all clients. This approach improves compatibility and follows current industry security standards.

For multi-node deployments or services accessible through multiple hostnames, using SAN extensions becomes especially important as they allow a single certificate to be valid for multiple identifiers.


# Cipher Suites & TLS Versions

Check which cipher suites and TLS versions each Connectware component supports for secure communication.

Connectware secures communications through Transport Layer Security (TLS) and mutual TLS (mTLS) protocols across its key components: **Ingress**, **Broker**, and **Control Plane**.

This page lists the supported cipher suites and TLS versions for each component, enabling you to implement secure communication channels in your industrial IoT deployments. A strong TLS configuration is critical for securing data transmissions, verifying endpoint identities, and meeting security compliance requirements.

## Insecure Cipher Suites

When configuring TLS for Connectware components, it is critical to avoid insecure cipher suites. These may include ciphers with known vulnerabilities, outdated algorithms, or insufficient key lengths that could compromise your communication security.

For maximum protection, avoid using ciphers that lack Perfect Forward Secrecy, use deprecated encryption algorithms, employ vulnerable modes such as CBC, or implement weak hash functions. We strongly recommend using only the modern cipher suites documented on this page for all Connectware components.

{% hint style="danger" %}
By default, Connectware does not allow the usage of insecure cipher suites. If you need to use insecure cipher suites, you must set the `CYBUS_ALLOW_INSECURE_TLS_CIPHERS` environment variables to `true`. For more information, see [Environment Variables](/reference/environment-variables).
{% endhint %}

## Ingress (443/TCP) Cipher Suites

### Supported TLS Versions

* TLS 1.2
* TLS 1.3

### Supported TLS Ciphers

Ingress in Connectware supports the following TLS versions and cipher suites.

All supported cipher suites provide 'A' grade security strength. Cipher preference is server-controlled for TLS 1.2 and client-controlled for TLS 1.3. Only null compression is supported, enhancing security by avoiding compression-related vulnerabilities.

**TLS 1.2 Supported Cipher Suites**

| Cipher Suite                                  | Key Length & Elliptic Curve Parameters     |
| --------------------------------------------- | ------------------------------------------ |
| `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`       | 128-bit AES, 256-bit SHA, X25519           |
| `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`       | 256-bit AES, 384-bit SHA, X25519           |
| `TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256` | 256-bit ChaCha20, 256-bit Poly1305, X25519 |

**TLS 1.3 Supported Cipher Suites**

| Cipher Suite                   | Key Length & Elliptic Curve Parameters     |
| ------------------------------ | ------------------------------------------ |
| `TLS_AES_128_GCM_SHA256`       | 128-bit AES, 256-bit SHA, X25519           |
| `TLS_AES_256_GCM_SHA384`       | 256-bit AES, 384-bit SHA, X25519           |
| `TLS_CHACHA20_POLY1305_SHA256` | 256-bit ChaCha20, 256-bit Poly1305, X25519 |

## Broker (8883/TCP) Cipher Suites

### Supported TLS Versions

* TLS 1.2

### Supported TLS Ciphers

The MQTT broker in Connectware supports the following TLS version and cipher suites:

**TLS 1.2 Supported Cipher Suites**

| Cipher Suite                            | Key Length & Elliptic Curve Parameters              |
| --------------------------------------- | --------------------------------------------------- |
| `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA`    | 128-bit AES, 160-bit SHA1, SECP256R1 (NIST P-256)   |
| `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256` | 128-bit AES, 256-bit SHA256, SECP256R1 (NIST P-256) |
| `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` | 128-bit AES, 256-bit SHA256, SECP256R1 (NIST P-256) |
| `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA`    | 256-bit AES, 160-bit SHA1, SECP256R1 (NIST P-256)   |
| `TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384` | 256-bit AES, 384-bit SHA384, SECP256R1 (NIST P-256) |
| `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` | 256-bit AES, 384-bit SHA384, SECP256R1 (NIST P-256) |
| `TLS_RSA_WITH_AES_128_CBC_SHA`          | 128-bit AES, 160-bit SHA1, RSA 2048-bit             |
| `TLS_RSA_WITH_AES_128_CBC_SHA256`       | 128-bit AES, 256-bit SHA256, RSA 2048-bit           |
| `TLS_RSA_WITH_AES_128_GCM_SHA256`       | 128-bit AES, 256-bit SHA256, RSA 2048-bit           |
| `TLS_RSA_WITH_AES_256_CBC_SHA`          | 256-bit AES, 160-bit SHA1, RSA 2048-bit             |
| `TLS_RSA_WITH_AES_256_CBC_SHA256`       | 256-bit AES, 256-bit SHA256, RSA 2048-bit           |
| `TLS_RSA_WITH_AES_256_GCM_SHA384`       | 256-bit AES, 384-bit SHA384, RSA 2048-bit           |

All supported cipher suites provide 'A' grade security strength. Cipher preference is client-controlled. Only null compression is supported, enhancing security by avoiding compression-related vulnerabilities.

## Control Streaming Server Cipher Suites

### Supported TLS Versions

* TLS 1.2
* TLS 1.3

### Supported TLS Ciphers

Control Streaming Server in Connectware supports the following TLS versions and cipher suites:

**TLS 1.2 Supported Cipher Suites**

| Cipher Suite                              | Key Length & Elliptic Curve Parameters                               |
| ----------------------------------------- | -------------------------------------------------------------------- |
| `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` | 128-bit AES, 256-bit SHA, usually `secp256r1` (NIST P-256) for ECDSA |
| `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`   | 128-bit AES, 256-bit SHA, usually `secp256r1` (NIST P-256) for ECDHE |
| `TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305`  | 256-bit ChaCha20, 256-bit Poly1305, usually `secp256r1` or `x25519`  |
| `TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305`    | 256-bit ChaCha20, 256-bit Poly1305, usually `secp256r1` or `x25519`  |
| `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` | 256-bit AES, 384-bit SHA, usually `secp384r1` (NIST P-384) for ECDSA |
| `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`   | 256-bit AES, 384-bit SHA, usually `secp384r1` (NIST P-384) for ECDHE |

**TLS 1.3 Supported Cipher Suites**

| Cipher Suite                   | Key Length & Elliptic Curve Parameters                                    |
| ------------------------------ | ------------------------------------------------------------------------- |
| `TLS_AES_128_GCM_SHA256`       | 128-bit AES, 256-bit SHA, typically `x25519` or `secp256r1`               |
| `TLS_AES_256_GCM_SHA384`       | 256-bit AES, 384-bit SHA, typically `x25519`, `secp256r1`, or `secp384r1` |
| `TLS_CHACHA20_POLY1305_SHA256` | 256-bit ChaCha20, 256-bit Poly1305, typically `x25519`                    |


# CA Certificates

Establish trust with built-in Cybus CA certificates or add your own certificate authority.

Certificate Authority (CA) certificates are used to validate other certificates. Connectware uses a certificate system that includes both built-in Cybus CA certificates and any custom CA certificates you choose to add. These certificates establish trust relationships between different systems and verify the authenticity of connections.

## CA Certificate Types

### Default Cybus CA Certificates

Connectware includes built-in Cybus CA certificates, which are pre-installed and maintained by the system. These form the foundation of Connectware’s security infrastructure.

* The externally used CA certificate chain is maintained in the `cybus_ca.crt` certificate bundle file within the `certs` volume.
* The internally used CA certificate chain is maintained in the `shared_yearly_ca.crt` certificate bundle file within the `certs` volume.
* Which CA an agent requires depends on the hostname through which it connects to Connectware. For example, through the Connectware ingress, or directly to the Control Streaming Server (NATS) through the internal network. The combined CA bundle `cybus_combined_ca.crt` (in the `certs` volume) contains **both** external (`cybus_ca.crt`) and internal (`shared_yearly_ca.crt`) chains and can be used by Connectware agents for TLS chain verification. This simplifies the configuration.

By default, Connectware automatically manages the certificates.

* The internal certificate (`shared_yearly_ca.crt`) is handled by the system and requires no user action.
* The external certificate (`cybus_ca.crt`) is intended for user customization. You can extend the default server certificate (signed by the external CA) with additional hostnames, or replace the entire external PKI (`cybus_ca.crt`, `cybus_server.crt`, `cybus_server.key`, `cybus_client.crt`, `cybus_client.key`) with one managed by your organization. For example, by a central IT security team.

{% hint style="info" %}
In production environments, we recommend that you use a custom CA certificate that your organization manages and has authorized for the external PKI.
{% endhint %}

### Custom CA Certificates

Custom CA certificates are user-provided Certificate Authority certificates that you add to the system to establish trust for secure communications with external systems. These certificates allow Connectware to authenticate and verify devices, clients, or servers that use certificates signed by a non-default or custom CA, rather than relying solely on the built-in Cybus CA.

By adding custom CA certificates, you can integrate your own Public Key Infrastructure (PKI) to ensure that Connectware can recognize and trust certificates issued by external CAs. This increases security and flexibility for specific industry use cases or corporate policies.

{% hint style="info" %}
In production environments, we recommend that you use a custom CA certificate that your organization manages and has authorized for the external PKI.
{% endhint %}

## Adding Custom CA Certificates

You can add custom CA certificates to Connectware via the Admin UI and via the `certs` volume.

{% hint style="info" %}
All certificate and key files must be in PEM format.
{% endhint %}

### Adding Custom CA Certificates via the Admin UI

You can add your custom CA certificate to Connectware via the Admin UI. When you add a certificate, a backup of the current certificates is created. The last backup will be overwritten with the newly created backup and then the uploaded certificate will be appended to the current certificate chain.

1. Select **User** > **User Certificates**.
2. In the **Certificates** view, click **Add Certificate**. See [Certificates View](/access/security/tls-certificates/ca-certificates/certificates-view).

<figure><img src="/files/brv34sPKrbFpTlEjwzzG" alt=""><figcaption></figcaption></figure>

3. In the file browser, select your certificate file and click **Open**.
4. [Restart Connectware](/deployment/restarting-connectware) to apply the changes.

### Adding Custom CA Certificates via the Certs Volume

You can add your custom CA certificate to Connectware via the `certs` volume.

**Prerequisites**

The following files are available:

* The `cybus_ca.crt` from Connectware.
* The `ca-chain.pem` CA certificate chain in PEM format.
* Connectware has a planned maintenance downtime.

{% tabs %}
{% tab title="Kubernetes" %}

### Adding Custom CA Certificates via the Certs Volume (Kubernetes)

1. Append your `ca-chain.crt` to `cybus_ca.crt`:

{% code lineNumbers="true" %}

```bash
cat ca-chain.pem >> cybus_ca.crt
```

{% endcode %}

2. Upload the modified `cybus_ca.crt` to Connectware. Make sure to specify the Connectware namespace:

{% code lineNumbers="true" %}

```bash
pod=$(kubectl -n ${NAMESPACE} get pod -o name -lapp.kubernetes.io/name=auth-server | head -1 | sed 's/pod\///g');
kubectl -n ${NAMESPACE} cp -c auth-server cybus_ca.crt $pod:/connectware_certs/cybus_ca.crt
kubectl -n ${NAMESPACE} exec $pod -c auth-server -- chown -R root:root /connectware_certs
kubectl -n ${NAMESPACE} exec $pod -c auth-server -- chmod 664 /connectware_certs/cybus_ca.crt
```

{% endcode %}

3. Restart the `system-control-server` deployment to rebuild and synchronize the combined CA bundle (`cybus_combined_ca.crt`):

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} rollout restart deployment system-control-server
```

{% endcode %}

4. [Restart Connectware](/deployment/restarting-connectware) to apply the changes.
   {% endtab %}

{% tab title="Docker" %}

### Adding CA Certificates via the Certs Volume (Docker)

1. Append your `ca-chain.crt` to `cybus_ca.crt`:

{% code lineNumbers="true" %}

```bash
cat ca-chain.pem >> cybus_ca.crt
```

{% endcode %}

2. Upload the modified `cybus_ca.crt` to Connectware:

{% code lineNumbers="true" %}

```bash
# Get the container ID or name using labels
container_id=$(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=auth-server")

# Copy the modified CA certificate
docker cp cybus_ca.crt $container_id:/connectware_certs/cybus_ca.crt

# Set proper ownership and permissions
docker exec $container_id chown -R root:root /connectware_certs
docker exec $container_id chmod 664 /connectware_certs/cybus_ca.crt
```

{% endcode %}

3. Restart the `system-control-server` deployment to rebuild and synchronize the combined CA bundle (`cybus_combined_ca.crt`). Ensure that only a single Connectware instance is running.

{% code lineNumbers="true" %}

```bash
docker restart $(docker container ls -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=system-control-server" -q)
```

{% endcode %}

4. [Restart Connectware](/deployment/restarting-connectware) to apply the changes.
   {% endtab %}
   {% endtabs %}

## Removing CA Certificates

You must have at least two CA certificates in Connectware to remove a certificate, as one certificate must always remain in the system.

1. Select **User** > **User Certificates**.
2. In the certificates list, click the arrow next to the certificate that you want to remove. See [Certificates View](/access/security/tls-certificates/ca-certificates/certificates-view).
3. Click **Remove Certificate**.
4. [Restart Connectware](/deployment/restarting-connectware) to apply the changes.


# Certificates View

Here you can add and manage your certificates within Connectware.

The **Certificates view** allows you to add custom CA certificates to the `certs` volume of Connectware.

For more information on how to add custom CA certificates, see [Adding Custom CA Certificates](/access/security/tls-certificates/ca-certificates#adding-custom-ca-certificates).

* To open the **Certificates** view, select **User** > **User Certificates**.

<figure><img src="/files/CgiqQecua3k7GGa7jzC3" alt=""><figcaption></figcaption></figure>


# Client Certificates

Learn how to secure MQTT connections with client certificates via mTLS.

Mutual Transport Layer Security (mTLS) with client certificates provides enhanced security for MQTT connections to Connectware by eliminating the need for traditional username/password authentication. This approach uses X.509 client certificates for public-key authentication, reducing security risks during the authentication process.

Connectware uses a truststore file (`cybus_ca.crt`) to determine which Certificate Authorities (CAs) it trusts for mTLS authentication.

{% hint style="info" %}
Connectware supports TLS up to version 1.2.
{% endhint %}

## Setting Up Client Certificates

To access MQTT using mTLS with Connectware, the following steps are required:

1. Choose the authentication method for MQTT, either username and password or certificate based authentication.
2. Generate a Certificate Signing Request and private key for the client device.
3. Sign the CSR with your custom Certificate Authority to create the final client certificate.
4. Add the custom CA or certificate chain to the Connectware truststore file `cybus_ca.crt`.
5. Configure certificate based authentication in Connectware by creating a user whose Common Name matches the client certificate.

{% hint style="info" %}
All certificate and key files must be in PEM format.
{% endhint %}

**See also**

* [Server Certificates](/access/security/tls-certificates/server-certificates)
* [Using Mutual Transport Layer Security (mTLS) for agents with the connectware-agent Helm chart](/cybus-helm-charts/connectware-agent-helm-chart/mutual-tls)
* [X.509](https://en.wikipedia.org/wiki/X.509)
* [OpenSSL PKI](https://pki-tutorial.readthedocs.io/en/latest/)
* [OpenSSL](https://www.openssl.org/)

### 1. Choosing Your Authentication Method

Connectware provides the following authentication methods for the message broker:

* **Default authentication**: Utilizes username and password credentials. This method is compatible with:
  * Unencrypted connections over port 1883
  * Encrypted connections over port 8883 (TLS)
* **Alternative authentication**: Certificate-based mutual TLS authentication (mTLS)

When using mTLS, the following changes take effect:

* Clients that want to authenticate using mTLS must present valid client certificates when connecting to MQTTS on port 8883.
* Connectware will extract the certificate's Common Name (CN) for user identification.
* The extracted CN must match an existing Connectware user configured for certificate-based authentication (grant type).
* A connection will only be established if both the certificate is validated and the associated user is successfully authenticated.

{% hint style="warning" %}
Each Connectware user can authenticate with either username/password or certificate-based authentication, not both. Configure the grant type per user in the Admin UI.
{% endhint %}

### 2. Generating a Certificate Signing Request (CSR)

We recommend implementing your own Public Key Infrastructure (PKI) to issue and manage client certificates for Connectware authentication.

**Prerequisites**

* Access to your organization's Certificate Authority (CA) infrastructure.
* The ability to sign certificate requests with your CA or Intermediate CA.
* Basic understanding of OpenSSL commands.

**Procedure**

To generate the CSR, proceed as follows:

1. Generate a private key for your device:

{% code lineNumbers="true" %}

```bash
openssl genrsa -out anymachine-key.pem 2048
```

{% endcode %}

2. Download the `openssl-client-cert.conf` sample file from [GitHub](https://github.com/cybusio/tutorial-how-to-use-client-certificates-for-mqtt-over-tls-with-connectware/blob/main/resources/openssl-client-cert.conf).
3. Open the `openssl-client-cert.conf` file and modify the following settings:

{% code lineNumbers="true" %}

```bash
COMMON_NAME = device001
ORGNAME = Smart Factory Inc.
```

{% endcode %}

3. Create the CSR using your configuration and key:

{% code lineNumbers="true" %}

```bash
openssl req -new \
-config openssl-client-cert.conf \
-key anymachine-key.pem \
-out anymachine.csr
```

{% endcode %}

You can also create both the private key and the CSR at the same time via `-keyout`:

{% code lineNumbers="true" %}

```bash
openssl req -new \
-config openssl-client-cert.conf \
-keyout anymachine-key.pem \
-out anymachine.csr
```

{% endcode %}

4. Verify your CSR:

{% code lineNumbers="true" %}

```bash
openssl req -in anymachine.csr -noout -text -nameopt sep_multiline
```

{% endcode %}

The important fields to verify include:

{% code lineNumbers="true" %}

```bash
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=DE
            O=Smart Factory Inc.
            CN=device001
```

{% endcode %}

### 3. Signing the CSR with Your Custom CA

A manual or automated process for signing certificates with a company Root CA or Intermediate CA is up to the user.

This page assumes the availability of a custom CA key-pair or a corresponding Intermediate CA key-pair eligible to sign certificate requests.

**Example:** For testing purposes, you can use an example root CA configuration to generate a new self-signed root CA. Download the `openssl-root-ca-example.conf` sample file from [GitHub](https://github.com/cybusio/tutorial-how-to-use-client-certificates-for-mqtt-over-tls-with-connectware/blob/main/resources/openssl-root-ca-example.conf).

1. Create a CSR for the device that you want to connect to Connectware.
2. Sign the CSR with your custom CA:

{% code lineNumbers="true" %}

```bash
openssl x509 -req -in anymachine.csr -days 100 \
-CA custom_ca.crt \
-CAkey custom_ca.key \
-set_serial 01 > anymachine.crt
```

{% endcode %}

This produces the signed certificate valid 100 days with the following output:

{% code lineNumbers="true" %}

```bash
Signature ok
subject=/C=DE/O=Smart Factory Inc./CN=device001
Getting CA Private Key
```

{% endcode %}

3. Inspect the signed certificate to verify its details. The output should confirm that the issuer matches your custom CA and that the subject corresponds to the device or machine identity you provided.

{% code lineNumbers="true" %}

```bash
openssl x509 -in anymachine.crt -text -noout
```

{% endcode %}

**Result:** Once properly configured, your custom-signed client certificates will function with Connectware without requiring container restarts.

### 4. Add a Custom CA to the cybus\_ca.crt Truststore

To allow Connectware to authenticate clients using this certificate, the custom CA certificate (or full certificate chain) must be trusted by Connectware.

1. Add your CA chain to the Connectware truststore (cybus\_ca.crt). You can retrieve this file from your Connectware instance and then add your custom CA:

{% code lineNumbers="true" %}

```bash
cat custom_ca.crt >> cybus_ca.crt
```

{% endcode %}

2. To verify the trust chain locally before deploying:

{% code lineNumbers="true" %}

```bash
openssl verify -CAfile cybus_ca.crt cybus_client.crt custom_client.crt
```

{% endcode %}

Expected output:

{% code lineNumbers="true" %}

```bash
cybus_client.crt: OK
custom_client.crt: OK
```

{% endcode %}

### 5. Configuring Certificate-Based Authentication

After generating client certificates, you must configure Connectware to recognize and authorize connections using these certificates:

1. For certificate authentication to work, the Common Name (CN) in your client certificate must exactly match a username in Connectware that has been configured with the certificate grant type.
2. Create a user in Connectware with the same name as the CN in your client certificate:

{% code lineNumbers="true" %}

```bash
curl -k --location --request POST 'https://localhost/api/users' \
--header 'Authorization: Bearer eyJzdWI...
--data-raw '{
    "username": "device001",
    "identityProvider": "local",
    "grantTypes": [ { "method": "certificate", "isRequired": false } ],
    "roles": [ "cfb72c04-e4a8-11eb-92a8-0242ac1e0006" ]
}'
```

{% endcode %}

3. Assign appropriate access roles to this certificate-authenticated user. For testing, you can use the `connectware-admin` role. For production environments, follow the principle of least privilege with more restricted roles.
4. To find the correct `connectware-admin` role ID for your environment, use the following GET request:

{% code lineNumbers="true" %}

```bash
https://localhost/api/roles?name[eq]=connectware-admin
```

{% endcode %}

**Result:** Once properly configured, clients connecting via mTLS with a certificate containing `CN=device001` will authenticate successfully, provided the certificate was signed by a CA in the trusted `cybus_ca.crt` chain.

**See also**

* [Adding Individual Permissions to Users](/access/user-management/users#adding-individual-permissions-to-users)

## Verifying the mTLS Configuration

{% tabs %}
{% tab title="Kubernetes" %}

## Verifying the mTLS Configuration (Kubernetes)

To confirm that mTLS is configured correctly for Connectware, do the following:

1. In the [Admin UI](/access/admin-ui), select **User** > **User Management**, and select the **admin** user.
2. In the **Edit User** dialog, enable **Advanced Mode**.
3. Enable **Certificate** and click **Update**.
4. Download the certificate files from the Connectware pod using kubectl. The following commands will extract the `cybus_ca.crt`, `cybus_client.crt`, and `cybus_client.key` files from the `/connectware_certs` directory in the system-control-server pod to your current local directory.

{% code lineNumbers="true" %}

```bash
kubectl cp $(kubectl get pod -l app.kubernetes.io/name=system-control-server -o name | sed -e 's/pod\///g'):/connectware_certs/cybus_ca.crt cybus_ca.crt
kubectl cp $(kubectl get pod -l app.kubernetes.io/name=system-control-server -o name | sed -e 's/pod\///g'):/connectware_certs/cybus_client.crt cybus_client.crt
kubectl cp $(kubectl get pod -l app.kubernetes.io/name=system-control-server -o name | sed -e 's/pod\///g'):/connectware_certs/cybus_client.key cybus_client.key
```

{% endcode %}

6. Use the `cybus_client` key pair with `CN=admin`.
7. Connect to an MQTT client on port 8883 using the CA file (`cybus_ca.crt`) and the `cybus_client` key pair.
8. Use an MQTT client like `mosquitto_sub` to check for successful connection.

{% code lineNumbers="true" %}

```bash
mosquitto_sub \
--cert cybus_client.crt \
--key cybus_client.key \
--cafile cybus_ca.crt \
-h localhost -p 8883 -t '#' -d
```

{% endcode %}
{% endtab %}

{% tab title="Docker" %}

## Verifying the mTLS Configuration (Docker)

To confirm that mTLS is configured correctly for Connectware, do the following:

1. In the [Admin UI](/access/admin-ui), select **User** > **User Management**, and select the **admin** user.
2. In the **Edit User** dialog, enable **Advanced Mode**.
3. Enable **Certificate** and click **Update**.
4. Download the `cybus_client.key` and `cybus_client.crt` files, located in the `/connectware_certs` Docker volume.
5. To extract the `cybus_client.*` files, use the [extract script](https://github.com/cybusio/tutorial-how-to-use-client-certificates-for-mqtt-over-tls-with-connectware/blob/main/tools/extract_certs-from_connectware.sh), which uses `docker cp` to copy files from a running container.
6. Use the `cybus_client` key pair with `CN=admin`.
7. Connect to an MQTT client on port 8883 using the CA file (`cybus_ca.crt`) and the `cybus_client` key pair.
8. Use an MQTT client like `mosquitto_sub` to check for successful connection.

{% code lineNumbers="true" %}

```bash
mosquitto_sub \
--cert cybus_client.crt \
--key cybus_client.key \
--cafile cybus_ca.crt \
-h localhost -p 8883 -t '#' -d
```

{% endcode %}
{% endtab %}
{% endtabs %}

### mTLS Example Output

**Successful connection**

{% code lineNumbers="true" %}

```bash
Client mosq-wcdbhQtb5lkGOBMIbi sending CONNECT
Client mosq-wcdbhQtb5lkGOBMIbi received CONNACK (0)
Client mosq-wcdbhQtb5lkGOBMIbi sending SUBSCRIBE (Mid: 1, Topic: #, QoS: 0, Options: 0x00)
Client mosq-wcdbhQtb5lkGOBMIbi received SUBACK
Subscribed (mid: 1): 0
```

{% endcode %}

**TLS handshake failure**

{% code lineNumbers="true" %}

```bash
Client mosq-wcdbhQtb5lkGOBMIbi sending CONNECT
OpenSSL Error[0]: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
Error: A TLS error occurred.
```

{% endcode %}

**Backend authorization failure**

{% code lineNumbers="true" %}

```bash
Client mosq-wcdbhQtb5lkGOBMIbi sending CONNECT
Client mosq-wcdbhQtb5lkGOBMIbi  received CONNACK (5)
Connection error: Connection Refused: not authorised.
Client mosq-wcdbhQtb5lkGOBMIbi  sending DISCONNECT
```

{% endcode %}

## Revoking Access for Clients with Custom CA Certificates

* To revoke all client certificates issued by a particular custom CA, remove the custom CA entries from the `cybus_ca.crt` file.

This will block further access from any certificate issued by that CA without needing to restart Connectware.


# Server Certificates

Generate and install your server certificate for secure connections.

The server certificate ensure secure connections to Connectware and must be properly maintained to avoid security issues. Regular certificate updates are necessary following Let's Encrypt renewals through `certbot` or when deploying self-signed certificates in your environment.

Without proper certificate configuration, users may encounter browser security warnings when accessing the [Admin UI](/access/admin-ui). To establish trusted communication within enterprise networks, Connectware requires server certificates that are trusted and validated by your organization's Public Key Infrastructure (PKI).

## Generating the Server Certificate

The following procedure can be performed on any system with OpenSSL installed.

{% hint style="info" %}
All certificate and key files must be in PEM format.
{% endhint %}

1. To define the server certificate configuration, create or modify an `openssl.cnf` file with the following parameters. Customize the values to match your specific environment:

{% code lineNumbers="true" %}

```bash
[alt_names]
DNS.1 = localhost
DNS.2 = server.cybus.io
DNS.3 = *.cybus.io
DNS.4 = *.dev.cybus.io
DNS.5 = a048ffe65867e4a02b615faa014e3cdb-1179064562.cybus.io
DNS.6 = *.eu-central.cybus.io
IP.1 = 127.0.0.1
IP.2 = 192.168.178.110
IP.3 = 172.17.0.1

[req]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256
prompt              = no

# Extension to add when the -x509 option is used.
x509_extensions     = server_cert
extensions          = server_cert
req_extensions      = server_cert

[req_distinguished_name]
countryName              = DE
stateOrProvinceName      = HH
0.organizationName       = Acme Test 002
organizationalUnitName   = Shopfloor
commonName               = Cybus Connectware Server 1

[server_cert]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName=@alt_names
```

{% endcode %}

2. To generate a new private key, run the following command:

{% code lineNumbers="true" %}

```bash
openssl genrsa -out cybus_server.key 2048
```

{% endcode %}

3. Store the `cybus_server.key` file in a secure location.
4. Generate a Certificate Sign Request (CSR) using your private key:

{% code lineNumbers="true" %}

```bash
openssl req -new -key cybus_server.key -out cybus_server.csr -config openssl.cnf
```

{% endcode %}

5. Submit the CSR to your IT department or certificate authority.
6. After receiving the signed server certificate, store the `cybus_server.crt` file in a secure location.

## Installing the Server Certificate

{% hint style="info" %}
All certificate and key files must be in PEM format.
{% endhint %}

{% tabs %}
{% tab title="Kubernetes" %}

## Installing the Server Certificate (Kubernetes)

1. Obtain the corporate certificate (.crt) and key (.key) files from your IT department.
2. Copy these files to Connectware's certificate volume using the following commands:

   Replace `[path-to/your-key-file.key]` and `[path-to/your-cert-file.crt]` with the absolute paths to your key and certificate files.

   Set the `NAMESPACE` variable to your Kubernetes namespace that hosts your Connectware installation.

{% code lineNumbers="true" %}

```bash
kubectl -n ${NAMESPACE} cp [path-to/your-key-file.key] $(kubectl -n ${NAMESPACE} get pod -l app.kubernetes.io/name=system-control-server -o name | sed -e 's/pod\///g'):/connectware_certs/cybus_server.key
kubectl -n ${NAMESPACE} cp [path-to/your-cert-file.crt] $(kubectl -n ${NAMESPACE} get pod -l app.kubernetes.io/name=system-control-server -o name | sed -e 's/pod\///g'):/connectware_certs/cybus_server.crt
```

{% endcode %}

3. After updating the certificates, [restart Connectware](/deployment/restarting-connectware) to apply the changes.

{% hint style="warning" %}
You must also add the CA certificate to Connectware to establish the trust chain. See [CA Certificates](/access/security/tls-certificates/ca-certificates).
{% endhint %}
{% endtab %}

{% tab title="Docker" %}

## Installing the Server Certificate (Docker)

1. Obtain the corporate certificate (.crt) and key (.key) files from your IT department.
2. Copy these files to Connectware's certificate volume using the following commands:

   Replace `[path-to/your-key-file.key]` and `[path-to/your-cert-file.crt]` with the absolute paths to your key and certificate files.

{% code lineNumbers="true" %}

```bash
# Get the container ID or name using labels
container_id=$(docker container ls -q -f "label=io.cybus.connectware=core" -f "label=com.docker.compose.service=auth-server")

# Copy the key and certificate files
docker cp [path-to/your-key-file.key] $container_id:/connectware_certs/cybus_server.key
docker cp [path-to/your-cert-file.crt] $container_id:/connectware_certs/cybus_server.crt

# Set proper ownership and permissions
docker exec $container_id chown -R root:root /connectware_certs
docker exec $container_id chmod 664 /connectware_certs/cybus_server.key
docker exec $container_id chmod 664 /connectware_certs/cybus_server.crt
```

{% endcode %}

3. After updating the certificates, [restart Connectware](/deployment/restarting-connectware) to apply the changes.

{% hint style="warning" %}
You must also add the CA certificate to Connectware to establish the trust chain. See [CA Certificates](/access/security/tls-certificates/ca-certificates).
{% endhint %}
{% endtab %}
{% endtabs %}


# Password Policy Configuration

Define and implement organization-specific password policies.

You can define customized password rules to strengthen security based on your organization's needs. Configure these rules using either:

* **Kubernetes deployment**: Set the `global.authentication.passwordPolicyRules` Helm value.
* **Docker deployment**: Use the `CYBUS_AUTH_PASSWORD_POLICY_RULES` environment variable.

If not configured, the default password rule is `{"min": 5}`, which requires passwords to have a minimum length of five characters without any specific character type requirements.

## Configuring Password Rules

{% tabs %}
{% tab title="Kubernetes" %}

## Configuring Password Rules (Kubernetes)

1. Open the `values.yaml` file.
2. Set the `global.authentication.passwordPolicyRules` Helm value to configure your password rules. For a list of all configuration properties, see [Password Parameters](#password-parameters).

{% code lineNumbers="true" %}

```yaml
global:
  authentication:
    passwordPolicyRules: '{"min": 10, "upper": 1, "lower": 1, "numeric": 1, "symbol": 1}'
```

{% endcode %}

3. Upgrade your Helm chart to apply the Helm configuration changes. For details, see [Applying Helm Configuration Changes](/cybus-helm-charts/working-with-cybus-helm-charts#applying-helm-configuration-changes).

{% code lineNumbers="true" %}

```bash
helm upgrade -n ${NAMESPACE} ${INSTALLATION_NAME} oci://repo.cybus.io/charts/connectware -f values.yaml
```

{% endcode %}

4. Verify your configuration.
   * Check the auth-server logs for any errors.
   * Try creating a new user with a password that does not meet the requirements to test.
     {% endtab %}

{% tab title="Docker" %}

## Configuring Password Rules (Docker)

1. Navigate to your Connectware installation directory. If you have used the default values during installation, this is the installation folder: `/opt/connectware`. The directory contains an `.env` file that is loaded when starting Connectware.
2. Open the `.env` file.
3. Set the `CYBUS_AUTH_PASSWORD_POLICY_RULES` environment variable to configure your password rules. For a list of all configuration properties, see [Password Parameters](#password-parameters).

{% code lineNumbers="true" %}

```yaml
environment:
  - CYBUS_AUTH_PASSWORD_POLICY_RULES={"min": 10, "upper": 1, "lower": 1, "numeric": 1, "symbol": 1}
```

{% endcode %}

4. Start or restart Connectware. For more information, see [Restarting Connectware](/deployment/restarting-connectware).
5. Verify your configuration.
   * Check the auth-server logs for any errors.
   * Try creating a new user with a password that does not meet the requirements to test.
     {% endtab %}
     {% endtabs %}

## Password Parameters

The `CYBUS_AUTH_PASSWORD_POLICY_RULES` variable and `global.authentication.passwordPolicyRules` Helm value parameters must contain a properly formatted JSON object. The following parameters are available:

| Parameter | Description                          | Example                                                              |
| --------- | ------------------------------------ | -------------------------------------------------------------------- |
| `min`     | Minimum total password length        | `{"min": 8}`                                                         |
| `lower`   | Minimum number of lowercase letters  | `{"lower": 2}` for at least two lowercase characters like `a` or `b` |
| `upper`   | Minimum number of uppercase letters  | `{"upper": 1}` for at least one uppercase character like `A` or `B`  |
| `numeric` | Minimum number of numeric digits     | `{"numeric": 1}` for at least one digit like `1` or `2`              |
| `symbol`  | Minimum number of special characters | `{"symbol": 1}` for at least one symbol like `$` or `#`              |

* **Parameter values**: Each parameter accepts a single integer value.
* **Optional parameters**: All parameters are optional in the JSON object.
* **Disabled rules**: Setting any value to zero (e.g., `{"upper": 0}`) disables that specific rule.
* **Character classification**: Character classes are evaluated using Unicode Regular Expression category parameters. For details on the exact definition of the character classes, see <https://unicode.org/reports/tr18/#General_Category_Property>.

## Troubleshooting

The environment variable is validated during system startup. If there is a misconfiguration (e.g., JSON syntax error), the auth-server microservice will fail to start and log an appropriate error message. Check the auth-server microservice logs for troubleshooting.


# JSON Web Tokens

Generate long-lived JSON Web Tokens (JWT) to authenticate API requests and automate tasks in Connectware.

JSON Web Tokens (JWT) allow you to authenticate API requests, automate tasks, and securely access Connectware resources. These tokens can be configured as long-lived tokens that remain valid for extended periods, making them ideal for ongoing automation and continuous system access. Learn how to generate tokens, apply security best practices, and understand the protections built into Connectware's authentication system.

## Token Security

Protect your authentication tokens through secure configuration and applying best practices.

### Token Redirection Rules

Connectware enforces strict URL redirection rules to prevent phishing attempts and protect against web security vulnerabilities.

1. **Protocol binding:** Connectware requires HTTPS and ensures that no redirects can downgrade the connection to HTTP.
2. **Domain restriction:** Redirects are limited to the current domain.
   * Example: When accessing `https://demo.cybus.io/`, you can only redirect to paths within that domain. Redirects to external domains like `https://cybus.io/` are blocked.

{% hint style="warning" %}
JSON web tokens provide access to Connectware with the same permissions as the user who generated it. Tokens should be generated by users with only the required permission levels.
{% endhint %}

### Token Best Practices

Implementing secure token practices is crucial for maintaining the security of your Connectware environment. Below are key practices to follow when working with tokens:

1. **Set appropriate expiration**
   * Configure token lifetime using the `expireTimeInHours` parameter based on your specific use case.
   * Avoid unnecessarily long expiration periods.
2. **Implement token rotation**
   * Replace active tokens regularly with new ones.
   * Revoke old tokens after replacement.
3. **Separate token usage**
   * Create distinct tokens for different services or tasks.
   * This limits potential security exposure if any single token is compromised.

## Generating JSON Web Tokens

1. Send a POST request to obtain your token. The response will contain a token property with your JWT authentication credentials.

{% code lineNumbers="true" %}

```yaml
curl -X 'POST' \
'https://<CONNECTWARE HOST>/api/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-k \
-d '{
"username": "<A USERNAME>",
"password": "<A PASSWORD>",
"expireTimeInHours": 99999,
"label": "test-token"
}'
```

{% endcode %}

2. Use this token in subsequent requests by adding it as an `apiToken` query string parameter in your URLs.

{% code lineNumbers="true" %}

```yaml
curl -k --location --request GET https://<CONNECTWARE HOST>/api/users?apiToken=<TOKEN OBTAINED IN PREVIOUS STEP HERE>
```

{% endcode %}

## Browser Authentication via JSON Web Tokens

You can use tokens to authenticate users via an authentication URL or redirect users to a specific location within Connectware after authentication.

* **Authentication URL:** To authenticate users on the browser using the token, enter the following URL:

{% code lineNumbers="true" %}

```yaml
https://<CONNECTWARE HOST>/admin?apiToken=<TOKEN>
```

{% endcode %}

* **Authentication with Redirection:** To redirect users to a specific location within Connectware after authentication, enter the following URL. This is particularly useful when working with [Cybus::IngressRoute](/data-flows/service-commissioning-files/resources/cybus-ingressroute) resources.

{% code lineNumbers="true" %}

```yaml
https://<CONNECTWARE HOST>/admin?redirect=<REDIRECTION URL>&apiToken=<TOKEN>
```

{% endcode %}

**Example**

{% code lineNumbers="true" %}

```yaml
https://<CONNECTWARE HOST>/admin?redirect=/services/foo/bar&apiToken=barFoo
```

{% endcode %}


# Services

Services allow you to automate deployment and management of multiple connected operations.

Services in Connectware are configurations that allow for the simultaneous setup and execution of multiple operations. They follow the Infrastructure as Code principle, enabling you to manage complex setups through a single point of configuration.

## What is a Service?

A service is a collection of resources and their configurations, which can include:

* User management and permissions
* Network connections
* Containerized applications
* Data processing tasks

When enabled, a service automatically implements all its defined resources. When disabled, it removes these resources, returning the system to its previous state.

## How to Implement Services?

Services are defined using a [service commissioning file](/data-flows/service-commissioning-files) - a YAML-formatted text file that specifies all required resources and their parameters. This file serves as a complete description of the service's components and their relationships.

## Key Aspects of Services

* They allow for consistent, repeatable deployments
* They can be version-controlled
* They simplify the management of complex configurations

Two features build directly on services: the [Rule Engine](/data-flows/rule-engine) transforms data as it flows through your mappings and endpoints, and [FlowSync](/data-flows/flowsync) enables transactional data flows that carry a response or error back to the requesting system.

The following sections explain how to create, manage, and use services effectively within Connectware.


# Managing Services

Manage services in the Services view of Connectware, including installing, enabling, updating, disabling, and deleting them.

This section explains how to manage services using the **Service** view of Connectware. Services are modular components that perform specific functions within your system.

The following sections cover key aspects of service management:

* [Installing Services](/data-flows/services/managing/installing)
* [Enabling Services](/data-flows/services/managing/enabling)
* [Updating Services](/data-flows/services/managing/updating)
* [Disabling Services](/data-flows/services/managing/disabling)
* [Deleting Services](/data-flows/services/managing/deleting)

After you have set up and configured your services, you can monitor the data of all services in the [Data Explorer](/monitoring/data-explorer) and of individual services in the [Live Data](/monitoring/live-data) tab.


# Installing Services

Upload service commissioning files to deploy services and check the prerequisites that prevent failed installations.

To deploy a service in Connectware, you must upload its corresponding service commissioning file. This file defines how the service is configured and installed.

## Prerequisites

* **Validate the service commissioning file**: Ensure that your service commissioning file is valid before uploading. If the file contains invalid resources, incorrect references, or other defects, the service will fail to [enable](/data-flows/services/managing/enabling) and be shown as [deviated](/data-flows/services/deviations). In such cases, you must manually reinstall a previously working version of the file.
* **Install parent services first (recommended)**: If the service depends on another service (parent/child relationship), install the parent service first. This ensures:
  * Service relations are created during installation.
  * Each service can be installed with `targetState=enabled`.
* **Install child services first (alternative)**: It is possible to install the dependent (child) service first, but this comes with limitations:
  * Service relations are only established when the service is enabled.
  * The dependent (child) service can **only** be installed with `targetState=disabled`.

For more details, see [Service Dependency Behavior](/data-flows/services/inter-service-referencing#service-dependency-behavior) and [targetState](/data-flows/service-commissioning-files/resources/cybus-endpoint#targetstate).

## Procedure

Follow these steps to upload and install a new service:

1. On the navigation panel, click **Services**.

<figure><img src="/files/oenCzTV60hPh7E8t2J2F" alt=""><figcaption></figcaption></figure>

2. Click **Upload Service** to add a new service commissioning file.

<figure><img src="/files/BGgz6g6NGPm4Vv1Ocw2t" alt=""><figcaption></figcaption></figure>

3. In the **Create Service** dialog, click **Choose File**.
4. In your file browser, select your service commissioning file and click **Open**.

<figure><img src="/files/c062K11nPYP6UmiE7Caz" alt=""><figcaption></figcaption></figure>

JSONata rules are validated during the upload. If the service commissioning file does not meet these rules, the installation will be rejected.

{% hint style="info" %}
The validation checks only syntax (well-formed JSONata), not semantics (e.g., existing Cybus resource references or payloads generated by other services).
{% endhint %}

5. The configuration of your service commissioning file is added to the **Configure the new service** section.
6. Define a unique [service ID](/data-flows/services/serviceid).
7. Optional: If your service commissioning file provides configurable parameters, you can customize the values for your service here. Depending on the service commissioning file, parameter descriptions and default values may be available. You can click **Click to see commissioning file** to review your service commissioning file.
8. Once you are finished, click **Install** to install the service.

<figure><img src="/files/zCF3zKPiG3udTLYBp6Gk" alt=""><figcaption></figcaption></figure>

9. Upon successful configuration, your new service will appear in the service list. Initially, the service has the status **Disabled**.

<figure><img src="/files/OsQ7QNat5QC0glavQG8G" alt=""><figcaption></figcaption></figure>

10. After the installation, you must enable the service. For details, see [Enabling Services](/data-flows/services/managing/enabling).


# Enabling Services

Enable services in the Connectware Admin UI after uploading a service commissioning file and grant the required resource access.

After uploading a service commissioning file, you must enable each configured service in the Admin UI.

1. In the **Services** view, click the service that you want to enable to open its **Service Details** view.
2. In the upper right corner, click **Enable**.

<figure><img src="/files/HmaqCpxzWDyC5kAsUs4S" alt=""><figcaption></figcaption></figure>

3. The **Authorization Required** dialog displays the resources that the service must access. Review the requirements, then click **Allow**.

<figure><img src="/files/uw7a5ZIGxtbHfpGPmc54" alt=""><figcaption></figcaption></figure>

The service shows **Enabling** at the status while creating all resources specified in the service commissioning file. Once complete, the status changes to **Enabled**.

<figure><img src="/files/QAjnysBbb78e6Oi76NeC" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/uOWCwlRFevwueFjEYuTS" alt=""><figcaption></figcaption></figure>

4. Select the **Live Data** tab to get insights into topic activity, message content, and associated resources of your service. For more information, see [Live Data](/monitoring/live-data).

<figure><img src="/files/bjFyl2msLbJMLXWqgF7R" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
If a service does not work as expected, it may have a deviation. Check the [Deviation](/data-flows/services/deviations) tab to see all deviated services.
{% endhint %}

## Troubleshooting

### Invalid Service Commissioning Files

If a service commissioning file with invalid resources, references, or other defects is installed, it will fail to be enabled and will result in the service being deviated.

If this happens, manually reinstall the previous working version of the service commissioning file. Keep backups of stable versions so they can be restored when needed.

To prevent such issues, it is recommended to validate your service commissioning files before installation and maintain backups of working configurations.


# Updating Services

Update a service by uploading a new commissioning file or changing its parameters in the Admin UI.

You can modify a service by either uploading an updated service commissioning file or reconfiguring its parameters in the Admin UI.

1. In the **Service Details** view of the service that you want to update, click **Update**.

<figure><img src="/files/EFtGvYkoF0pJYJXaeEwx" alt=""><figcaption></figcaption></figure>

2. In the **Update or Reconfigure Service** dialog, do one of the following:

* **Upload a service commissioning file**: Click **Choose File**, select the updated service commissioning file in the file browser, and click **Open**.
* **Edit parameters in the Admin UI**: In the **Reconfigure service** section, edit the parameters as needed. Some fields may show default values, depending on the service.

<figure><img src="/files/bU0dOBRHZoLq9enzvEnG" alt=""><figcaption></figcaption></figure>

* **If the service came from the Services Catalog**: The **Update or Reconfigure Service** dialog shows the available versions. If a newer version is available and you want to upgrade, select **Use version** (the latest version number).

<figure><img src="/files/AfnFfucdT9VgevftEnwJ" alt=""><figcaption><p>Version selection for services installed from the Services Catalog</p></figcaption></figure>

3. If the service contains configurable parameters, customized values for the parameters can be entered in the right part of the window.

<figure><img src="/files/opjwPgPa6d8VjLdhqVN0" alt=""><figcaption></figcaption></figure>

4. Click **Update** to apply your changes.

Result: The service status will temporarily change to **Updating**, then revert to its original state (**Enabled** or **Disabled**).

{% hint style="warning" %}
If the updated configuration is invalid, the service is not updated and the previous configuration is restored.
{% endhint %}


# Disabling Services

Disable individual or multiple services in Connectware to stop their containers, connections, endpoints, and mappings.

You can disable services in their corresponding **Service Details** view or disable multiple services at once in the **Services** view.

{% hint style="warning" %}
Disabling a service will terminate all running containers, active connections, endpoints, and mappings associated with it. However, volumes will remain unchanged and will automatically reattach to the service when it is re-enabled.
{% endhint %}

## Disabling Multiple Services

1. On the navigation panel, click **Services**.
2. In the **Services** view, activate the checkboxes of the services that you want to disable.
3. Click **Disable**.
4. In the **Disable Services** dialog, click **Disable**.

<figure><img src="/files/jmtu8dwuT4LRcVh4O5Df" alt=""><figcaption></figcaption></figure>

## Disabling a Service from its Service Details View

1. In the **Service Details** view of a service, click **Disable**.
2. In the **Disable Service** dialog, click **Disable**.
3. In the **Disable Services** dialog, click **Disable**.


# Deleting Services

Disable and delete services that you no longer need in the Services view of Connectware.

{% hint style="warning" %}
When a service is disabled, all running containers, active connections, endpoints, and mappings are stopped. Volumes are not affected and will automatically reattach when the service is re-enabled.
{% endhint %}

1. Before deleting a running service, you must disable it first. For details, see [Disabling Services](/data-flows/services/managing/disabling).
2. On the navigation panel, click **Services**.
3. In the **Services** view, activate the checkboxes of the services that you want to delete.
4. Click **Delete**.

<figure><img src="/files/OHjnrbU0QGOdhWulchGn" alt=""><figcaption></figcaption></figure>

5. In the **Delete Service** dialog, click **Delete** to delete the service.

<figure><img src="/files/eJs0xxYfi3Z8uC5l5Pja" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
After deleting a service, there is a waiting period required before you can install another service with the same service ID. You can customize the waiting period via the `CYBUS_SERVICE_REINSTALL_DELAY_SECONDS` [environment variable](/reference/environment-variables).
{% endhint %}


# Service Overview

Start in the Service Overview to install new services and drill down into the details of any running service.

The **Service Overview** allows you to upload, configure, and monitor services. The details of a service are described in a service commissioning file in the text-based YAML format, which includes metadata, parameters, connections, endpoints, mappings, and volumes.

You can click a service to open its [**Service Details** view](/data-flows/services/service-details-view). This view allows you to gain deep insights into each service, facilitating thorough understanding and precise control of service operations.

* To open the **Service Overview**, click **Services** on the navigation panel.

<div data-with-frame="true"><figure><img src="/files/faWqNkrusktDfXzzR6kZ" alt=""><figcaption><p><strong>Service Overview</strong></p></figcaption></figure></div>

In the Service Overview, the following information and options are available:

**Upload Service**

* Upload service commissioning files to Connectware to [install services](/data-flows/services/managing/installing).

**Search**

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search is case-insensitive.

**Service ID**

* The unique identifier of each service.

**Name**

* The name of each service.

**Version**

* The version number of each service, if applicable.

**Links**

* The links for specific functions of the service (e.g. dashboards, servers).

<div data-with-frame="true"><figure><img src="/files/djiwSN484JFA3H9PLfEq" alt=""><figcaption><p>Links in the <strong>Service Overview</strong></p></figcaption></figure></div>

**Status**

* The current state of the service (e.g., enabled or not enabled).

**Deviation**

* The current state of the [deviations](/data-flows/services/deviations) (e.g., no deviation or deviation).


# Service Resources View

Inspect every resource across all services from a single view instead of opening each Service Details view individually.

In Connectware, resources are the foundation of a service. You can monitor and configure all resources for your services, such as containers, volumes, connections, endpoints, or mappings.

For each resource, you can either see the configuration for all services in the **Service Resources** view or for an individual service in their respective **Service Details** view.

* To open the **Service Resources** view, click **Services** on the navigation panel and click **Service Resources**.

<figure><img src="/files/bvudeTGAMKwOaqO9AM13" alt=""><figcaption><p>Resources menu</p></figcaption></figure>

There following resource views are available:

* [Service Links View](/data-flows/services/service-resources-view/service-links-view)
* [Servers View](/data-flows/services/service-resources-view/servers-view)
* [Containers View](/data-flows/services/service-resources-view/containers-view)
* [Volumes View](/data-flows/services/service-resources-view/volumes-view)
* [Connections View](/data-flows/services/service-resources-view/connections-view)
* [Endpoints View](/data-flows/services/service-resources-view/endpoints-view)
* [Mappings View](/data-flows/services/service-resources-view/mappings-view)

## API Definition for Resources

The API definition for resources are available here: [Resources API](/reference/api-reference/resources-api)

### Search

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.


# Service Links View

Open external web pages or container-hosted web interfaces that services expose as Cybus::Link resources.

## Overview

The **Service Links View** provides an overview of all [Cybus::Link](/data-flows/service-commissioning-files/resources/cybus-link) resources. The link resource provides direct access to web resources. This resource can be external to Connectware or refer to a location that is available within a web server of a container. For more information, see [Service Links Details View](/data-flows/services/service-resources-view/service-links-view).

* To open the **Service Links View** for all service links, click **Services** > **Service Resources** and click the **Service Links** tab.

<figure><img src="/files/LbMJ3UfZDQEQ5bw30rce" alt=""><figcaption><p>Service Links View</p></figcaption></figure>

In the list, all service links are displayed with the following information:

**Service ID**

* The unique identifier of the service that contains this service link.

**Name**

* The name of the service link.

**Links**

* The link provides direct access to web resources of this service. This resource can be external to Connectware or refer to a location that is available within a web server of a container. For example, a dashboard.

## Service Links Details View

* To open the **Service Links Details View** for a specific service, click **Services** > **Service Resources** and select a service.

<figure><img src="/files/nUNUQ8JvVINhYyiz8Qcj" alt=""><figcaption><p>Connections Details View</p></figcaption></figure>

At the top of the **Service Links Details View**, the following information is displayed:

**Service ID**

* The unique identifier of the service that contains this service link.

**Name**

* The name of the service link (e.g. Cybus Data Monitor).

**Description**

* A description of the service link.

**Provider**

* The provider of the service link.

**Version**

* The version of the service link.

**Status**

* The current state of the service link (e.g., enabled).

**Deviation**

* The status of the deviation of the service link (e.g., no deviation).

### Service Links Logs

You can view detailed log messages for the service links of the selected service in the **Service Logs** tab of the **Service Links Details View**.

**Download CSV**

* Export the visible log entries as a CSV file.

{% hint style="info" %}
The log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the raw logs that contain the full logs, see [Logs of All Services](/data-flows/services/service-logs/service-logs-of-all-services).
{% endhint %}

**Refresh Logs**

* Refresh the log messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view log messages.

**Search**

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.

**Level**

* The type of message. For example, info or warning.

**Time**

* Shows the exact date and time when each log message was generated.

**Message**

* Displays the message of the log (e.g., **lathe\_01: Enabled InfluxdbConnection**).


# Servers View

Monitor the server resources that give clients access to Connectware data, such as OPC UA or REST servers, in the Servers View.

A server provides several options for client access to Connectware data, such as through OPC UA or RESTful interaction. Alternatively, you can access the data of the MQTT broker through the MQTT API. The data of the server resource is structured by node resources that define the available data structure.

See also: [Cybus::Server resource](/data-flows/service-commissioning-files/resources/cybus-server)

## Overview

The **Servers View** displays all active and inactive servers. Click a server for further information about its configuration and the associated nodes.

* To open the **Servers** view, click **Services** on the navigation panel and click **Service Resources**. In the **Service Resources** view, click the **Servers** tab.

<figure><img src="/files/aFvvpCocnAAtI8UYgPvr" alt=""><figcaption><p>Servers View</p></figcaption></figure>

In the list, all servers are displayed with the following information:

**Service ID**

* The unique identifier of the service that contains this server.

**Name**

* The name of the server.

**Protocol**

* The communication protocol used for the server (e.g., Modbus, HTTPS, OPC UA).

**Status**

* The current state of the server.

## Server Details View

* To open the **Server View** for a specific service, click **Services** > **Service Overview** and select a service. In the **Service Details View** of the selected service, click the **Servers** tab.

The following information is displayed:

### Server Logs

Shows the server logs of the selected server.

<figure><img src="/files/FPHvbOPYYGZDm02Vsx1V" alt=""><figcaption></figcaption></figure>

**Download CSV**

* Export the visible log entries as a CSV file.

{% hint style="info" %}
The log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the raw logs that contain the full logs, see [Logs of All Services](/data-flows/services/service-logs/service-logs-of-all-services).
{% endhint %}

**Refresh Logs**

* Refresh the log messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view log messages.

**Search**

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.

**Level**

* The type of message. For example, info or warning.

**Time**

* Shows the exact date and time when each log message was generated.

**Message**

* Displays the message of the log (e.g., **Started HTTP Server A23 on port: 8080**).

### Nodes

Shows the associated nodes of the selected server.

<figure><img src="/files/y98Oe0BxLtX8QgYnAy68" alt=""><figcaption></figcaption></figure>

**Service ID**

* The unique identifier of the service that contains this server.

**Name**

* The name of the server.

**Parent**

* The parent server of the active server.

**Protocol**

* The communication protocol used for the server (e.g., Modbus, HTTPS, OPC UA).

**Operation**

* The operation of the server.

**Status**

* The current state of the server.

**Search**

* Find specific nodes by keyword. The search filters the displayed service log messages, showing only matching results.
  * Minimum search length is 3 characters.
  * Search services by service ID or name.
  * Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
  * Search is case-insensitive.


# Containers View

Monitor the containers that run third-party applications for your services in the Containers View of Connectware.

Containers allow you to extend the basic functionality of Connectware.

A container represents any (third-party) application made available using the docker ([https://www.docker.com](https://www.docker.com/)) technology. There are no limits on the range of possible applications in Docker containers.

Connectware imposes no constraints on the actual containers, but will ensure security by running the containers in encapsulated networks. This way the containerized applications can neither compromise the host system nor access any other data except those explicitly granted access to within the service commissioning file (see [Services](/data-flows/services)).

{% hint style="info" %}
This feature is available only in Docker Compose deployments, but not in Kubernetes deployments of Connectware. Using this in a Kubernetes deployment will be refused with a suitable error message.
{% endhint %}

See also: [Cybus::Container resource](/data-flows/service-commissioning-files/resources/cybus-container)

Containers can be added by [installing a Service](/data-flows/services/managing/installing).

## Overview

Once a service using one or more containers is enabled, respective rows representing each container will be visible in the overview table.

<figure><img src="/files/pvpZhwo6dq4VppDBUQ1Z" alt=""><figcaption></figcaption></figure>

Once the service is in the *enabled* state, basic manual interaction with the container is possible by selecting the checkbox on the left side of the row in the overview table. Activating this checkbox will show the toolbar, where buttons for manually stopping and starting the container are available.

<figure><img src="/files/b4XNZYucm7ayVmz9kKOK" alt=""><figcaption></figcaption></figure>

Once stopped, containers can also be removed by clicking the delete icon in the toolbar.

{% hint style="warning" %}
Manual stopping or deletion of containers will render the corresponding service to be [deviated](/data-flows/services/deviations) (i.e. only partially functional). This is indicated by a yellow warning popup window at the bottom left of the screen. To restore the initial settings it is always possible to [disable](/data-flows/services/managing/disabling) and then again [enable the service](/data-flows/services/managing/enabling).
{% endhint %}

Like every other resource, containers have a detail view. By clicking on one of the listed containers you get redirected to the [Details View](#details-view) of the selected container.

## Containers Details View

Containers have multiple resources itself. These are grouped in [Configuration Tab](#configuration-tab) and [Environment Variables Tab](#environment-variables-tab). Additionally, you can see the container logs in the **Container Logs** tab.

<figure><img src="/files/b89QLo3TFklOMNMYo1U8" alt=""><figcaption></figcaption></figure>

### Configuration Tab

This tab shows the configuration properties of the selected container.

<figure><img src="/files/eU5I9OrwqYPET4ff8LYL" alt=""><figcaption></figcaption></figure>

### Environment Variables Tab

This tab shows the specified environment variables that are specified for the selected container.

<figure><img src="/files/9dye7ZLVTsfrJXUb5ONz" alt=""><figcaption></figcaption></figure>


# Volumes View

Check the persistent storage volumes that your services use in Docker Compose deployments of Connectware.

Volumes provide persistent storage for services. The overview page displays information about the associated service, the volume name ([resource ID](/data-flows/service-commissioning-files/resources#resource-id)), creation date and time, and current status.

See also: [Cybus::Volume resource](/data-flows/service-commissioning-files/resources/cybus-volume)

{% hint style="info" %}
This feature is available only for Docker Compose deployments of Connectware. It is not supported on Kubernetes.
{% endhint %}

## Overview

<figure><img src="/files/d37nhwShw11I7wHZUEC2" alt=""><figcaption></figcaption></figure>

Clicking on a listed volume redirects you to the [Volume Details View](#volume-details-view) for that volume.

## Volume Details View

Each volume has its own resources. For a selected volume, the **Volume Logs** and **Labels** tabs are available.

<figure><img src="/files/Wuow31pLUl4hqzv2XFG7" alt=""><figcaption></figcaption></figure>


# Connections View

Check which protocol connections of your services are currently established and inspect the details of each connection.

Connections are resources that allow you to connect to devices over [protocols](/connectors/shop-floor-connectors). The **Connections View** shows an overview of all active and inactive protocol connections.

See also: [Cybus::Connection resource](/data-flows/service-commissioning-files/resources/cybus-connection)

In Connectware, you can monitor the connections of all services in the [Connections View](#connections-view) and connections of individual services in the [Connection Details View](#connection-details-view).

## Overview

The **Connections View** displays all available protocol connections, including their service ID, connection ID, host, and port. You can click a connection for more information about its configuration. For more information, see [Connection Details View](#connection-details-view).

* To open the **Connections View** for all connections, click **Services** > **Service Resources** and click the **Connections** tab.

<figure><img src="/files/rqJ1uGvYU9lBDMOMp3fr" alt=""><figcaption><p>Connections View</p></figcaption></figure>

In the list, all connections are displayed with the following information:

**Service ID**

* The unique identifier of the service that contains this connection.

**Connection ID**

* The unique identifier assigned to this specific connection within the service.

**Protocol**

* The communication protocol used for the connection (e.g., Modbus, HTTPS, OPC UA).

**Host**

* The hostname or IP address of the target system or device.

**Port**

* The network port number used for the connection.

**Agent**

* The agent to which this connection is assigned.

**Status**

* The current state of the connection (e.g., connected or not connected).

## Connection Details View

* To open the **Connection View** for a specific service, click **Services** > **Service Overview** and select a service. In the **Service Details View** of the selected service, click the **Connections** tab.

<figure><img src="/files/z7lpMQ94iAelP293m4s9" alt=""><figcaption><p>Connections Details View</p></figcaption></figure>

At the top of the **Connection Details View**, the following information is displayed:

**Connection ID**

* The unique identifier assigned to this specific connection within the service.

**Service ID**

* The unique identifier of the service that contains this connection.

**Host**

* The hostname or IP address of the target system or device.

**Port**

* The network port number used for the connection.

**Agent**

* The agent to which this connection is assigned.

**Status**

* The current state of the connection (e.g., connected or not connected).

## Resources of Connections

Each connection has resources itself.

* To open the resources of connections, click a connection in the **Connections View**.

<figure><img src="/files/liX4mfKcOq7GLFfekIF4" alt=""><figcaption><p>Connections Details View with open resources</p></figcaption></figure>

### Connection Logs

You can view detailed log messages for the connections of the selected service in the **Connection Logs** tab of the **Connection Details View**.

**Download CSV**

* Export the visible log entries as a CSV file.

{% hint style="info" %}
The log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the raw logs that contain the full logs, see [Logs of All Services](/data-flows/services/service-logs/service-logs-of-all-services).
{% endhint %}

**Refresh Logs**

* Refresh the log messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view log messages.

**Search**

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.

**Level**

* The type of message. For example, info or warning.

**Time**

* Shows the exact date and time when each log message was generated.

**Message**

* Displays the message of the log (e.g., **lathe\_01: Enabled InfluxdbConnection**).

#### Log Details Dialog

The **Log Details dialog** provides in-depth information about specific log entries in the service logs.

* To open the **Log Details dialog**, click a log entry of a service.

<figure><img src="/files/LtuSEJC1GtHqBrfx6LbV" alt=""><figcaption></figcaption></figure>

When you select a log entry, this dialog displays the following fields:

**Time**

* The timestamp of the log entry in Unix milliseconds format (.e.g., **1728878765733**).

**Pid**

* The Process ID associated with the log entry.

**Hostname**

* The name of the host or service that generated the log (e.g., **protocol-mapper**).

**Class Name**

* The class or category of the log entry (e.g., **InfluxdbConnection**).

**Message**

* A detailed description of the logged event (e.g., **lathe\_01: Enabled ModbusConnection**).

### Configuration

**Name**

* The name of the configuration (e.g., **maxRetryDelay**).

**Value**

* The value of the configuration.

### Endpoints

Lists the endpoints that are associated with the connection.

**Service ID**

* The unique identifier of the service that contains this endpoint (e.g., **lathe\_01**).

**Name**

* The name of the endpoint (e.g., **temperature**).

**Protocol**

* The communication protocol used for the endpoint (e.g., Modbus, HTTPS, OPC UA).

**Agent**

* The agent to which this connection is assigned.

**Status**

* The current state of the endpoint (e.g., enabled or enabling).


# Endpoints View

Monitor the data endpoints of your services and their protocol addresses in the Endpoints View of Connectware.

Endpoints describes the address of a single data endpoint within a specific protocol.

See also: [Cybus::Endpoint resource](/data-flows/service-commissioning-files/resources/cybus-endpoint)

## Overview

<figure><img src="/files/1jAAMo6qU9n7iu5ScsGA" alt=""><figcaption><p>Endpoints View</p></figcaption></figure>

In the list, all endpoints are displayed with the following information:

**Service ID**

* The unique identifier of the service that contains this endpoint.

**Name**

* The name of the endpoint (e.g. current, rpm, temperature).

**Connection ID**

* The unique identifier assigned to this specific endpoint within the service.

**Protocol**

* The communication protocol used for the endpoint (e.g., Modbus, HTTPS, OPC UA).

**Operation**

* The operation type of the endpoint (e.g., subscribe or publish).

**Agent**

* The agent that is assigned to the endpoint.

**Status**

* The current state of the endpoint (e.g., enabled or disabled).

## Endpoint Details View

* To open the **Endpoint View** for a specific service, click **Services** > **Service Overview** and select a service. In the **Service Details View** of the selected service, click the **Endpoints** tab.

<figure><img src="/files/SygJj4rlhMkrHvFb4DH4" alt=""><figcaption><p>Endpoint Details View</p></figcaption></figure>

At the top of the **Endpoint Details View**, the following information is displayed:

**Name**

* The name of the endpoint (e.g. current, rpm, temperature).

**Service ID**

* The unique identifier of the service that contains this endpoint.

**Protocol**

* The communication protocol used for the endpoint (e.g., Modbus, HTTPS, OPC UA).

**Operation**

* The operation type of the endpoint (e.g., subscribe or publish).

**Agent**

* The agent that is assigned to the endpoint.

**Status**

* The current state of the endpoint (e.g., enabled or disabled).

**Topics**

* The topic of the endpoint. You can monitor all topics in the Data Explorer.

## Resources of Endpoints

Each endpoint has resources itself.

* To open the resources of endpoints, click an endpoint in the **Endpoints View**.

### Endpoint Logs

You can view detailed log messages for the endpoints of the selected service in the **Endpoints Logs tab** of the **Endpoint Details View**.

**Download CSV**

* Export the visible log entries as a CSV file.

{% hint style="info" %}
The log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the raw logs that contain the full logs, see [Logs of All Services](/data-flows/services/service-logs/service-logs-of-all-services).
{% endhint %}

**Refresh Logs**

* Refresh the log messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view log messages.

**Search**

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.

**Level**

* The type of message. For example, info or warning.

**Time**

* Shows the exact date and time when each log message was generated.

**Message**

* Displays the message of the log (e.g., **lathe\_01: Enabled InfluxdbEndpoint**).

#### Log Details Dialog

The **Log Details dialog** provides in-depth information about specific log entries in the service logs.

* To open the **Log Details dialog**, click a log entry of a service.

<figure><img src="/files/LtuSEJC1GtHqBrfx6LbV" alt=""><figcaption></figcaption></figure>

When you select a log entry, this dialog displays the following fields:

**Time**

* The timestamp of the log entry in Unix milliseconds format (.e.g., **1728878765733**).

**Pid**

* The Process ID associated with the log entry.

**Hostname**

* The name of the host or service that generated the log (e.g., **protocol-mapper**).

**Class Name**

* The class or category of the log entry (e.g., **InfluxdbEndpoint**).

**Message**

* A detailed description of the logged event. Example: **lathe\_01: Enabled ModbusEndpoint**

### Address

The **Address** lists the address property specified for the endpoint in the service commissioning file.

**Name**

* The name of the address (e.g. length or interval).

**Value**

* The value of the address.

**Search**

* Find specific addresses by keyword.

### Rules

The **Rules tab** lists associated Rule Engine rules for the endpoint. The rules define how data should be processed between subscribing and publishing. For more information, see [Rule Engine](/data-flows/rule-engine).


# Mappings View

Follow how data flows through your services by inspecting all deployed mapping resources in Connectware.

Mappings describe the data flow from one topic to another, such as the data flow between devices and processing rules.

See also: [Cybus::Mapping resource](/data-flows/service-commissioning-files/resources/cybus-mapping)

## Overview

<figure><img src="/files/rZWhu4lU2gPodq5F23Fx" alt=""><figcaption><p>Connections Overview</p></figcaption></figure>

In the list, all mappings are displayed with the following information:

**Service ID**

* The unique identifier of the service that contains this mapping.

**Name**

* The name of the mapping.

**Entries**

* The number of entries for the mapping.

**Agent**

* The agent that is assigned to the mapping.

**Status**

* The current state of the mapping (e.g., enabled or enabling).

## Mapping Details View

* To open the **Mappings View** for a specific service, click **Services** > **Service Overview** and select a service. In the **Service Details** view of the selected service, click the **Mappings** tab.

<figure><img src="/files/K652A6FH2mbhvEUohac9" alt=""><figcaption><p>Mapping Details View</p></figcaption></figure>

At the top of the **Mapping Details View**, the following information is displayed:

**Mapping ID**

* The unique identifier of the service that contains this mapping.

**Service ID**

* The unique identifier of the service that contains this mapping.

**Entries**

* The number of entries for the mapping.

**Agent**

* The agent that is assigned to the mapping.

**Status**

* The current state of the mapping (e.g., enabled or enabling).

## Resources of Mappings

Each mapping has resources itself.

* To open the resources of mappings, click a mapping in the **Mappings View**.

See also: [Cybus::Mapping resource](/data-flows/service-commissioning-files/resources/cybus-mapping)

{% hint style="warning" %}
For reliable operation, MQTT shared subscriptions are not supported in the **Entries tab**, as they could interfere with other clients subscribed to the same topics.
{% endhint %}

<figure><img src="/files/GiemxOUXFmAZ2P5vnBtb" alt=""><figcaption></figcaption></figure>

**Subscribe**

* The resource that the mapping subscribes data from.

**Subscribe Broker**

* Indicates which message broker is used to receive the subscribed data (e.g., internal).

**Publish**

* The resource that the mapping publishes data to. You can click the entry to open the details view of the resource.

**Publish Broker**

* Indicates which message broker is used to publish the data (e.g., internal).

**Rules**

The **Rules tab** lists associated Rule Engine rules for the mapping. The rules define how data should be processed between subscribing and publishing. For more information, see [Rule Engine](/data-flows/rule-engine).

### Search

The search allows you to filter the list.

* Minimum search length is 3 characters.
* Search services by service ID or name.
* Search resources by name, ID, protocol, parent resource ID, agent name, or service ID.
* Search is case-insensitive.


# Service Details View

Examine individual services in the Service Details view to inspect configurations, monitor live data and metrics, and access logs.

The **Service Details** view serves as a comprehensive interface for examining individual services, offering users the ability to delve into specific service configurations, monitor real-time data, and efficiently manage various service-related aspects. This view allows you to gain deep insights into each service, facilitating thorough understanding and precise control of service operations.

Key components include:

* **Service Configuration**: View and modify service settings
* **Live Data**: Monitor real-time MQTT topic data
* **Metrics**: Analyze service performance and usage statistics
* **Logs**: Access service-specific log entries for troubleshooting

## Opening the Service Details View

* To open the **Service Details** view for a service, click **Services** in the navigation panel and click a service.

<div data-with-frame="true"><figure><img src="/files/otbH4pXQWMtIwgFuJa0V" alt=""><figcaption><p><strong>Service Details</strong> view</p></figcaption></figure></div>

## Sections of the Service Details View

The **Service Details** view contains the following functions:

* The top left displays essential service attributes, including the service name, [ServiceID](/data-flows/services/serviceid), description, agent, provider, status, and any detected [deviations](/data-flows/services/deviations). If defined in the service commissioning file, service-specific action buttons are also presented here.
* On the top right, you can [enable](/data-flows/services/managing/enabling), [disable](/data-flows/services/managing/disabling), and [update](/data-flows/services/managing/updating) the service, including the option to download the corresponding [service commissioning file](/data-flows/service-commissioning-files).
* The lower section is organized into [tabs](#tabs-of-the-service-details-view), each representing different resources utilized by the service.

## Tabs of the Service Details View

The **Service Details** view contains the following tabs:

* **Service Logs**: Displays operational logs and events related to the service. For more information, see [Service Logs](/data-flows/services/service-logs).
* **Live Data**: Allows you to monitor MQTT topics of the selected service for insights into topic activity. For more information, see [Live Data](/monitoring/live-data).
* **Servers**: Lists physical or virtual servers associated with the service. For more information, see [Servers View](/data-flows/services/service-resources-view/servers-view).
* **Containers**: Shows containerized components of the service, if applicable. For more information, see [Containers View](/data-flows/services/service-resources-view/containers-view).
* **Volumes**: Displays information about storage volumes allocated to the service. For more information, see [Volumes View](/data-flows/services/service-resources-view/volumes-view).
* **Connections**: Details network connections and integrations used by the service. For more information, see [Connections View](/data-flows/services/service-resources-view/connections-view).
* **Endpoints**: Lists service endpoints. For more information, see [Endpoints View](/data-flows/services/service-resources-view/endpoints-view).
* **Mappings**: Displays any data or resource mappings configured for the service. For more information, see [Mappings View](/data-flows/services/service-resources-view/mappings-view).
* **Deviations**: Provides a detailed view of any detected anomalies or deviations from expected service behavior. For more information, see [Deviation](/data-flows/services/deviations).


# Service ID

Unique identifier for services and inter-service communication.

A **service ID** uniquely identifies each service and enables [inter-service referencing](/data-flows/services/inter-service-referencing). It ensures that services can be reliably referenced, managed, and deployed. When you are using the same service commissioning file for multiple service instances, you must define a unique service ID for each instance.

## Default Service ID

A default service ID is automatically generated from the `name` property in the service commissioning file's [metadata](/data-flows/service-commissioning-files/metadata#name) when uploading a service commissioning file to Connectware. Non-permitted characters are removed and remaining characters are converted to lowercase during this process.

However, the `name` field in the service commissioning file does **not** define the service ID. It only influences the default value.

You must change the default service ID to a unique value if the service commissioning file is used for more than one instance. See [Defining Service IDs](#defining-service-ids).

## Defining Service IDs

You can define service IDs manually via:

* **Admin UI**: After uploading a service commissioning file, Connectware creates a default service ID based on the `name` property. You can edit the default service ID in the **Create Service** dialog before confirming the installation. See [Defining the Service ID via the Admin UI](#defining-the-service-id-via-the-admin-ui).
* **Deployment pipeline**: If your service commissioning files are deployed automatically in a rollout process, the service IDs must be calculated and set to prevent setup conflicts. For example, a single service commissioning file could be deployed multiple times with different IDs and parameterization to provide resources to multiple distributed agents.

{% hint style="info" %}
We provide an [Ansible Collection](https://galaxy.ansible.com/ui/repo/published/cybus/connectware/) to simplify automated Connectware deployments.
{% endhint %}

### Defining the Service ID via the Admin UI

The default service ID is auto-generated when uploading the service commissioning file to Connectware. You must change the default service ID to a unique value if the service commissioning file is used for more than one instance.

1. In the **Services View**, click **Upload Service** to add a new service commissioning file.
2. In the **Create Service** dialog, click **Choose File**.
3. In your file browser, select your service commissioning file and click **Open**.
4. The default service ID is displayed in the **Configure the new service** section.

**Example:** If the `name` property in the service commissioning file is set to `PressLine_TempSensor-01`...

{% code title="press\_line\_12.yml" lineNumbers="true" %}

```yaml
metadata:
  name: PressLine_TempSensor-01
```

{% endcode %}

...the auto-generated service ID will be `presslinetempsensor01`.

<figure><img src="/files/LH1EkqjbEQibqop9CpM0" alt=""><figcaption><p>Example of the resulting service ID presslinetempsensor01 displayed during upload to Connectware in the Create Service dialog.</p></figcaption></figure>

5. Change the default service ID to a unique service ID. This is particularly relevant when using the same service commissioning file for multiple service instances. Adhere to the [Service ID Requirements](#service-id-requirements).
6. Optional: Make additional configurations in the **Create Service** dialog.
7. Click **Install**.

## Service ID Requirements

Follow these requirements when defining service IDs:

* **Length**: See [Service ID Length Restrictions](#service-id-length-restrictions).
* **Allowed characters**:
  * ASCII letters (both lowercase and uppercase)
  * Numbers
  * Underscore (`_`)
  * Period (`.`)
* **Pattern**: Must follow the regular expression pattern: `[a-zA-Z0-9][a-zA-Z0-9_.]*`
* **Restrictions**: Hyphens (`-`) are not permitted in service IDs as they serve as special separators between service IDs and usernames in Connectware's Docker container resource management.

This is validated automatically when you are installing a service via the **Create Service** dialog. See [Defining the Service ID via the Admin UI](#defining-the-service-id-via-the-admin-ui).

## Service ID Length Restrictions

The maximum length of the **service ID** and the **resource ID** are interdependent. The combination of `service ID + hyphen + resourceName` forms the [resource ID](/data-flows/service-commissioning-files/resources#resource-id). Make sure to stay within the limit of the resource ID when defining service IDs and resource names.

* **General restriction**: The combination of `serviceId + hyphen + resourceName` must be **100 characters or fewer**.
* **Docker hostname restriction**: When a service includes [Cybus::Container](/data-flows/service-commissioning-files/resources/cybus-container) or [Cybus::Volume](/data-flows/service-commissioning-files/resources/cybus-volume), the combination of `serviceId + hyphen + resourceName` must be **63 characters or fewer**.

{% hint style="warning" %}

* If you have long resource names, consider abbreviations to keep the combined string within the applicable limit.
* Do not add an extra hyphen. Connectware adds one automatically.
  {% endhint %}

### Determining the Service ID Length (Examples)

Here are examples on how you can determine the maximum length of a service ID.

<details>

<summary><strong>A) Example for the General Limit (100 Characters)</strong></summary>

* Resource name: **10 characters**
* Calculation: **max.length - hyphen - resourceName.length**
* Remaining for the service ID: **100 - 1 - 10** = **89**
* Result: The service ID must be **89 characters or fewer**.

</details>

<details>

<summary><strong>B) Example for the Docker-Only Limit (63 Characters)</strong></summary>

The following length limitation only applies to Docker-based deployments where service IDs are used in hostnames for containers ([Cybus::Container](/data-flows/service-commissioning-files/resources/cybus-container)) or volumes ([Cybus::Volume](/data-flows/service-commissioning-files/resources/cybus-volume)).

* Resource name: **10 characters**
* Calculation: **max.length - hyphen - resourceName.length**
* Remaining for service ID: **63 - 1 - 10** = **52**
* Result: The service ID must be **52 characters or fewer**.

</details>


# Inter-Service Referencing

Building modular service architecture by referencing resources across service commissioning files.

Inter-service referencing enables resources in one service commissioning file to depend on resources defined in other service commissioning files. This allows you to build modular, reusable services that can be composed together to create complex architectures.

By default, resources within a service commissioning file can only reference other resources in the same file. Inter-service referencing breaks this limitation, allowing you to:

* Create reusable connection definitions that multiple services can share.
* Build modular architectures where services have clear separation of concerns.
* Manage complex deployments by breaking them into smaller, focused components.

## Referencing Resources Across Services

To reference a resource in another service:

{% code lineNumbers="true" %}

```yaml
!ref '${otherServiceName}::resourceId'
```

{% endcode %}

Where:

* `otherServiceName` is the service that contains the target Service ID.
* `resourceId` is the ID of the resource in the target service.

To reference a resource from another service:

* **Do not hardcode the Service ID** directly.
* Instead, use a parameter that dynamically provides the correct Service ID at runtime.

parameterName is a parameter that contains the target Service ID resourceId is the ID of the resource in the target service

For example, if you define a parameter named `otherServiceName`, you can reference a resource in that service as:

{% code lineNumbers="true" %}

```yaml
!ref '${otherServiceName}::resourceId'
```

{% endcode %}

For further details, see [Service ID](/data-flows/services/serviceid) and [Resource ID](/data-flows/service-commissioning-files/resources#resource-id).

## Service Dependency Behavior

Connectware enables advanced relationships between services. Understanding how these interdependencies behave at runtime is crucial for correct deployment and maintenance.

* **Child services**: Services that reference other services.
* **Parent services**: Services that are referenced by others.

### Installation Order

* Install parent services first (recommended):
  * Service relations are created automatically during installation.
  * Both parent and child services can be installed with `targetState=enabled`.
  * This is the most reliable approach and avoids issues during activation.
* Install child services first (alternative):
  * Service relations are only established once the parent service becomes available and the child is enabled.
  * The dependent (child) service can only be installed with `targetState=disabled`.
  * Attempting to install and enable a child without its parent will fail until the parent is added. Logs in Service Manager will indicate the unresolvable reference.

For more details, see [targetState](/data-flows/service-commissioning-files/resources/cybus-endpoint#targetstate).

### Expected Behaviors

Following are four scenarios and how the services behave in each case:

1. All services are installed and then enabled in parents/child order.
   1. This behaves as any other set of services.
   2. Disabling a `Parent Service` will disable all its `Child Services`.
2. All services are installed and then enabled in random order.
   * `Child Services` will not wait on the `Enabling` state and the request will fail.
3. `Child Services` are installed first without `Parent Service` present.
   1. These services must be installed with targetState=disabled.
   2. Trying to enable them before the parent exists will fail, with Service Manager logs indicating the missing reference.
   3. Once the parent service is added, enabling the child succeeds and the relation is established.
4. Parents services are installed first without child presents.
   * No special behavior. When child services are later added, this behaves as cases 1 or 2.

### Example

The following service commissioning files demonstrate the behaviors described above:

1. A Cybus::Container running a database
   * Service ID will be `mssqldatabase`
2. A Cybus::Connection connecting to the database
   * Service ID will be `serviceaconnection`
3. A Cybus::Endpoint using referencing to use that Connection
   * Service ID will be `servicebendpoint`

By deploying these, you can reproduce all the installation and dependency behaviors.

#### SQL Database

{% code lineNumbers="true" %}

```yaml
description: MSSQL Database
metadata:
  name: MSSQL Database

definitions:
  password: password1234!

resources:
  mssqlDatabase:
    type: Cybus::Container
    properties:
      image: mcr.microsoft.com/mssql/server
      ports:
        - '1433:1433'
      environment:
        ACCEPT_EULA: 'Y'
        SA_PASSWORD: !ref password
```

{% endcode %}

#### SQL Connection

{% code lineNumbers="true" %}

```yaml
description: MSSQL Connection
metadata:
  name: Service A Connection

parameters:
  ip_host:
    type: string
    title: IP address or hostname where Connectware is installed

definitions:
  port: 1433
  database: master
  username: sa
  password: password1234!

resources:
  mssqlConnection:
    type: Cybus::Connection
    properties:
      protocol: Mssql
      connection:
        host: !ref ip_host
        port: !ref port
        username: !ref username
        password: !ref password
        database: !ref database
        useEncryption: false
```

{% endcode %}

#### SQL Endpoint

{% code lineNumbers="true" %}

```yaml
description: Service B
metadata:
  name: Service B Endpoint

parameters:
  mssqlConnectionServiceId:
    type: string
    title: Service ID of the MSSQL Connection

resources:
  mssqlVersionB:
    type: Cybus::Endpoint
    properties:
      protocol: Mssql
      connection: !ref '${mssqlConnectionServiceId}::mssqlConnection'
      subscribe:
        query: 'SELECT @@version'
        interval: 1000
```

{% endcode %}


# Deviations

Spot and fix service resources that do not reach their target state.

## What is a Deviation?

A **deviation** occurs when at least one resource of a service does not reach its **target state** after the service is enabled. When you [enable a service](/data-flows/services/managing/enabling), its resources are expected to transition from disabled to enabled (or to another state defined in the service commissioning file). The service commissioning file specifies all resources and the states they must reach for the service to function correctly.

If issues such as hardware faults, network outages, or misconfiguration prevent resources from reaching those states, the service is marked as **deviated**. A single out-of-state resource is enough for the entire service to be considered deviated.

## Where to See Deviations in the Admin UI

You can find services whose actual states differ from their expected states in several places:

* **Deviations notification:** When a deviation occurs, a pop-up appears in the Admin UI. Click the down arrow to expand the panel and see all currently deviated services.

<figure><img src="/files/WdBGDr8d5IZfUdyuO5XP" alt="Deviation notification popup"><figcaption><p>Deviation notification</p></figcaption></figure>

<figure><img src="/files/khG8m6R2zWFw41r5a7lD" alt="Detailed view of deviated resources"><figcaption><p>Expanded Deviation notification showing state discrepancies</p></figcaption></figure>

* **Deviated Services view:** Go to **Services** > **Deviated Services** for a consolidated list of all deviated services. The overview shows **Service ID**, **Name**, **Version**, and the number of **Deviated Resources** per service.
* **Deviations tabs across the Admin UI:** Deviation status and details are also available in:
  * The [Service Overview](/data-flows/services/service-overview).
  * The [Service Details view](/data-flows/services/service-details-view) for individual services.
  * The [Resources](/data-flows/services/service-resources-view) lists of an affected service.

## Inspecting Deviated Resources

To see exactly which resources are causing a deviation:

1. Open any of the [locations](#where-to-see-deviations-in-the-admin-ui) above where deviations are shown.
2. Review the comparison between expected and actual states for each resource

<figure><img src="/files/Msu4NNUUSnhX5LamHAIA" alt="Deviations tab showing resource status"><figcaption><p>Deviations tab displaying expected vs. actual status for each deviated resource</p></figcaption></figure>

## Resolving Deviations

When addressing deviations, working through the following checklist is a good practice:

1. **Identify the root cause**
   * **Hardware:** Device powered on? Correct port/cabling? Any faults or alarms?
   * **Network:** Reachability, DNS, routing, firewall rules, required ports open.
   * **Configuration:** Credentials, certificates/keys, endpoints, topics/paths, resource parameters match the service commissioning file.
   * **Dependencies:** Upstream resources healthy (connections, adapters, brokers, PLCs, etc.).
2. **Fix the underlying issue**
   * Update configuration values that are wrong or outdated.
   * Restore connectivity or replace faulty hardware.
   * Correct dependency order or bring prerequisites online first.
3. **Verify and re-enable**
   * Re-enable the service to trigger the state transition. See [Enabling Services](/data-flows/services/managing/enabling).
   * Confirm all resources reach their target state and that the deviation indicator clears.

{% hint style="warning" %}
If a deviation persists after remediation, capture details (affected resources, error messages, recent changes) and escalate to your system administrator for further troubleshooting.
{% endhint %}


# Service Logs

Watch what your services are doing in near real time and narrow down issues with filters, search, and log export.

Service logs allow you to monitor system events, service activities, and operational data. It shows the behavior of services within the Connectware environment.

In the **Service Logs** view, you can monitor the activities of all active services. In the **Service Logs** tab of the **Service Details** view, you can see the service logs of individual services.

**Key Features**

* **Near Real-time Log Streaming**: View logs as they are generated, allowing for immediate insight into current system activities.
* **Filter**: Easily narrow down log entries based on various criteria such as service name, log level, or time range.
* **Log Level Differentiation**: Quickly identify the severity and importance of log entries through color-coded log levels (e.g., INFO, WARN, ERROR).
* **Detailed Log Entries**: Access comprehensive information for each log entry, including timestamp, process ID, hostname, and message content.

## Benefits of Service Logs

* **Troubleshooting**: Quickly identify and diagnose issues by tracing service activities and error messages.
* **Performance Monitoring**: Track service performance and resource utilization over time.
* **Security Auditing**: Review logs for any suspicious activities or unauthorized access attempts.
* **Compliance**: Maintain detailed records of system activities for regulatory compliance purposes.
* **Operational Insights**: Gain a deeper understanding of how your services operate and interact within Connectware.

## Best Practices

* Regularly review logs to stay proactive in system management.
* Set up log rotation to manage storage efficiently.
* Use filtered views to focus on specific services or issues.
* Leverage the Log Details dialog for in-depth analysis of critical events.
* Consider integrating log data with external analysis tools for advanced insights.


# Logs of Individual Services

Monitor, filter, search, and export the log messages of an individual service in the Service Logs tab of the Service Details view.

Service log messages of individual services provide a detailed view of individual service activities for effective monitoring and troubleshooting. You can filter, search, and export log data in the **Service Logs** tab of the **Service Details** view. By accessing these service logs, you can:

* Track important events
* Ensure optimal service performance
* Identify and diagnose issues for troubleshooting

## Service Logs Tab (Service Details View)

You can view detailed log messages for each service in the **Service Logs** tab of the **Service Details** view.

* To open the **Service Logs** tab of a service, click **Services**, click the service for which you want to check the service logs and click **Service Logs**.

<figure><img src="/files/IcGFyBpdPdXFtDv8yZLD" alt=""><figcaption></figcaption></figure>

**Download CSV**

* Export the visible log entries as a CSV file.

{% hint style="info" %}
The service log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the raw logs that contain the full logs, see [Logs of All Services](/data-flows/services/service-logs/service-logs-of-all-services)
{% endhint %}

**Refresh Logs**

* Refresh the service logs messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view service log messages.

**Search**

* Find specific service log messages by keyword. The search filters the displayed service log messages, showing only matching results.

**Level**

* The type of message. For example, info or warning.

**Time**

* Shows the exact date and time when each log message was generated.

**Message**

* Displays the message of the service log. For example, **Lathe\_01: Enabled Service**.

## Log Details Dialog

The **Log Details** dialog provides in-depth information about specific log entries in the service logs.

* To open the **Log Details** dialog, click a log entry of a service.

<figure><img src="/files/LtuSEJC1GtHqBrfx6LbV" alt=""><figcaption></figcaption></figure>

When you select a log entry, this dialog displays the following fields:

**Time**

* The timestamp of the log entry in Unix milliseconds format. Example: **1728878765733**

**Pid**

* The Process ID associated with the log entry.

**Hostname**

* The name of the host or service that generated the log. Example: **service-manager**

**Class Name**

* The class or category of the log entry. Example: **Service**

**Message**

* A detailed description of the logged event. Example: **Drehmaschine\_02: Enabling Service**


# Logs of All Services

Monitor, filter, search, and export the service log messages of all services in the Service Logs view of Connectware.

Service log messages of all services provide a detailed view of all service activities for effective monitoring and troubleshooting. You can filter, search, and export log data in the **Service Logs** tab of the **Service Details** view. By accessing these service logs, you can:

* Track important events
* Ensure optimal service performance
* Identify and diagnose issues for troubleshooting

## Service Logs Tab (Services View)

You can view detailed log messages for each service in the **Service Logs** tab of the **Service Details** view.

* To open the **Service Logs** view, click **Services** and click **Service Logs**.

<figure><img src="/files/GoigIVXZUtSVQDCJQNb3" alt=""><figcaption></figcaption></figure>

**Download CSV**

* Export the visible service log entries as a CSV file. The service log entries in the CSV file are limited to the most recent 500 lines in the current view. To download the full log, click **Download Raw Logs**.

**Download Raw Logs**

* Export all service log entries as a **.log** file.

**Refresh Logs**

* Refresh the service logs messages to show the most recent entries.

**Filter**

* Use these filters to focus on specific service log message types based on your troubleshooting or monitoring needs. You can filter for **Debug**, **Error**, **Fatal**, **Info**, **Trace**, and **Warn** messages.

**Start Time/End Time**

* Select a specific start date/time and end date/time to define the period for which you want to view service log messages.

**Search**

* Find specific service log messages by keyword. The search filters the displayed service log messages, showing only matching results.

**Level**

* The type of message. For example, info or warning.

**Time**

* The exact date and time when each log message was generated.

**Service**

* The name of the service.

**Message**

* Displays the message of the service log. For example, **Lathe\_01: Enabled Service**.

## Log Details Dialog

The **Log Details** dialog provides in-depth information about specific log entries in the service logs.

* To open the **Log Details** dialog, click a log entry of a service.

<figure><img src="/files/LtuSEJC1GtHqBrfx6LbV" alt=""><figcaption></figcaption></figure>

When you select a log entry, this dialog displays the following fields:

**Time**

* The timestamp of the log entry in Unix milliseconds format. Example: **1728878765733**

**Pid**

* The Process ID associated with the log entry.

**Hostname**

* The name of the host or service that generated the log. Example: **service-manager**

**Class Name**

* The class or category of the log entry. Example: **Service**

**Message**

* A detailed description of the logged event. Example: **Drehmaschine\_02: Enabling Service**


# Shared Subscriptions

Distribute MQTT messages across a group of clients for load balancing, horizontal scaling, and fault tolerance.

The Protocol Mapper supports MQTT 5 shared subscriptions, which enables load balancing across multiple clients and horizontal scaling. When multiple clients subscribe to a topic as a shared group, the broker distributes each message to only one client within that group. You can also use [Rule Engine](/data-flows/rule-engine) context variables with shared subscriptions for advanced use cases.

{% hint style="info" %}
While shared subscriptions are a feature of MQTT5, you can also use them with MQTT 3.1.1.
{% endhint %}

{% hint style="info" %}
For more information, consult both this documentation and the official MQTT specification section on shared subscriptions in the OASIS standard: <https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250>
{% endhint %}

## Use Cases for Shared Subscriptions

Shared subscriptions enable multiple clients to efficiently share and process MQTT messages, providing key benefits for scalable and reliable systems.

Here are some key use cases for shared subscriptions:

* **Load balancing:** Shared Subscriptions enable multiple clients to share the message load for a single topic. Instead of each client receiving all messages, the broker distributes each message to one client in the group, ensuring an even distribution of messages.
* **Scalability:** Shared Subscriptions improve system scalability by allowing additional clients to be added to the group as needed. This ensures that higher message volumes can be handled without overwhelming individual clients.
* **Fault tolerance:** If a client in a shared subscription group becomes unavailable, other clients in the group continue to receive messages, increasing the overall reliability of the system.
* **Optimized resource usage:** By delivering each message to only one client within the group, Shared Subscriptions reduce bandwidth and resource consumption.
* **Simplified client management:** The MQTT broker handles load balancing and message distribution, eliminating the need for complex client-side logic to manage message loads or failover mechanisms.

## Example of a Shared Subscriptions Workflow

The diagram below shows how messages are routed when **MQTT Client 5** publishes to the `input` topic to the broker.

* **MQTT Client 1** and **MQTT Client 2** are grouped together in **Group 1**. Each message is forwarded to only one group member. In this example, **MQTT Client 1** receives messages 1 and 3, while **MQTT Client 2** receives messages 2 and 4.
* **MQTT Client 3** is the only member of **Group 2**, meaning it receives all messages published to the topic.
* **MQTT Client 4** is subscribed directly to the `input` topic without using the shared subscription feature, so it receives every message, regardless of the group distribution.

<figure><img src="/files/cDNS98O45aP3NR8i4Jiy" alt=""><figcaption></figcaption></figure>

## Behavior of Protocol-Mapper Agents

For protocol-mapper agents, all mappings from a single agent default to using the same **MQTT Connection**.

<figure><img src="/files/9zBzYmsDLCy6PYGbmCLZ" alt=""><figcaption></figcaption></figure>

From the broker’s perspective, the **MQTT Connection** is a single client subscribing to all topics and dispatching messages to the relevant mappings.

<figure><img src="/files/RuGuP4tk7izUl7M3GFWX" alt=""><figcaption></figcaption></figure>

For shared subscriptions, **MQTT Connections** are also treated as single clients. The broker dispatches messages according to the shared subscription group.

**Example**

If four messages are published on the input topic, client1 receives messages 1 and 3, and client2 receives messages 2 and 4. However, mappings such as mapping1 and mapping2 in the same group will both receive the same messages (1 and 3), even though they share the same subscription group.


# Setting Up Shared Subscriptions

Configure shared subscriptions in mappings and endpoints with ready-to-use service commissioning file examples.

In Connectware, you can use shared subscriptions with mappings and endpoints. Below, we provide three service commissioning file examples that demonstrate different use cases for implementing shared subscriptions.

## Syntax of Shared Subscriptions

The syntax for shared subscriptions follows this pattern:

{% code lineNumbers="true" %}

```yaml
$share/group_name/topic
```

{% endcode %}

| Parameter    | Description                                                                                                                                                         | Required |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `$share`     | A fixed prefix that designates a shared subscription.                                                                                                               | Yes      |
| `group_name` | An identifier for the group of clients that will share the message load. All clients using the same group name will be part of the same message distribution group. | Yes      |
| `topic`      | The actual topic pattern to subscribe to. Can include wildcards and multi-level topics according to standard MQTT topic rules.                                      | Yes      |

**Example**

{% code lineNumbers="true" %}

```yaml
$share/processing_group/sensors/data
```

{% endcode %}

In this example:

* All clients subscribing with this pattern will be part of the `processing_group`
* Messages published to `sensors/data` will be distributed among these clients
* Each message will be delivered to exactly one client in the group, preventing duplicate processing

## Shared Subscriptions Examples

### Basic Example with One Agent

This example allows you to test if shared subscriptions work correctly by forwarding messages published to the `input` topic to the mapping subscribed to `$share/group1/input`.

1. Install an agent. See [Installing Agents](/data-flows/agents/installing-agents).
2. Register the agent in Connectware. See [Registering Agents in Connectware](/data-flows/agents/registering-agents-in-connectware).
3. Apply the service to the agent. See [Installing Services](/data-flows/services/managing/installing).
4. Enable the services. See [Enabling Services](/data-flows/services/managing/enabling).
5. Publish a message to the `input` topic.

**Result:** The agent will publish to the topic `output`.

{% code lineNumbers="true" %}

```yaml
description: |
  Simple Mapping with Shared Subscription

metadata:
  name: Simple Shared Subscription

resources:
  sharedSubscriptionMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            topic: $share/group1/input
          publish:
            topic: output
          rules:
            - transform:
                expression: |
                  {
                    "msg": $
                  }
```

{% endcode %}

### Advanced Example with Two Agents (Load Balancing)

This example allows you to test the load-balancing capability of shared subscriptions using two agents.

1. Install two agents named **agent01** and **agent02**. See [Installing Agents](/data-flows/agents/installing-agents).
2. Register the agents in Connectware. See [Registering Agents](/data-flows/agents/registering-agents-in-connectware).
3. Apply the same service to both agents (rename one for differentiation). See [Installing Services](/data-flows/services/managing/installing).
4. Enable the services. See [Enabling Services](/data-flows/services/managing/enabling).
5. Publish a message to the `input` topic.

**Result:** Either **agent01** or **agent02** will publish to the `output` topic, but only one will act at a time. This ensures load balancing between the agents.

{% code lineNumbers="true" %}

```yaml
description: |
  Shared Subscription Test

metadata:
  name: Shared Subscription Test

parameters:
  agentName:
    description: Choose Agent
    type: string
    enum: ['agent01', 'agent02']

resources:
  sharedSubscriptionMapping:
    type: Cybus::Mapping
    properties:
      agentName: !ref agentName
      mappings:
        - subscribe:
            topic: $share/group1/input
          publish:
            topic: output
          rules:
            - transform:
                expression: !sub |
                  (
                    $merge([$, {"agent": "${agentName}"}]);
                  )
```

{% endcode %}

### Advanced Example with Multiple Agents (Wildcard Mappings)

In this example, a shared subscription is deployed across multiple agents. This example sets up a `qa` group where agents subscribe to the `service/#` topic wildcard, allowing them to handle messages on all subtopics. This setup is particularly useful for load testing, where tens of thousands of messages per second are processed from sources like OPC UA. The agents then publish these messages to the `northbound/opcua/$nodes` topic.

The wildcards `#nodes` and `$nodes` represent a named wildcard that maps the topic tree under services (e.g., service/a/bc, service/x/y/z/...) to the northbound path (e.g., northbound/opcua/a/bc).

The dedicated `connection` specified in the subscribe property ensures that each agent creates a new MQTT client instead of sharing a single MqttConnection.

{% code lineNumbers="true" %}

```yaml
---
description: |
  Wildcard Mapping with Shared Subscription

metadata:
  name: Wildcard Mapping Shared Subscription
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  agentName:
    type: string
    default: protocol-mapper

  mqttBroker:
    type: string
    default: broker.example.com

  mqttUser:
    type: string
    default: admin

  mqttPassword:
    type: string
    default: admin

resources:
  mqttConnection:
    type: Cybus::Connection
    properties:
      agentName: !ref agentName
      protocol: Mqtt
      targetState: connected
      connection:
        host: !ref mqttBroker
        username: !ref mqttUser
        password: !ref mqttPassword

  wildcardMappingSharedSubscription:
    type: Cybus::Mapping
    properties:
      agentName: !ref agentName
      mappings:
        - subscribe:
            topic: $share/qa/services/#nodes
            connection: !ref mqttConnection
          publish:
            topic: northbound/opcua/$nodes
```

{% endcode %}


# Service Commissioning Files

Learn the structure of service commissioning files, the YAML blueprints that define each service in Connectware.

Service commissioning files are the foundation for defining and implementing services in Connectware. These files use YAML format to describe all the resources, configurations, and relationships that make up a [service](/data-flows/services).

A service commissioning file serves as a blueprint for a service, detailing:

1. The resources required by the service (e.g., users, connections, containers)
2. Configuration parameters for each resource
3. Relationships and dependencies between resources

When you enable a service in Connectware, the system reads the service commissioning file and automatically sets up all specified resources according to the defined parameters.

## Structure of Service Commissioning Files

Service commissioning files define how services are configured and deployed within your infrastructure. These files follow a structured format that enables you to specify all necessary components and their relationships for your service implementation.

A service commissioning file consists of several main sections that serve distinct purposes in service configuration. These include version information, service descriptions, metadata for service identification, parameters for configuration, resource definitions, and the actual resources that make up your service.

The resources section is particularly important as it contains various Cybus-specific resource types that handle different aspects of your service:

* [Connections](/data-flows/service-commissioning-files/resources/cybus-connection) establish data source and target interfaces
* [Endpoints](/data-flows/service-commissioning-files/resources/cybus-endpoint) define specific connection points
* [Mappings](/data-flows/service-commissioning-files/resources/cybus-mapping) configure data transformations
* [Containers](/data-flows/service-commissioning-files/resources/cybus-container) specify runtime environments
* [Links](/data-flows/service-commissioning-files/resources/cybus-link) establish relationships between resources
* And several other specialized resources for managing [users](/data-flows/service-commissioning-files/resources/cybus-user), [roles](/data-flows/service-commissioning-files/resources/cybus-role), [volumes](/data-flows/service-commissioning-files/resources/cybus-volume), and more

Understanding the structure and proper usage of these components is essential for creating effective and maintainable service configurations in Connectware. The following sections provide detailed information about each component and how they work together to create a complete service definition.

**Example**

Service commissioning files follow a standardized YAML structure with several distinct sections. At the core of each service commissioning file are the following components:

{% code lineNumbers="true" %}

```yaml
---
version: 'version number'

description: >
  "string"

metadata: 'service commissioning file metadata'

parameters: 'set of parameters'

definitions: 'set of definitions for internal use'

resources: 'set of resources'
```

{% endcode %}

Each section serves a specific purpose in defining your service configuration:

* The `version` field specifies the service commissioning file format version
* The `description` section provides details about the service's purpose and functionality
* `metadata` contains identification and classification information
* `parameters` defines configurable values used throughout the service
* `definitions` holds reusable elements for internal reference
* The `resources` section defines the actual service elements and their configurations

The following chapters will explain each section in detail.

## Service Commissioning Files Requirements

### Payload Size

Connectware uses NATS with `max_payload` set to 32 MB. This is the maximum payload size allowed by NATS.


# Version

Declare a version number for your service commissioning file to keep track of template revisions.

The version section allows you to add a version number to the service commissioning file.

```yaml
---
version: 'version number'
```


# Description

Summarize the purpose of your service in the required description section of the service commissioning file.

The description section (required) allows to include comments about the template. The description must follow the [version](/data-flows/service-commissioning-files/version) section.

The value for the description declaration must be a literal string that is between 0 and 1024 bytes in length. The following snippet is an example of a description declaration:

{% code lineNumbers="true" %}

```yaml
description: >
  Here are some
  details about
  the template.
```

{% endcode %}


# Metadata

Specify structured information about your service, such as its name, icon, provider, and version, in the metadata section.

The metadata section allows you to specify further information about your service in a structured way.

## Metadata Properties

| Property              | Type     | Required     |
| --------------------- | -------- | ------------ |
| [name](#name)         | `string` | **Required** |
| [homepage](#homepage) | `string` | Optional     |
| [icon](#icon)         | `string` | Optional     |
| [provider](#provider) | `string` | Optional     |
| [version](#version)   | `string` | Optional     |

### name

A short title typically used in UI representation.

It is allowed to use [parameter substitutions](/data-flows/service-commissioning-files/parameters) in this property, for example setting it to `!sub 'Machine ${machineNum}'` if there exists a parameter `machineNum`.

The auto-generated default [Service ID](/data-flows/services/serviceid) will be generated from this string by removing all characters that are not allowed for the Service ID. For backward-compatibility reasons, in Connectware version 1.0.x all characters are changed to lowercase and also all punctuation is removed, including underscore and period.

* **Required**
* Type: `string`
  * maximum length: 80 characters

### homepage

URL to the homepage of the provider

* **Optional**
* Type: `string`
* Format: `uri` – Uniform Resource Identifier (according to [RFC3986](http://tools.ietf.org/html/rfc3986))

### icon

A link to an icon image typically used in UI representation

* **Optional**
* Type: `string`

### provider

The provider/author of the this service commissioning file

* **Optional**
* Type: `string`

### version

Semantic version of the service. The version identifies the capabilities of the service commissioning file. The latest version is 1 and is the only valid value.

{% code lineNumbers="true" %}

```yaml
version: 1
```

{% endcode %}

* **Optional**
* Type: `string`

## Example

{% code lineNumbers="true" %}

```yaml
metadata:
  name: Simulated Machining Center
  icon: http://www.axon-mcs.de/wp-content/uploads/2016/08/Litz-LU620.jpg
  provider: cybus
  homepage: https://www.cybus.io
```

{% endcode %}


# Parameters

Customize services for different use cases with parameters that users set or confirm when installing or reconfiguring a service.

The parameters section is an optional component of service commissioning files that enables service customization for different use cases. When installing or reconfiguring a service, users will be prompted to either input custom values for these parameters or confirm their default values.

## Using Parameter Values

Parameter values can be utilized within the service commissioning file by reference (`!ref`) or by string substitution (`!sub`).

### Reference Method (`!ref`)

Use the reference method to directly insert a parameter's value at a specific property location. The syntax consists of `!ref` followed by the parameter name.

**Example**

{% code lineNumbers="true" %}

```yaml
!ref Cybus::MqttHost
```

{% endcode %}

### String Substitution Method (`!sub`)

Use string substitution to replace the parameter name inside the a string by the parameter’s value. The resulting string with the substituted value will be used at the specified property location. The syntax uses `!sub` followed by a string containing the parameter name enclosed in `${...}`.

**Example**

{% code lineNumbers="true" %}

```yaml
!sub 'Connected to ${hostname}'
```

{% endcode %}

{% hint style="warning" %}
Parameters can only be used in their complete, unmodified form. This limitation applies to all data types, including arrays. For example, when working with array-type parameters, you can only reference or substitute the entire array—individual element access is not supported.
{% endhint %}

## Parameter Properties

The parameters section of a service commissioning file allows you to define configurable values using specific properties for each parameter. These properties follow the JSON Schema specification, which provides a robust framework for defining and validating parameter data types and constraints.

For a comprehensive reference of the JSON Schema specification used in parameter definitions, refer to the ajv library documentation at: <https://ajv.js.org/json-schema.html#json-data-type>

The following properties can be specified for each parameter:

### Core Properties

#### type

**Required**. The data type for the parameter (DataType), specified by one of the following strings.

* `string`: Text values (e.g. "MyUserName"). See also [String-Specific Properties](#string-specific-properties).
* `number`: Decimal or integer values. See also [Number-Specific Properties](#number-specific-properties).
* `integer`: Whole numbers only. See also [Number-Specific Properties](#number-specific-properties).
* `boolean`: true/false values. When referenced with `!ref` within service commissioning files, it will evaluate to true/false.
* `array`: A JSON array of literal values, which in turn can be either strings or numbers. Requires the `items:` property as described in [Array-Specific Properties](#array-specific-properties). Note: When substituting such a parameter using `!sub` inside the file, only the full value can be substituted. No element addressing or similar is possible inside the service commissioning file.

**Example:** A parameter with type: array could receive the following value: `[test,dev,prod]`. When substituting this into e.g. [JSONata expressions](/data-flows/rule-engine/data-processing-rules#expression) of the Rule Engine, the value will evaluate to `["test","dev","prod"]` which can then be processed in JSONata accordingly.

#### default

Optional. A value of the appropriate type for the parameter to use if no value is specified when the service is installed. If additional constraints have been defined as explained below, this default value must adhere to those constraints.

#### description

Optional. A string of up to 4000 characters that describes the parameter. This is shown in the configuration dialog window when installing a service in the admin UI.

#### enum

Optional. An array containing the list of values allowed for the parameter. If a value different from all array elements has been specified for this parameter, it will be invalid, and the resulting error message will list the allowed values as given in this property as `allowedValues: [...]`

### String-Specific Properties

#### minLength

Optional, and only active for string values: An integer value that specifies the minimum number of characters which the value must have.

#### maxLength

Optional, and only active for string values: An integer value that specifies the maximum number of characters which the value must have.

#### pattern

Optional, and only active for string values: A regular expression pattern which the value must match, otherwise the value is invalid.

#### format

Optional, and only active for string values: Specifies one of several fixed string formats which the parameter value must fulfill. Currently available formats are: `date, date-time, uri, email, hostname, ipv4, ipv6, regex`. For more information, see <https://ajv.js.org/json-schema.html#format>

### Number-Specific Properties

#### minimum

Optional, and only active for number values: The minimum allowed value for the data to be valid.

#### maximum

Optional, and only active for number values: The maximum allowed value for the data to be valid.

### Array-Specific Properties

#### items

**Required**. An object, or an array of objects, describing the types of the array’s items. To define an array of strings, write `items: { type: string }`

#### minItems

Optional. The value should be a number defining the minimum number of items in the array. Only applicable if `items` is an object and not an array, i.e. all array elements have the same type.

#### maxItems

Optional. The value should be a number defining the maximum number of items in the array. Only applicable if `items` is an object and not an array, i.e. all array elements have the same type.

#### uniqueItems

Optional. If the value is `true`, the array should have unique items only to be valid.

## Example

{% code lineNumbers="true" %}

```yaml
parameters:
  modbusPort:
    type: integer
    default: 10922
    description: The modbus port number

  someString:
    type: string
    description: This should be a string to be used somewhere else in the service

  hostname:
    type: string
    format: hostname
    description: The hostname for the xy connection

  hostname_array:
    description: List of hostnames or IP addresses
    type: array
    items: { type: string }
    default: ['123.123.123.123:4567', '124.124.124.124:5678']

  mixedArray:
    type: array
    items: [{ type: 'integer' }, { type: 'string' }]
    default: [1, 'abc']

  anotherArray:
    type: array
    items: { type: 'number' }
    minItems: 2
    maxItems: 4
    uniqueItems: true
```

{% endcode %}

## Global Pre-Defined Parameters

In addition to the parameters defined in the parameters section of the service commissioning file, the following global parameters are always pre-defined by Connectware and can be used everywhere:

#### Cybus::ServiceId

This is the [ServiceID](/data-flows/services/serviceid) that uniquely identifies the currently running service, as defined by the user when [installing](/data-flows/services/managing/installing) and configuring the service

#### Cybus::MqttHost

Hostname of Connectware’s internal MQTT broker.

#### Cybus::MqttPort

Hostname of Connectware’s internal MQTT broker.

#### Cybus::MqttUser

Valid username for Connectware’s internal MQTT broker (auto-generated).

#### Cybus::MqttPassword

Valid password for Connectware’s internal MQTT broker (auto-generated).

#### Cybus::MqttRoot

Topic prefix for all MQTT topics within this service instance. This global parameter by default has the value `services/<serviceId>` where `<serviceId>` is replaced with the actual ServiceID of the current service, as specified by the user during [installing a service](/data-flows/services/managing/installing).

The default Cybus::MqttRoot can be overridden by defining the `CYBUS_MQTT_ROOT` variable in the [definitions](/data-flows/service-commissioning-files/definitions) section of the service commissioning file. See below for an explanation of when this override may be needed. In the general case it is not recommended to override the default, because the auto-generated topic prefix helps keeping the services isolated from each other.

## Resource Isolation and Namespacing

Connectware implements resource isolation between services through a systematic namespacing approach. This ensures that resources from different services remain protected and separated from each other.

The namespacing principle automatically applies unique prefixes to all resource identifiers that could potentially conflict across services. This isolation extends to multiple aspects including:

* Generated URLs
* Persistent storage
* MQTT communication topics
* Docker container names

### MQTT Namespacing

For MQTT communication, Connectware automatically prepends all service-specific topics with a unique prefix based on the service instance. This prefix is available within the service commissioning file through the global parameter `Cybus::MqttRoot`.

### Custom Prefix Configuration

While automatic namespacing works well for most cases, some applications may require custom prefix configurations. This typically occurs when working with Docker containers that have fixed MQTT topic requirements that cannot be easily configured through environment variables.

In such cases, you can manually define the `Cybus::MqttRoot` prefix by setting the `CYBUS_MQTT_ROOT` variable in the service commissioning file's definitions section:

{% code lineNumbers="true" %}

```yaml
definitions:
  CYBUS_MQTT_ROOT: 'your/custom/prefix'
```

{% endcode %}

{% hint style="warning" %}
When manually setting the MQTT root prefix:

* You become responsible for preventing naming collisions between service instances
* Ensure your prefix choice doesn't conflict with other services running on the same Connectware installation
* Consider this approach only when automatic namespacing cannot meet your application's requirements

This manual configuration should be used sparingly, as the automatic namespacing feature provides built-in protection against resource conflicts.
{% endhint %}


# Definitions

Define reusable value blocks in a service commissioning file and reference them with the !ref or !merge functions.

Definitions allow you to reference blocks from within a service commissioning file. While they share similarities with parameters, definitions are designed for internal use only.

You can define values of any data type, including object types. These values can be referenced using the `!ref` or `!merge` functions.

## Example

In this example, we create a definition for default Modbus endpoint settings that we want to reference.

{% code lineNumbers="true" %}

```yaml
modbusEndpointDefaults:
  connectionId: !ref modbusConnection
  operation: subscribe
  interval: 1000
  address:
    fc: 3
    length: 2
```

{% endcode %}

When you reference this definition using `!ref modbusEndpointDefaults`, you get the following value:

{% code lineNumbers="true" %}

```yaml
connectionId: !ref modbusConnection
  operation: subscribe
  interval: 1000
  address:
    fc: 3
    length: 2
```

{% endcode %}




---

[Next Page](/llms-full.txt/1)

