Skip to content
⚠️
You are viewing the documentation for Rhize v4.5.1. View the latest.

Agent configuration

Configure the libre-agent service through its Helm chart.

The chart’s rhizeAgentConfig value holds the application configuration, and the other chart values control the deployment, including environment variables that override individual settings.

Application configuration

Everything in this section goes into the chart’s rhizeAgentConfig value, which becomes libre-agent’s entire configuration file.

The chart ships a populated rhizeAgentConfig with defaults. If you delete a key, most take no value. Some revert to a built-in value meant for a developer’s own machine: -libreDataStoreGraphQl.serverUrl becomeshttp://localhost:8080/graphql

  • oidc.serverUrl becomes http://localhost:8090,
  • nats.serverUrl becomes nats://localhost:4222,
  • datasource.id becomes server.

To override individual keys, use the environment variable supplied through the chart’s envVars or additionalSecrets.

Many of the following sections are required for only some deployments. There are three ways to set libre-agent up:

  • Run a subscription: watches a source system and publishes every value change it sees. This source is configured by the datasource.id value on the BAAS data source record.
  • Answer commands: answers a caller’s request to read a tag, write a value, or call a method on a device.
  • Bridge: carries messages from one broker to another.

A subscription and commands can run in the same deployment, and most deployments run both. However, a bridge cannot run with a subscription or command.

General settings

ValueDescription
datasource.id
[Required]
  • ID of the data source record in BAAS that drives this deployment. Everything libre-agent subscribes to and publishes is read from that record, so a value matching no record in BAAS leaves libre-agent running but idle. Also used to build the OPC UA session name.
  • Environment variable: RHIZE_AGENT_DATASOURCE_ID
  • Default: libre-agent
  • Example: DS_0806
  • Type: string
libreDataStoreGraphQl.serverUrl
[Required]
  • GraphQL endpoint libre-agent fetches the data source record from. Give the full address of the BAAS alpha Service, including the port and the /graphql path, since the path is not added for you. Startup fails with Unable to get initial config`` if this endpoint is unreachable.</li><li>Environment variable: RHIZE_AGENT_LIBREDATASTOREGRAPHQL_SERVERURL</li><li>Default: http://baas-alpha:8080/graphql</li><li>Example: http://baas-alpha:8080/graphql`
  • Type: string
libreDataStoreGraphQl.caFile
  • Path to a PEM CA certificate libre-agent trusts in addition to the system roots when making outbound HTTPS calls to BAAS and to the OIDC provider. Set it to the path the certificate is mounted at, which is /certs/ca-cert.pem for a certificate supplied through the chart’s caFile value. A path that cannot be read or parsed stops the calls that need it.
  • Environment variable: RHIZE_AGENT_LIBREDATASTOREGRAPHQL_CAFILE
  • Example: /certs/ca-cert.pem
  • Type: string
logging.level
  • Lowest severity that reaches the log, one of trace, debug, info, warn, error, fatal, panic, or disabled. Each level lets through itself and everything more severe, so info keeps informational messages, warnings, and errors but drops trace and debug, and disabled stops libre-agent logging at all. Setting trace or debug also logs the full configuration libre-agent is running with at startup, which is the quickest way to check that a value you set actually reached libre-agent.
  • Environment variable: RHIZE_AGENT_LOGGING_LEVEL
  • Default: info
  • Example: info
  • Type: string
logging.type
  • Output format. json writes structured JSON to stderr, for collection by a log aggregator. multi writes human-readable lines to stderr and JSON to stdout at the same time. console writes human-readable lines to stderr.
  • Environment variable: RHIZE_AGENT_LOGGING_TYPE
  • Default: console
  • Example: json
  • Type: string
openTelemetry.serverUrl
  • OTLP gRPC endpoint for trace export, given as host and port with no scheme. Failure to initialise is logged as a warning and libre-agent continues without tracing.
  • Environment variable: RHIZE_AGENT_OPENTELEMETRY_SERVERURL
  • Default: otel:4317
  • Example: tempo-distributor.monitoring.svc.cluster.local:4317
  • Type: string

oidc

ValueDescription
oidc.serverUrl
[Required]
  • Base URL of the OIDC provider. Endpoints are discovered from <SERVER_URL>/.well-known/openid-configuration.
  • Environment variable: RHIZE_AGENT_OIDC_SERVERURL
  • Default: http://keycloak:80
  • Example: http://keycloak:80
  • Type: string
oidc.realm
[Required when oidc.enableGenericOidc is false]
  • Keycloak realm.
  • Environment variable: RHIZE_AGENT_OIDC_REALM
  • Default: libre
  • Example: libre
  • Type: string
oidc.clientId
[Required]
  • Client ID. Tokens are obtained with the client credentials grant, so the client’s service account needs the required roles in the provider.
  • Environment variable: RHIZE_AGENT_OIDC_CLIENTID
  • Default: libreAgent
  • Example: libreAgent
  • Type: string
oidc.clientSecret
[Required]
  • Client secret paired with oidc.clientId. Supply from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_OIDC_CLIENTSECRET
  • Example: 8f3b6c21-4d5e-4a7b-9c0d-1e2f3a4b5c6d
  • Type: string
oidc.enableGenericOidc
  • Switches to a generic OIDC provider, such as Okta, rather than Keycloak-specific handling.
  • Environment variable: RHIZE_AGENT_OIDC_ENABLEGENERICOIDC
  • Default: false
  • Example: false
  • Type: boolean
oidc.customAudienceKey
  • Claim to read the audience from when using a non-Keycloak provider.
  • Environment variable: RHIZE_AGENT_OIDC_CUSTOMAUDIENCEKEY
  • Example: rhize.com/aud
  • Type: string
oidc.credentialsScope
  • Optional scope requested during the client credentials grant.
  • Environment variable: RHIZE_AGENT_OIDC_CREDENTIALSSCOPE
  • Example: openid
  • Type: string

Commands

Alongside the subscription, libre-agent answers individual commands:

  • Read a tag now.
  • Write a value to a tag or topic on the data source.
  • Call a method on a device.

When restate.enabled is on, which is the chart’s default, the command API is served through Restate, and these settings describe how it is reached. An answer returns to the caller the same way it came rather than through an egress handler.

Which commands can be answered depends on the type of data source.

  • An OPC UA data source answers all three. The libre-agent will not start without restate.enabled, stopping with At least one of NATS or Kafka or Restate must be enabled for OPCUA data source.
  • An MQTT data source answers writes only, and requires restate.enabled to be true: if false, libre-agent runs but accepts no commands at all.
  • A Kafka, Azure Service Bus, or Azure Event Hubs data source answers no commands. These need restate.enabled to be false. If true, libre-agent still tries to register with Restate at startup and exits if it cannot.
ValueDescription
restate.enabled
[Required when the data source is Kafka, Azure Service Bus, or Azure Event Hubs]
  • Makes libre-agent serve read, write, and method call commands over HTTP on the port the chart’s service.port sets and register itself with Restate at startup, after which a caller reaches libre-agent by invoking it through Restate rather than by sending to it directly. Registration is a single attempt: libre-agent exits if it fails, so turn this off for a data source that answers no commands.
  • Environment variable: RHIZE_AGENT_RESTATE_ENABLED
  • Default: true
  • Example: true
  • Type: boolean
restate.adminUrl
[Required when restate.enabled is true]
  • Restate admin API libre-agent registers itself with.
  • Environment variable: RHIZE_AGENT_RESTATE_ADMINURL
  • Default: http://restate:9070
  • Example: http://restate:9070
  • Type: string
restate.serviceName
  • Hostname Restate calls back on. Derived from the pod hostname.
  • Environment variable: RHIZE_AGENT_RESTATE_SERVICENAME
  • Default: the Deployment name
  • Example: libre-agent
  • Type: string

Data sources

How libre-agent connects to the system it reads from. Fill in the one section that matches the data source record in BAAS — kafka, opcUa, mqtt, azure for Azure Service Bus, or eventHubs — and leave the others out. health applies only to an OPC UA server.

kafka

How libre-agent connects to the Kafka broker supplying the data.

ValueDescription
kafka.bootstrapServerUrl
[Required when the data source is Kafka]
  • Kafka bootstrap server.
  • Environment variable: RHIZE_AGENT_KAFKA_BOOTSTRAPSERVERURL
  • Example: redpanda:9092
  • Type: string
kafka.groupId
[Required when the data source is Kafka]
  • Name of the Kafka consumer group libre-agent reads under. Every replica reads under this group, so the topics are split between them and each message is read once rather than once per replica. The group also remembers how far it has read, so a restart continues from the last read. A group ID that has not been used before starts at the oldest message the topic still holds.
  • Environment variable: RHIZE_AGENT_KAFKA_GROUPID
  • Example: libre-agent
  • Type: string
kafka.workerThreads
  • Number of worker threads reading from the broker in parallel.
  • Environment variable: RHIZE_AGENT_KAFKA_WORKERTHREADS
  • Default: 1
  • Example: 1
  • Type: integer
kafka.sessionTimeout
  • Consumer session timeout in milliseconds.
  • Environment variable: RHIZE_AGENT_KAFKA_SESSIONTIMEOUT
  • Default: 60000
  • Example: 30000
  • Type: integer
kafka.maxSendRetries
  • Retries for a failed send.
  • Environment variable: RHIZE_AGENT_KAFKA_MAXSENDRETRIES
  • Default: 3
  • Example: 3
  • Type: integer

opcUa

How libre-agent connects to the OPC UA server supplying the data. Relevant only when the data source is an OPC UA server.

ValueDescription
opcUa.serverUrl
[Required when the data source is OPC UA]
  • OPC UA endpoint to connect to.
  • Environment variable: RHIZE_AGENT_OPCUA_SERVERURL
  • Default: opc.tcp://opcua-server
  • Example: opc.tcp://opcua-server:4840
  • Type: string
opcUa.discoveryUrl
[Required when the data source is OPC UA]
  • OPC UA discovery endpoint, usually the same as serverUrl.
  • Environment variable: RHIZE_AGENT_OPCUA_DISCOVERYURL
  • Default: opc.tcp://opcua-server
  • Example: opc.tcp://opcua-server:4840
  • Type: string
opcUa.authentication
  • How libre-agent identifies itself to the server. Anonymous presents no identity and ignores opcUa.username and opcUa.password. UserName signs in with that pair. Certificate presents the client certificate from opcUa.certFile and proves ownership with opcUa.keyFile. The server has to offer the chosen method on the endpoint it selects.
  • Environment variable: RHIZE_AGENT_OPCUA_AUTHENTICATION
  • Default: Anonymous
  • Example: UserName
  • Type: string
opcUa.username
[Required when opcUa.authentication is UserName]
  • OPC UA username.
  • Environment variable: RHIZE_AGENT_OPCUA_USERNAME
  • Example: opcuauser
  • Type: string
opcUa.password
[Required when opcUa.authentication is UserName]
  • OPC UA password. Supply from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_OPCUA_PASSWORD
  • Example: ExamplePassword123
  • Type: string
opcUa.mode
  • What protection is applied to each message. None sends them unsigned and in the clear. Sign signs them, so tampering is detectable while the contents stay readable on the wire. SignAndEncrypt signs and encrypts them. Auto takes the strongest mode the server advertises. Any other value logs “Invalid security Mode”, matches no endpoint, and leaves libre-agent unable to connect.
  • Environment variable: RHIZE_AGENT_OPCUA_MODE
  • Default: Auto
  • Example: SignAndEncrypt
  • Type: string
opcUa.policy
  • Cryptographic suite used for the signing and encryption opcUa.mode asks for, from the list under this table. Setting either this or opcUa.mode to None forces both to None, so security is off unless both carry a real value. Any other value stops libre-agent with “Invalid security Policy”.
  • Environment variable: RHIZE_AGENT_OPCUA_POLICY
  • Default: None
  • Example: Basic256Sha256
  • Type: string
opcUa.applicationUri
  • Application URI libre-agent presents. Must match the URI in the client certificate when a security policy is in use.
  • Environment variable: RHIZE_AGENT_OPCUA_APPLICATIONURI
  • Default: urn:opcua-server.server.application
  • Example: urn:opcua-server.server.application
  • Type: string
opcUa.certFile / opcUa.keyFile
[Required when opcUa.mode is Sign or SignAndEncrypt, opcUa.authentication is Certificate, or opcUa.genCert is true]
  • Paths inside the container to the client certificate and its private key, which has to be RSA. Both have to be set for either to be read. Mount the pair with extraVolumes and extraVolumeMounts, and register the certificate with the OPC UA server as a trusted client. A pair that fails to load logs Failed to load certificate and the connection goes on without a certificate, which the server then refuses.
  • Environment variable: RHIZE_AGENT_OPCUA_CERTFILE / RHIZE_AGENT_OPCUA_KEYFILE
  • Example: /certs/opcua-client.pem / /certs/opcua-client.key
  • Type: string
opcUa.genCert
  • Generates a self-signed 2048-bit certificate for opcUa.applicationUri at startup and writes it to opcUa.certFile and opcUa.keyFile, so both need to name writable paths; left empty, the certificate is written to cert.pem and key.pem and then not found, which logs Failed to load certificate. A new certificate is generated on every start, even when the files already exist, so a server that trusted the last one rejects the next.
  • Environment variable: RHIZE_AGENT_OPCUA_GENCERT
  • Default: false
  • Example: false
  • Type: boolean
opcUa.subscription.publishingInterval
  • How often, in milliseconds, the server publishes notifications.
  • Environment variable: RHIZE_AGENT_OPCUA_SUBSCRIPTION_PUBLISHINGINTERVAL
  • Default: 1000
  • Example: 1000
  • Type: integer
opcUa.subscription.lifetimeCount
  • Publishing cycles the server keeps the subscription alive without a publish request. Should be at least three times maxKeepAliveCount.
  • Environment variable: RHIZE_AGENT_OPCUA_SUBSCRIPTION_LIFETIMECOUNT
  • Default: 10000
  • Example: 10000
  • Type: integer
opcUa.subscription.maxKeepAliveCount
  • Publishing cycles without data before the server sends a keep-alive.
  • Environment variable: RHIZE_AGENT_OPCUA_SUBSCRIPTION_MAXKEEPALIVECOUNT
  • Default: 3000
  • Example: 3000
  • Type: integer
opcUa.subscription.maxNotificationsPerPublish
  • The maximum notifications in a single publish response.
  • Environment variable: RHIZE_AGENT_OPCUA_SUBSCRIPTION_MAXNOTIFICATIONSPERPUBLISH
  • Default: 10000
  • Example: 10000
  • Type: integer
opcUa.subscription.priority
  • Relative priority of this subscription on the server.
  • Environment variable: RHIZE_AGENT_OPCUA_SUBSCRIPTION_PRIORITY
  • Default: 0
  • Example: 0
  • Type: integer
opcUa.monitoredItem.samplingInterval
  • How often, in milliseconds, the server samples each item. 0 means as fast as the server allows.
  • Environment variable: RHIZE_AGENT_OPCUA_MONITOREDITEM_SAMPLINGINTERVAL
  • Default: 0
  • Example: 0
  • Type: integer
opcUa.monitoredItem.queueSize
  • Server-side queue depth per monitored item between publications. If samples are being lost between publishes, raise the queue size.
  • Environment variable: RHIZE_AGENT_OPCUA_MONITOREDITEM_QUEUESIZE
  • Default: 100
  • Example: 100
  • Type: integer
opcUa.monitoredItem.discardOldest
  • Whether a full queue discards the oldest sample rather than the newest.
  • Environment variable: RHIZE_AGENT_OPCUA_MONITOREDITEM_DISCARDOLDEST
  • Default: true
  • Example: true
  • Type: boolean

The opcUa.policy value accepts the following security policies:

ValueDescription
AutoTakes the strongest policy the server advertises, leaving the choice to the server.
NoneNo signing or encryption, and it forces opcUa.mode to None as well.
Basic128Rsa15128-bit AES with SHA-1 signatures and RSA PKCS#1 v1.5 key exchange. Deprecated in OPC UA 1.04 and refused by many servers; set it only for equipment that offers nothing else.
Basic256256-bit AES with SHA-1 signatures. Deprecated on the same grounds as Basic128Rsa15.
Basic256Sha256256-bit AES with SHA-256 signatures. The policy most servers have in common, and the usual choice.
Aes128_Sha256_RsaOaep128-bit AES with SHA-256 signatures and RSA-OAEP key exchange, introduced in OPC UA 1.04.
Aes256_Sha256_RsaPss256-bit AES with SHA-256 signatures and RSA-PSS key exchange. The strongest of the set and the newest, so the least widely supported.

health

Watches the tags libre-agent has subscribed to and renews the subscription for any that stop reporting or begin returning errors. Only relevant when the data source is an OPC UA server.

ValueDescription
health.pollInterval
  • How often, in milliseconds, every subscribed tag is checked. 0 turns the watcher off, so nothing is renewed. Anything under 200 is raised to 200, which is logged as Poll interval is too low. Clamping.
  • Environment variable: RHIZE_AGENT_HEALTH_POLLINTERVAL
  • Default: 1000
  • Example: 1000
  • Type: integer
health.subscriptionTimeout
  • How long, in milliseconds, a tag may report a bad status before its subscription is renewed. Anything over 24 hours is lowered to 24 hours, logged as Node timeout is too high. Clamping.
  • Environment variable: RHIZE_AGENT_HEALTH_SUBSCRIPTIONTIMEOUT
  • Default: 60000
  • Example: 60000
  • Type: integer
health.subscriptionMaxCount
  • How many OPC UA subscriptions libre-agent opens before it stops creating more and shares the existing ones between tags. Raise it where a server limits how many monitored items one subscription may carry.
  • Environment variable: RHIZE_AGENT_HEALTH_SUBSCRIPTIONMAXCOUNT
  • Default: 5
  • Example: 5
  • Type: integer

Health is reported in two places:

  • The log carries a line per tag as it is renewed, at warn level, reading Node status is not OK. Last seen 1m2s. Renewing subscription. with the tag in a node field and the OPC UA status alongside, so a tag renewing over and over is a tag worth investigating at the server. Set logging.level to debug to also see the intervals in force at startup, or to trace to see every health update as it lands.

  • Counts come from a Prometheus endpoint each pod serves on port 6061 at /metrics. Scrape it at the pod’s own address, since the Service carries only service.port. Five values are published: opcua_handles_active, the number of monitored items currently subscribed; opcua_monitored_item_handled and opcua_messages_handled_total, counters that should keep climbing while the source is alive; and opcua_notify_channel_length with message_handler_data_channel_length, queue depths inside libre-agent that sit near zero unless it is falling behind what it is being sent.

mqtt

How libre-agent connects to the MQTT broker supplying the data. Only relevant when the data source is MQTT.

ValueDescription
mqtt.serverUrl
[Required when the data source is MQTT]
  • Broker URL.
  • Environment variable: RHIZE_AGENT_MQTT_SERVERURL
  • Default: mqtt://mqtt:1883
  • Example: mqtt://mqtt-broker:1883
  • Type: string
mqtt.version
  • Which MQTT client libre-agent connects with. 3.1.1 selects the MQTT 3.1.1 client, for brokers that do not speak MQTT 5. 5 selects the MQTT 5 client.
  • Environment variable: RHIZE_AGENT_MQTT_VERSION
  • Default: 5
  • Example: 5
  • Type: string
mqtt.clientId
  • MQTT client ID. Must be unique per broker connection; two agents sharing one will disconnect each other.
  • Environment variable: RHIZE_AGENT_MQTT_CLIENTID
  • Default: rhize-agent
  • Example: rhize-agent
  • Type: string
mqtt.username
  • Broker username. Empty means anonymous.
  • Environment variable: RHIZE_AGENT_MQTT_USERNAME
  • Example: system
  • Type: string
mqtt.password
  • Broker password. Supply from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_MQTT_PASSWORD
  • Example: ExamplePassword123
  • Type: string
mqtt.qos
  • How hard the broker works to deliver each message, chosen from the list under this table. One value covers both directions: the topics libre-agent subscribes to, and the values it publishes when answering a write. Anything outside 0, 1, and 2 fails the connection with mqtt.qos must be 0, 1, or 2.
  • Environment variable: RHIZE_AGENT_MQTT_QOS
  • Default: 0
  • Example: 1
  • Type: integer
mqtt.decomposeJson
  • On, each field in a JSON payload is published as a reading in its own right. Off, the whole payload goes out as one value, leaving whatever consumes it to pull the readings apart. Turn it on for a device that reports several readings in one message. Fields whose name starts with _ are left out.
  • Environment variable: RHIZE_AGENT_MQTT_DECOMPOSEJSON
  • Default: false
  • Example: false
  • Type: boolean
mqtt.timestampField
  • Field in the payload holding the sample timestamp.
  • Environment variable: RHIZE_AGENT_MQTT_TIMESTAMPFIELD
  • Default: timestamp
  • Example: timestamp
  • Type: string
mqtt.timestampFormat
  • Valid formats are : RFC3339, RFC3339Nano, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, ANSIC, UnixDate, RubyDate, Kitchen, Stamp, StampMilli, StampMicro, StampNano, UnixSeconds, UnixMilli, UnixMicro, or UnixNano. An unset or unrecognised format logs time format not recognized and the value is stamped with the time libre-agent received it instead.
  • Environment variable: RHIZE_AGENT_MQTT_TIMESTAMPFORMAT
  • Default: RFC3339Nano
  • Example: RFC3339Nano
  • Type: string
mqtt.requestTimeout
  • Request timeout in seconds.
  • Environment variable: RHIZE_AGENT_MQTT_REQUESTTIMEOUT
  • Default: 5
  • Example: 5
  • Type: integer

The delivery guarantees mqtt.qos accepts:

ValueDescription
0Sent once, with no acknowledgement and no retry. The cheapest and the fastest, and the level at which a message is simply gone if it does not arrive.
1Redelivered until it is acknowledged, so a message is not lost, at the price of the same message sometimes arriving more than once. Nothing downstream filters repeats, so a second delivery becomes a second value change carrying the same reading.
2Delivered exactly once, using a four-step exchange per message. The slowest of the three, so consider lowering the guarantee on a fast-moving feed.

Two things bound what raising the level buys:

  • A message is delivered at the lower of the level it was published with and the level libre-agent subscribed with, so 2 cannot improve on a device that publishes at 0.
  • And a level above 0 only covers messages that arrive while libre-agent is connected, unless the broker is holding a session for it: on 3.1.1 the session outlives a dropped connection after the first one, so the broker queues what was missed and delivers it on reconnect, while the MQTT 5 path asks for no session expiry, which ends the session with the connection and leaves nothing to queue into.

azure

Azure Service Bus credentials, used when the data source is Service Bus.

ValueDescription
azure.clientId
[Required when the data source is Azure Service Bus]
  • Azure AD application client ID.
  • Environment variable: RHIZE_AGENT_AZURE_CLIENTID
  • Example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
  • Type: string
azure.clientSecret
[Required when the data source is Azure Service Bus]
  • Azure AD client secret. Supply from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_AZURE_CLIENTSECRET
  • Example: Exa8Q~ExampleClientSecretValue1234567890
  • Type: string
azure.tenantId
[Required when the data source is Azure Service Bus]
  • Azure AD tenant ID.
  • Environment variable: RHIZE_AGENT_AZURE_TENANTID
  • Example: 2b1f8d4c-93ae-4a61-8f0b-6d5c4e3a2b1f
  • Type: string
azure.serviceBusHostName
[Required when the data source is Azure Service Bus]
  • Service Bus namespace hostname.
  • Environment variable: RHIZE_AGENT_AZURE_SERVICEBUSHOSTNAME
  • Example: example.servicebus.windows.net
  • Type: string

eventHubs

Azure Event Hubs consumer. Hub entity names come from the data source topic labels in BAAS rather than from configuration.

ValueDescription
eventHubs.namespaceConnectionString
[Required when the data source is Event Hubs and eventHubs.fullyQualifiedNamespace is empty]
  • Connection string for the Event Hubs namespace.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_NAMESPACECONNECTIONSTRING
  • Example: Endpoint=sb://example-ns.servicebus.windows.net/;SharedAccessKeyName=listen-policy;SharedAccessKey=ExampleSharedAccessKey1234567890=
  • Type: string
eventHubs.fullyQualifiedNamespace
  • Namespace hostname, used for Azure AD authentication instead of a connection string.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_FULLYQUALIFIEDNAMESPACE
  • Example: example-ns.servicebus.windows.net
  • Type: string
eventHubs.consumerGroup
  • Event Hubs consumer group.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_CONSUMERGROUP
  • Default: $Default
  • Example: agent-consumer
  • Type: string
eventHubs.checkpointStorageConnectionString
[Required when the data source is Event Hubs and eventHubs.checkpointStorageAccountUrl is empty]
  • Storage account connection string for the blob checkpoint store, authenticating with a storage account key or a SAS token.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_CHECKPOINTSTORAGECONNECTIONSTRING
  • Example: DefaultEndpointsProtocol=https;AccountName=examplestorage;AccountKey=ExampleStorageAccountKey1234567890==;EndpointSuffix=core.windows.net
  • Type: string
eventHubs.checkpointStorageAccountUrl
  • Blob service URL for the checkpoint store. When set, it takes precedence over eventHubs.checkpointStorageConnectionString, and libre-agent signs in to the storage account as an Azure AD application rather than with a key. Set the application’s tenant ID, client ID and client secret in the AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET environment variables, which are separate from the azure settings. With them unset, it uses the managed identity of the node the pod runs on. Either identity needs the Storage Blob Data Contributor role on the account.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_CHECKPOINTSTORAGEACCOUNTURL
  • Example: https://examplestorage.blob.core.windows.net
  • Type: string
eventHubs.checkpointBlobContainerName
[Required when the data source is Event Hubs]
  • Blob container holding the checkpoints.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_CHECKPOINTBLOBCONTAINERNAME
  • Example: checkpoints
  • Type: string
eventHubs.receivePartitionId
  • Restricts the consumer to a single partition. Empty means all partitions are handled by the processor.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_RECEIVEPARTITIONID
  • Example: 0
  • Type: string
eventHubs.receiveAllPartitions
  • Receives from all partitions.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_RECEIVEALLPARTITIONS
  • Default: false
  • Example: false
  • Type: boolean
eventHubs.receiveMaxBatchSize
  • Maximum events fetched per receive call. Unset or 0 means 100, and anything above 300 is rejected at startup.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_RECEIVEMAXBATCHSIZE
  • Default: 100
  • Example: 10
  • Type: integer
eventHubs.receiveStartFromEarliest
  • Starts from the earliest available event when no checkpoint exists, rather than from the latest.
  • Environment variable: RHIZE_AGENT_EVENTHUBS_RECEIVESTARTFROMEARLIEST
  • Default: false
  • Example: true
  • Type: boolean

egress

Where the subscription sends what it reads. Each handler listed receives every value change, and with no handler listed nothing is published at all, so a deployment that subscribes to anything defines at least one.

egress.handlers is a map whose keys are names you choose, so each setting is written egress.handlers.<name>.<field>. Define each handler in rhizeAgentConfig. The environment variables in the table then set that handler’s fields, provided each field is written in the handler’s block. To take a field’s value from its variable alone, write it in the block as "".

ValueDescription
egress.handlers.<name>.protocol
[Required when the handler is defined]
  • Where the handler sends messages. kafka produces to the Kafka topic named by topic, or to the topic a patterns entry picks. http POSTs each message to serverUrl. nats publishes to a NATS subject over the connection the nats section configures. Any other value logs Unknown egress protocol and the handler is skipped.
  • Environment variable: RHIZE_AGENT_EGRESS_HANDLERS_<NAME>_PROTOCOL
  • Example: kafka
  • Type: string
egress.handlers.<name>.serverUrl
[Required when the handler’s protocol is not nats]
  • Where to publish. For kafka, the broker address. For http, the URL to POST to, where a literal {id} in the URL is replaced with the message subject; the body is JSON and carries an idempotency-key header. Not used by nats, which takes its connection from the nats section instead. An empty value crashes libre-agent at startup for kafka and http.
  • Environment variable: RHIZE_AGENT_EGRESS_HANDLERS_<NAME>_SERVERURL
  • Example: kafka:9092 for Kafka, http://ingest:8080/values/{id} for HTTP
  • Type: string
egress.handlers.<name>.topic
[Required when the handler’s protocol is kafka]
  • Kafka only. Topic to publish to when no entry in patterns matches. Topics are created on demand if the broker allows it.
  • Environment variable: RHIZE_AGENT_EGRESS_HANDLERS_<NAME>_TOPIC
  • Example: value-changes
  • Type: string
egress.handlers.<name>.patterns
  • Kafka only. List of {topic, regex} pairs that route by source node name. When the regex matches the node, the message goes to that pair’s topic instead of the handler’s topic, and a $1 in that topic is replaced with the text of the first capture group, so a single pattern can give each site or line its own topic. Keep the patterns mutually exclusive: when several match, which one wins is not predictable. An entry with an empty topic, or a regex that does not compile, crashes libre-agent at startup.
  • Environment variable: None
  • Example: see the example block below
  • Type: list

A Kafka handler that splits temperatures onto their own topic, alongside an HTTP handler, as the block appears inside rhizeAgentConfig:

egress:
  handlers:
    kafka-values:
      protocol: kafka
      serverUrl: kafka:9092
      topic: value-changes
      patterns:
        - topic: temperatures
          regex: '.*Temperature$'
        - topic: 'values_$1'
          regex: '^bulktimeseries/Acme/([^/]+)/.*'
    historian:
      protocol: http
      serverUrl: http://ingest:8080/values/{id}

nats

The NATS connection an egress handler with protocol nats opens. Nothing else on this page uses it, and without such a handler none of these settings are read.

ValueDescription
nats.serverUrl
  • NATS server address. The default reaches a NATS Service named nats on its usual port in the same namespace, so it only needs setting where the server is named or ported differently. An unreachable address stops libre-agent at startup.
  • Environment variable: RHIZE_AGENT_NATS_SERVERURL
  • Default: nats:4222
  • Example: nats://nats:4222
  • Type: string
nats.username
  • NATS username.
  • Environment variable: RHIZE_AGENT_NATS_USERNAME
  • Default: system
  • Example: system
  • Type: string
nats.password
  • NATS password. Supply from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_NATS_PASSWORD
  • Default: system
  • Example: ExamplePassword123
  • Type: string

bridge

Turns libre-agent into a broker-to-broker message bridge. This is a replacement for normal operation. When a bridge section is present, libre-agent forwards messages between the brokers defined here and ignores every other section on this page, datasource included.

Each handler is one broker connection, and a message arriving on one is published to all others. Messages are never sent back to the handler they arrived on, and a message that has already been routed once is not routed again, so two handlers cannot loop.

bridge.handlers is a map whose keys are names you choose, and the name is what identifies the connection in the logs. As with egress, define each handler in rhizeAgentConfig, writing every field that its variable should set, using "" for a field whose value comes only from the variable.

ValueDescription
bridge.topics
[Required when a bridge section is present]
  • Topics to carry across the bridge, written the NATS way: a . between levels, * for any single level, and > for everything below that point. Every broker here subscribes to all of them. An MQTT broker gets the topics converted to MQTT form on the way, so libre.*.values reaches that broker as libre/+/values.
  • Environment variable: None
  • Example: [libre.>]
  • Type: list
bridge.handlers.<name>.protocol
[Required when the handler is defined]
  • Which broker the handler speaks to: nats for a NATS server, mqtt for an MQTT broker. A handler naming anything else is left out of the bridge.
  • Environment variable: RHIZE_AGENT_BRIDGE_HANDLERS_<NAME>_PROTOCOL
  • Example: mqtt
  • Type: string
bridge.handlers.<name>.serverUrl
[Required when the handler is defined]
  • Broker address, including scheme and port.
  • Environment variable: RHIZE_AGENT_BRIDGE_HANDLERS_<NAME>_SERVERURL
  • Example: mqtt://broker:1883 for MQTT, nats://nats:4222 for NATS
  • Type: string
bridge.handlers.<name>.username
  • Username for the broker. Omit for an anonymous connection.
  • Environment variable: RHIZE_AGENT_BRIDGE_HANDLERS_<NAME>_USERNAME
  • Example: bridge
  • Type: string
bridge.handlers.<name>.password
  • Password for the broker. Write it here as an empty value and supply the real one from a Kubernetes Secret.
  • Environment variable: RHIZE_AGENT_BRIDGE_HANDLERS_<NAME>_PASSWORD
  • Example: ExamplePassword123
  • Type: string
bridge.handlers.<name>.clientId
  • MQTT only. Client id for the connection. Must be unique per broker, since two connections sharing one will disconnect each other.
  • Environment variable: RHIZE_AGENT_BRIDGE_HANDLERS_<NAME>_CLIENTID
  • Example: libre-bridge
  • Type: string

A minimal two-broker bridge, as the block appears inside rhizeAgentConfig, with the NATS password left empty for additionalSecrets to fill:

bridge:
  topics:
    - libre.>
  handlers:
    plant:
      protocol: mqtt
      serverUrl: mqtt://plant-broker:1883
      clientId: libre-bridge
    central:
      protocol: nats
      serverUrl: nats://nats:4222
      username: bridge
      password: ""

Environment-only settings

These are read directly from the environment and carry no RHIZE_AGENT_ prefix.

ValueDescription
all_proxy
  • SOCKS5 proxy that libre-agent dials MQTT broker connections through, both for an MQTT data source and for MQTT connections in the bridge. Requires either a socks5:// or socks5h:// URL. An MQTT data source pinned to mqtt.version 3.1.1 connects directly, as do all other connections libre-agent makes, including NATS, Kafka, and calls to BAAS.
  • Example: socks5://proxy.example.com:1080
  • Type: string

Helm chart values

Values shared by every chart.

ValueDescription
rhizeAgentConfig
[Required]
  • The complete application configuration, rendered into a ConfigMap named after the release and mounted at /config. libre-agent exits if the file is missing.
  • Default: the block described above
  • Example: the Application configuration section
  • Type: object
envVars
  • Map of environment variable names to values passed to the container.
  • Example: see the example block below
  • Type: map
additionalSecrets
  • List of entries that each carry one value from a Kubernetes Secret into an environment variable: name is the variable the service reads, secretName is the Secret to take the value from, and secretKey is the name of the entry within that Secret. This is how every credential should reach libre-agent, using the variable names in the second column of the tables above: RHIZE_AGENT_OIDC_CLIENTSECRET for the OIDC client, and RHIZE_AGENT_OPCUA_PASSWORD, RHIZE_AGENT_MQTT_PASSWORD, or RHIZE_AGENT_NATS_PASSWORD for the data source or broker in use.
  • Example: see the example block below
  • Type: list
caFile
  • Contents of a PEM CA certificate for outbound HTTPS calls, given as a YAML block, caFile: |, with the certificate’s lines indented beneath. Trusting a certificate takes two values: give the certificate here, which mounts it at /certs/ca-cert.pem, and set libreDataStoreGraphQl.caFile in rhizeAgentConfig to that path.
  • Example: -----BEGIN CERTIFICATE-----…
  • Type: string
service.port
  • Port for the Service, the container port, and the port libre-agent serves Restate handlers on. The chart writes it into the configuration as restate.servicePort as well, so the port Restate calls back on is always the one the Service exposes.
  • Default: 8887
  • Example: 8887
  • Type: integer
extraVolumes / extraVolumeMounts
  • How an OPC UA client certificate and key get into the container, which is the one file libre-agent reads that the chart does not place itself. Mount the pair, then name the mounted paths in opcUa.certFile and opcUa.keyFile. Give each value as a list of standard Kubernetes volume and volume mount entries, and set both: a mount whose volume is missing stops the pod from starting.
  • Example: refer to following block
  • Type: list

A log level set directly, two credentials taken from Secrets, and an OPC UA certificate pair mounted from a third:

envVars:
  RHIZE_AGENT_LOGGING_LEVEL: info
additionalSecrets:
  - name: RHIZE_AGENT_OIDC_CLIENTSECRET
    secretName: libre-client-secrets
    secretKey: libreAgent
  - name: RHIZE_AGENT_MQTT_PASSWORD
    secretName: libre-passwords
    secretKey: agentMqtt
extraVolumes:
  - name: opcua-certs
    secret:
      secretName: agent-opcua-certs
extraVolumeMounts:
  - name: opcua-certs
    mountPath: /opcua-certs
    readOnly: true