> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Broker Configuration

> Complete guide to configuring the Coreflux MQTT Broker - ports, security, TLS, and deployment options

Configure your Coreflux MQTT Broker to match your deployment requirements. This guide covers network settings, security options, TLS certificates, and deployment-specific configurations.

<Note>
  Configuration changes require a broker restart to take effect. Plan configuration updates during maintenance windows for production systems.
</Note>

***

## Configuration Overview

The broker configuration is stored as a JSON object. The structure below shows every supported property (the file is encrypted on disk; this is an illustrative representation):

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "Name": "Coreflux DataHub",
  "Port": 1883,
  "TlsPort": 8883,
  "WebsocketPort": 5000,
  "WebsocketPortTls": 443,
  "BindIPForMQTT": "0.0.0.0",
  "BindIPForMQTTwithTls": "0.0.0.0",
  "BindIpForWebSockets": "0.0.0.0",
  "BindIpForWebSocketsTls": "0.0.0.0",
  "AnonymousLogin": false,
  "CleanSession": false,
  "SessionExpiryInterval": 0,
  "MaxPendingMessagesPerClient": 20000,
  "FullDebugLog": false,
  "CloudLogging": false,
  "ResendRetainTopics": false,
  "ClientCertificationValidation": false,
  "CheckCertificateChainValidation": false,
  "CheckCertificateRevokationList": false,
  "ServerCertificatePath": "",
  "ServerCertificateKeyPath": "",
  "ServerCertificatePassword": "",
  "RootCACertificatePath": "",
  "ClientCertificateSourcePath": "",
  "ClientCertificateRevocationListPath": "",
  "ProjectPath": "",
  "UsersFile": "",
  "EnvsPath": "",
  "SecretsPath": ""
}
```

### First-Run Defaults

When no config file exists, the broker creates one with these values:

| Property                          | Default                      |
| --------------------------------- | ---------------------------- |
| `Name`                            | `"Coreflux DataHub"`         |
| `Port`                            | `1883`                       |
| `TlsPort`                         | `8883`                       |
| `WebsocketPort`                   | `5000`                       |
| `WebsocketPortTls`                | `443`                        |
| Bind IPs (MQTT / TLS / WebSocket) | `"0.0.0.0"` (all interfaces) |
| `AnonymousLogin`                  | `true`                       |
| `FullDebugLog`                    | `false`                      |
| `ClientCertificationValidation`   | `false`                      |
| `MaxPendingMessagesPerClient`     | `20000`                      |
| `CleanSession`                    | `false`                      |
| `SessionExpiryInterval`           | `0`                          |

<Warning>
  On a brand-new install the broker creates the config with `AnonymousLogin: true`. Set it to `false` and configure user credentials before exposing the broker to any untrusted network.
</Warning>

***

## Network Settings

### Ports

The broker listens on multiple ports for different connection types:

<ParamField path="Port" type="integer" default="1883">
  Standard MQTT port for unencrypted connections. This is the default port used by most MQTT clients.
</ParamField>

<ParamField path="TlsPort" type="integer" default="8883">
  MQTT port for TLS-encrypted connections. Requires valid server certificate configuration.
</ParamField>

<ParamField path="WebsocketPort" type="integer" default="5000">
  Port for MQTT over WebSocket connections. Used by browser-based clients and applications that cannot use raw TCP.
</ParamField>

<ParamField path="WebsocketPortTls" type="integer" default="443">
  Port for MQTT over WebSocket with TLS encryption. Commonly set to 443 to work through corporate firewalls.
</ParamField>

<Warning>
  All ports must be between 1 and 65535. Ensure chosen ports are not already in use by other services.
</Warning>

### IP Bindings

Control which network interfaces the broker listens on:

<ParamField path="BindIPForMQTT" type="string">
  IP address to bind for standard MQTT connections. Use `0.0.0.0` to listen on all interfaces, or a specific IP to restrict access.
</ParamField>

<ParamField path="BindIPForMQTTwithTls" type="string">
  IP address to bind for TLS-encrypted MQTT connections.
</ParamField>

<ParamField path="BindIpForWebSockets" type="string">
  IP address to bind for WebSocket connections.
</ParamField>

<ParamField path="BindIpForWebSocketsTls" type="string">
  IP address to bind for WebSocket connections with TLS.
</ParamField>

#### Example: Restrict to Local Network

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "BindIPForMQTT": "192.168.1.100",
  "BindIPForMQTTwithTls": "192.168.1.100",
  "BindIpForWebSockets": "192.168.1.100",
  "BindIpForWebSocketsTls": "192.168.1.100"
}
```

#### Example: Listen on All Interfaces

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "BindIPForMQTT": "0.0.0.0",
  "BindIPForMQTTwithTls": "0.0.0.0",
  "BindIpForWebSockets": "0.0.0.0",
  "BindIpForWebSocketsTls": "0.0.0.0"
}
```

***

## Security Settings

### Authentication

<ParamField path="AnonymousLogin" type="boolean" default="true (first run)">
  When `true`, clients may connect **without** a valid username/password, and unknown usernames are treated as anonymous. When `false`, only registered users in the users store can connect.

  The class default is `false`, but on a brand-new install the broker writes the first-run config with `AnonymousLogin: true`. Enforced at runtime in `ValidateConnectionAsync`, which rejects unauthenticated connects when `false` and the user is not found.
</ParamField>

<Warning>
  Never leave `AnonymousLogin` enabled in production environments. Always require authentication for broker access.
</Warning>

### TLS Server Certificate

Configure TLS encryption for secure client connections:

<ParamField path="ServerCertificatePath" type="string">
  Path to the server certificate file (PEM or PFX format). Required to enable the TLS listeners — MQTTS and WSS endpoints are only started when a server certificate is loaded successfully. If set but the file is missing, a warning is logged and the broker may still start without TLS.
</ParamField>

<ParamField path="ServerCertificateKeyPath" type="string">
  Path to the **private key** file when the certificate and key are in separate PEM files. Leave empty if the key is embedded in the certificate file.
</ParamField>

<ParamField path="ServerCertificatePassword" type="string">
  Password for an encrypted private key or PFX bundle. If `ServerCertificatePath` is set but this is empty, a warning is logged at startup.
</ParamField>

<ParamField path="RootCACertificatePath" type="string">
  Path to the root CA certificate for certificate chain validation.
</ParamField>

#### Example: TLS Configuration

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "ServerCertificatePath": "/certs/server.crt",
  "ServerCertificateKeyPath": "/certs/server.key",
  "ServerCertificatePassword": "your-certificate-password",
  "RootCACertificatePath": "/certs/ca.crt"
}
```

### Mutual TLS (mTLS)

For environments requiring client certificate authentication:

<ParamField path="ClientCertificateSourcePath" type="string">
  Directory or source containing the **trusted client CA / client certificate** material used during mTLS validation. If set but the path does not exist, a warning is logged at startup.
</ParamField>

<ParamField path="ClientCertificationValidation" type="boolean" default="false">
  Enable client certificate validation. When `true`, TLS connections **require** a client certificate (`ClientCertificateMode.RequireCertificate`). When `false`, client certificates are optional (`AllowCertificate`).
</ParamField>

<ParamField path="ClientCertificateRevocationListPath" type="string">
  Path to the Certificate Revocation List (CRL) file for checking revoked certificates.
</ParamField>

<ParamField path="CheckCertificateRevokationList" type="boolean" default="false">
  Enable CRL checking for client certificates.
</ParamField>

<ParamField path="CheckCertificateChainValidation" type="boolean" default="false">
  Enable full certificate chain validation for client certificates.
</ParamField>

#### Example: mTLS Configuration

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "ServerCertificatePath": "/certs/server.crt",
  "ServerCertificateKeyPath": "/certs/server.key",
  "ServerCertificatePassword": "your-password",
  "ClientCertificateSourcePath": "/certs/trusted-clients/",
  "ClientCertificationValidation": true,
  "CheckCertificateChainValidation": true,
  "CheckCertificateRevokationList": true,
  "ClientCertificateRevocationListPath": "/certs/crl.pem"
}
```

<Tip>
  mTLS is recommended for high-security environments where you need to verify client identity at the transport layer, in addition to username/password authentication.
</Tip>

***

## Sessions and MQTT Behavior

<ParamField path="CleanSession" type="boolean" default="false">
  **Broker policy** (not the client CONNECT flag).

  * `false` — allow persistent sessions; honour each client's Clean Session / Clean Start flag.
  * `true` — **require** clean sessions only; reject clients that connect with a persistent session (returns `NotAuthorized`).

  Wired in via `ValidateConnectionAsync` (reject policy) and `WithPersistentSessions(!CleanSession)` at startup.
</ParamField>

<Note>
  **Naming note:** `CleanSession = true` on the broker means "force clean sessions from clients", not "enable clean session".
</Note>

<Warning>
  **Clean Session enforcement** — per the MQTT 5.0 spec, a broker with `CleanSession = true` rejects any client connecting with `CleanSession = false` (persistent session). Make sure your clients connect with a clean session when this policy is enabled.
</Warning>

<ParamField path="SessionExpiryInterval" type="integer (seconds)" default="0">
  **MQTT 5 only** — maximum session lifetime cap, in seconds. Defines how long the broker holds a session after a client disconnects. (Previously hardcoded to 10 minutes; now configurable.)

  * `0` — no cap; the client's CONNECT value is used as-is.
  * `> 0` — reject persistent connects where the client requests **more** than this many seconds.
  * `4294967295` (`uint.MaxValue`) — allow "never expire" client requests.

  Applied in `MqttService.ApplyConfiguredSessionExpiry` during connection validation.

  **MQTT 3.1.1:** ignored — persistence is controlled by `CleanSession` + `WithPersistentSessions` only.

  **Important:** Coreflux has **no** server-builder API for session expiry. Clients that need MQTT 5 persistence must set `SessionExpiryInterval > 0` in their CONNECT packet.
</ParamField>

<ParamField path="ResendRetainTopics" type="boolean" default="false">
  When `true`, the broker maintains a buffer of retained messages and re-publishes them in specific situations: on new subscriptions (copies retained messages into an internal buffer) and via periodic `LogRetainedObjects` publishing. Useful when clients need retained messages re-delivered after reconnect or subscription changes.
</ParamField>

***

## Performance and Back-Pressure

<ParamField path="MaxPendingMessagesPerClient" type="integer" default="20000">
  Maximum number of **pending outbound messages** queued per connected client before Coreflux drops messages (especially QoS 0). Protects broker memory when a client is slow to read.

  Wired in via `WithMaxPendingMessagesPerClient` at startup.
</ParamField>

<Warning>
  `MaxPendingMessagesPerClient` must be between `1` and `100000`. A value outside this range prevents the broker from starting.
</Warning>

***

## Deployment and Data Paths

These paths control where the broker stores its state. `ProjectPath` is the "base" that the other three resolve against.

<ParamField path="ProjectPath" type="string (directory path)">
  Overrides the broker **data root** (`CFBasePath`) so all state (`bin`, `log`, `stats`, config, projects, users, envs, secrets) lives under this path instead of the default install directory. Typical for Kubernetes volumes or custom install layouts. If not set, the broker uses its install directory.

  **Precedence:** the `COREFLUX_DATA_PATH` environment variable and the `-p` / `--path` CLI flag override `ProjectPath` when set.
</ParamField>

<ParamField path="UsersFile" type="string (file path)">
  Path to the file holding the broker's user accounts (the username/password credentials used when `AnonymousLogin` is `false`). When set and valid, users load from this **plaintext JSON** array instead of the encrypted user store, and runtime user changes are written back to this file.
</ParamField>

<ParamField path="EnvsPath" type="string (directory path)">
  Directory containing the `.env` file for environment variables the broker (and LOT logic) can reference at runtime — used to externalize deployment-specific values instead of hardcoding them in config. Resolves to `{EnvsPath}/.env`. Falls back to `CFBasePath` when empty. See [Environment Variables & Secrets](/latest/mqtt-broker/secrets-and-env) for usage.
</ParamField>

<ParamField path="SecretsPath" type="string (directory path)">
  Directory containing `secrets.json` — the secrets store for sensitive values (tokens, keys, credentials) kept separate from the main config so they aren't sitting in plain config JSON. Used by routes and LOT `GET SECRET`. Resolves to `{SecretsPath}/secrets.json`. Falls back to `CFBasePath` when empty. See [Environment Variables & Secrets](/latest/mqtt-broker/secrets-and-env) for usage.
</ParamField>

***

## Logging

<ParamField path="FullDebugLog" type="boolean" default="false">
  Enable detailed debug logging: connection validation details, every publish/subscription intercept, TCP health noise, etc. Useful for troubleshooting but may impact performance in production.
</ParamField>

<Warning>
  Only enable `FullDebugLog` for troubleshooting. Debug logging generates significant log volume and may impact broker performance.
</Warning>

<ParamField path="CloudLogging" type="boolean" default="false">
  When `true`, switches logging to **stdout-only structured JSON** (no rolling file sink). Intended for Docker/Kubernetes where log aggregators scrape container output. The `COREFLUX_CLOUD_LOGGING=true` environment variable also enables cloud logging.
</ParamField>

***

## Additional Settings

<ParamField path="Name" type="string" default="Coreflux DataHub">
  A human-readable name for this DataHub / broker instance. Used for identification in logs and UI; does not affect MQTT protocol behaviour.
</ParamField>

***

## Applying Configuration

### Via MQTT Topic

Publish a configuration JSON to the system topic using any MQTT client (such as MQTT Explorer). You can send a **partial update** — only the fields you include are changed; everything else is left as-is:

| Field     | Value                                                |
| --------- | ---------------------------------------------------- |
| **Topic** | `$SYS/Coreflux/Config/New`                           |
| **Auth**  | Requires a user with system configuration permission |

**Payload:** Full or partial configuration JSON object

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{"Name":"ProductionBroker","Port":1883,"TlsPort":8883,"AnonymousLogin":false}
```

<Info>
  The runtime handler currently persists only a subset of fields (`AnonymousLogin`, bind IPs, ports, `FullDebugLog`). After publishing, you must restart the broker for changes to take effect — a restart is required for listener, session, and certificate changes to take full effect.
</Info>

### Configuration Validation

The broker validates configuration on load. The following checks are **fatal** — an invalid value prevents the broker from starting:

| Check                         | Requirement                  |
| ----------------------------- | ---------------------------- |
| Port values                   | Must be between 1 and 65535  |
| IP addresses                  | Must be valid IPv4 addresses |
| `MaxPendingMessagesPerClient` | Must be between 1 and 100000 |

Certificate-related issues are **non-fatal**: they log a warning at startup and the broker continues without TLS rather than refusing to start.

| Condition                                                         | Behaviour                                 |
| ----------------------------------------------------------------- | ----------------------------------------- |
| `ServerCertificatePath` set but file missing                      | Warning logged; TLS listeners not started |
| `ServerCertificatePath` set but `ServerCertificatePassword` empty | Warning logged                            |
| `ClientCertificateSourcePath` set but path does not exist         | Warning logged                            |

### Related Environment Variables

These are **not** properties in the configuration object but override or complement it:

| Variable                 | Effect                                                      |
| ------------------------ | ----------------------------------------------------------- |
| `COREFLUX_DATA_PATH`     | Data root; takes precedence over `ProjectPath`              |
| `COREFLUX_CLOUD_LOGGING` | Enables stdout JSON logging (same intent as `CloudLogging`) |

***

## Docker Configuration

When running Coreflux in Docker, configure the broker using environment variables or mounted configuration files.

### Using Environment Variables

<Tabs>
  <Tab title="Docker Run">
    ```bash wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    docker run -d \
      -p 1883:1883 \
      -p 8883:8883 \
      -p 5000:5000 \
      -v /path/to/certs:/certs \
      -v /path/to/config:/config \
      --name coreflux \
      coreflux/broker
    ```
  </Tab>

  <Tab title="Docker Compose">
    ```yaml wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
    version: '3.8'
    services:
      coreflux:
        image: coreflux/broker
        container_name: coreflux
        ports:
          - "1883:1883"
          - "8883:8883"
          - "5000:5000"
          - "443:443"
        volumes:
          - ./config:/config
          - ./certs:/certs
        restart: unless-stopped
    ```
  </Tab>
</Tabs>

### Mounting Configuration

Mount your configuration file to the container:

```bash wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
docker run -d \
  -v /path/to/config.json:/app/config.json \
  -p 1883:1883 \
  coreflux/broker
```

### TLS with Docker

When using TLS in Docker, ensure certificate paths in the configuration match the mounted paths inside the container:

```yaml wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
version: '3.8'
services:
  coreflux:
    image: coreflux/broker
    ports:
      - "1883:1883"
      - "8883:8883"
    volumes:
      - ./certs/server.crt:/certs/server.crt:ro
      - ./certs/server.key:/certs/server.key:ro
      - ./certs/ca.crt:/certs/ca.crt:ro
```

Configuration JSON should reference the container paths:

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "ServerCertificatePath": "/certs/server.crt",
  "ServerCertificateKeyPath": "/certs/server.key",
  "RootCACertificatePath": "/certs/ca.crt"
}
```

***

## Configuration Examples

### Development Environment

Minimal configuration for local development:

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "Name": "DevBroker",
  "Port": 1883,
  "AnonymousLogin": true,
  "FullDebugLog": true,
  "BindIPForMQTT": "127.0.0.1"
}
```

### Production Environment

Secure configuration for production deployment:

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "Name": "ProductionBroker",
  "Port": 1883,
  "TlsPort": 8883,
  "WebsocketPort": 5000,
  "WebsocketPortTls": 443,
  "AnonymousLogin": false,
  "FullDebugLog": false,
  "BindIPForMQTT": "0.0.0.0",
  "BindIPForMQTTwithTls": "0.0.0.0",
  "BindIpForWebSockets": "0.0.0.0",
  "BindIpForWebSocketsTls": "0.0.0.0",
  "ServerCertificatePath": "/certs/server.crt",
  "ServerCertificateKeyPath": "/certs/server.key",
  "ServerCertificatePassword": "secure-password",
  "RootCACertificatePath": "/certs/ca.crt"
}
```

### High-Security Environment

Configuration with mTLS for maximum security:

```json wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "Name": "SecureBroker",
  "Port": 1883,
  "TlsPort": 8883,
  "AnonymousLogin": false,
  "FullDebugLog": false,
  "BindIPForMQTT": "0.0.0.0",
  "BindIPForMQTTwithTls": "0.0.0.0",
  "ServerCertificatePath": "/certs/server.crt",
  "ServerCertificateKeyPath": "/certs/server.key",
  "ServerCertificatePassword": "secure-password",
  "RootCACertificatePath": "/certs/ca.crt",
  "ClientCertificateSourcePath": "/certs/trusted-clients/",
  "ClientCertificationValidation": true,
  "CheckCertificateChainValidation": true,
  "CheckCertificateRevokationList": true,
  "ClientCertificateRevocationListPath": "/certs/crl.pem"
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Broker Commands" icon="terminal" href="/latest/mqtt-broker/commands">
    Learn how to manage the broker via MQTT commands.
  </Card>

  <Card title="$SYS Topics" icon="sitemap" href="/latest/mqtt-broker/sys-topics">
    Monitor broker status through system topics.
  </Card>
</CardGroup>
