Configuration

To list all CLI options, start chirpstack with the --help flag. This will print:

ChirpStack is an open-source LoRaWAN(TM) Network Server

Usage: chirpstack --config <DIR> [COMMAND]

Commands:
  configfile
          Print the configuration template
  print-ds
          Print the device-session for debugging
  import-legacy-lorawan-devices-repository
          Import legacy lorawan-devices repository
  create-api-key
          Create global API key
  help
          Print this message or the help of the given subcommand(s)

Options:
  -c, --config <DIR>  Path to configuration directory
  -h, --help          Print help
  -V, --version       Print version

Configuration files

ChirpStack must be started using the -c / --config-dir argument. This directory must contain one or multiple .toml configuration files. Typically it will contain a single chirpstack.toml configuration file for common configuration, and multiple region_...toml configuration files, one for each region configuration.

Environment variables

Values in the configuration file can be substituted by environment variables. Example:

[integration.mqtt]
  server="tcp://$MQTT_BROKER_HOST:1883/"
  json=true

In the above example, $MQTT_BROKER_HOST gets replaced if the MQTT_BROKER_HOST variable is set, with the value of this environment variable.

Configuration examples

Configuration examples are included in most ChirpStack distributables. A complete overview of configuration examples can be found here: https://github.com/chirpstack/chirpstack/tree/master/chirpstack/configuration

Example chirpstack.toml configuration



# Logging configuration
[logging]

  # Log level.
  #
  # Valid options are:
  #   * TRACE
  #   * DEBUG
  #   * INFO
  #   * WARN
  #   * ERROR
  #   * OFF
  level="info"

  # Log as JSON.
  json=false

# PostgreSQL configuration.
[postgresql]

  # PostgreSQL DSN.
  #
  # Format example: postgres://<USERNAME>:<PASSWORD>@<HOSTNAME>/<DATABASE>?sslmode=<SSLMODE>.
  #
  # SSL mode options:
  #  * disable - Do not use TLS
  #  * prefer - Attempt to connect with TLS but allow sessions without
  #  * require - Require the use of TLS
  dsn="postgresql://chirpstack:chirpstack@localhost/chirpstack?sslmode=disable"

  # Max open connections.
  #
  # This sets the max. number of open connections that are allowed in the
  # PostgreSQL connection pool.
  max_open_connections=10

  # CA certificate (optional).
  #
  # Set this to the path of the CA certificate in case you are using TLS and
  # the server-certificate is not signed by a CA in the platform certificate
  # store.
  ca_cert=""


# Redis configuration.
[redis]

  # Server address or addresses.
  #
  # Use rediss:// in case of a TLS secured connection.
  #
  # Example formats:
  #   redis://127.0.0.1:6379
  #   rediss://127.0.0.1:6379
  #   redis://:password@127.0.0.1:6379
  #   redis://username:password@127.0.0.1:6379
  #
  # Set multiple addresses when connecting to a cluster.
  servers=[
    "redis://127.0.0.1/",
  ]

  # Redis Cluster.
  #
  # Set this to true when the provided URLs are pointing to a Redis Cluster
  # instance.
  cluster=false

  # Key prefix.
  #
  # A key prefix can be used to avoid key collisions when multiple deployments
  # are using the same Redis database and it is not possible to separate
  # keys by database index (e.g. when using Redis Cluster, which does not
  # support multiple databases).
  key_prefix=""

  # Max open connections.
  #
  # This sets the max. number of open connections that are allowed in the
  # Redis connection pool.
  max_open_connections=100

  # Min idle connections.
  #
  # This sets the min. number of idle connections in the Redis connection
  # pool (0 = equal to max_open_connections).
  min_idle_connections=0


# API interface configuration.
[api]

  # interface:port to bind the API interface to.
  bind="0.0.0.0:8080"

  # Secret.
  #
  # This secret is used for generating login and API tokens, make sure this
  # is never exposed. Changing this secret will invalidate all login and API
  # tokens. The following command can be used to generate a random secret:
  #   openssl rand -base64 32
  secret=""


# Global gateway configuration.
# Please note that backend configuration can be found in the per-region
# configuration.
[gateway]

  # CA certificate and key file (optional).
  #
  # If setting the CA certificate and key file options, ChirpStack 
  # will generate client certificates which can be used by the gateway for
  # authentication and authorization. The Common Name of the certificate will
  # be set to the Gateway ID.
  #
  # The ca_key is expected to be in PKCS#8 format (you can use openssl to
  # convert to PKCS#8).
  ca_cert=""
  ca_key=""

  # Certificate lifetime.
  #
  # This defines how long (after generating) the certificate remains valid.
  client_cert_lifetime="11months 30days 3h 50m 24s"

  # Allow unknown gateways.
  #
  # If set to true, then uplinks received from gateways not configured in
  # ChirpStack will be allowed.
  allow_unknown_gateways=false


# Network related configuration.
[network]

  # Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).
  net_id="000000"

  # Secondary NetIDs.
  #
  # Additional NetIDs. At this moment, the additional NetIDs are only used to
  # validate if an uplink belongs to the ChirpStack instance or if it is a
  # roaming device (if roaming is enabled).
  # If you would like to assign DevAddrs from multiple NetIDs, you must specify
  # these in the dev_addr_prefixes configuration.
  secondary_net_ids=[
  ]

  # DevAddr prefix(es).
  #
  # This makes it possible to configure one or multiple DevAddr (sub)ranges
  # If left blank, then the complete DevAddr space provided by the configured
  # net_id value will be used. If multiple prefixes are configured, a random
  # prefix will be chosen when generating a DevAddr.
  #
  # Example configuration:
  # dev_addr_prefixes=["0000ff00/24"]
  #
  # This example configures the DevAddr range to 0000ff00 - 0000ffff.
  # The /24 means that the 24MSB of the prefix will be used, meaning that the
  # 8LSB will be used as address space.
  dev_addr_prefixes=[
  ]

  # Enabled regions.
  #
  # Multiple regions can be enabled simultaneously. Each region must match
  # the 'name' parameter of the region configuration in '[[regions]]'.
  enabled_regions=[
  ]

  # Time to wait for uplink de-duplication.
  #
  # This is the time that ChirpStack will wait for other gateways to receive
  # the same uplink frame. Please note that this value affects the
  # roundtrip time. The total roundtrip time (which includes network latency)
  # must be less than the (first) receive-window.
  deduplication_delay="200ms"

  # Get downlink data delay.
  #
  # This is the time that ChirpStack waits between forwarding data to the
  # integration(s) and reading data from the queue. A higher value means that
  # an end-application has more time to schedule a downlink queue item which
  # can be processed within the same uplink / downlink transaction.
  # Please note that this value has influence on the uplink / downlink
  # roundtrip time. Setting this value too high means ChirpStack will be
  # unable to respond to the device within its receive-window.
  get_downlink_data_delay="100ms"

  # Mac-commands disabled.
  mac_commands_disabled=false

  # Custom ADR plugins.
  #
  # The custom ADR plugin must be implemented in JavaScript. For an example
  # skeleton, please see:
  # https://github.com/chirpstack/chirpstack/blob/master/examples/adr_plugins/plugin_skeleton.js
  adr_plugins=[
  ]


  # Scheduler settings.
  [network.scheduler]

    # Scheduler interval.
    #
    # The interval in which the downlink scheduler for multicast, Class-B and
    # Class-C runs.
    interval="1s"

    # Class-A lock duration.
    #
    # This defines the lock duration between receiving a Class-A uplink and
    # the next scheduler-run for a device. The purpose of this lock is to
    # avoid collisions between Class-A and Class-B/C downlinks.
    class_a_lock_duration="5s"

    # Class-C lock duration.
    #
    # This defines the lock duration between scheduling two Class-C downlink
    # payloads for the same device. The purpose of this lock is to avoid
    # overlap between scheduling Class-C downlinks and / or spreading the 
    # downlink capacity load on the gateway.
    class_c_lock_duration="5s"

    # Multicast Class-C margin.
    #
    # This defines the minimum margin between scheduling multiple multicast downlinks
    # (within the same multicast-group). This value must be equal or greater than the
    # scheduler interval.
    multicast_class_c_margin="5s"

    # Multicast Class-B margin.
    #
    # This defines the minimum margin between scheduling multiple multicast downlinks
    # (within the same multicast-group). This value must be equal or greater than the
    # scheduler interval.
    multicast_class_b_margin="5s"


# Monitoring related configuration.
[monitoring]

  # interface:port to bind the monitoring endpoint to (optional).
  #
  # /health  - Returns 200 in case the healthchecks have passed.
  # /metrics - Returns metrics which can be scraped by Prometheus.
  #
  # If not set, this endpoint will be disabled.
  bind=""

  # Backend Interfaces log max history.
  #
  # This defines the max number of Backend Interface request records that will be persisted
  # in Redis Streams. Setting this value to 0 disables this features.
  backend_interfaces_log_max_history=10

  # Meta-log max history.
  #
  # This defines the max number of meta records that will be persisted in Redis Streams.
  # Setting this value to 0 disables this feature.
  meta_log_max_history=10

  # Gateway frame-log max history.
  #
  # This defines the max number of frame-log records that will be persisted in Redis Streams.
  # This stream contains the uplink and downlink frames of all gateways.
  # Setting this value to 0 disables this feature.
  gateway_frame_log_max_history=10

  # Device frame-log max history.
  #
  # This defines the max number of frame-log records that will be persisted in Redis Streams.
  # This stream contains the uplink and downlink frames of all devices.
  # Setting this value to 0 disables this feature.
  device_frame_log_max_history=10

  # Device event-log max history.
  #
  # This defines the max number of event-log records that will be persisted in Redis Streams.
  # This stream contains the events of all devices.
  # Setting this value to 0 disables this feature.
  device_event_log_max_history=10

  # Per gateway frame-log max history.
  #
  # Equal to the gateway_frame_log_max_history, but for each gateway a new Redis Stream
  # is created.
  # Setting this value to 0 disables this feature.
  per_gateway_frame_log_max_history=10

  # Per gateway frame-log TTL.
  #
  # This defines the TTL of the Redis Stream key.
  per_gateway_frame_log_ttl="1month 13h 26m 24s"

  # Per device frame-log max history.
  #
  # Equal to the device_frame_log_max_history, but for each device a new Redis Stream
  # is created.
  # Setting this value to 0 disables this feature.
  per_device_frame_log_max_history=10

  # Per device frame-log TTL.
  #
  # This defines the TTL of the Redis Stream key.
  per_device_frame_log_ttl="1month 13h 26m 24s"

  # Per device event-log max history.
  #
  # Equal to the device_event_log_max_history, but for each device a new Redis Stream
  # is created.
  # Setting this value to 0 disables this feature.
  per_device_event_log_max_history=10

  # Per device event-log TTL.
  #
  # This defines the TTL of the Redis Stream key.
  per_device_event_log_ttl="1month 13h 26m 24s"


# Global integration related configuration.
[integration]

  # Enabled integrations (global).
  enabled = [
  ]

  # MQTT integration configuration.
  [integration.mqtt]

    # Event topic template.
    event_topic="application/{{application_id}}/device/{{dev_eui}}/event/{{event}}"

    # Command topic.
    #
    # This is the topic on which the MQTT subscribes for receiving (enqueue) commands.
    command_topic="application/{{application_id}}/device/{{dev_eui}}/command/{{command}}"

    # Use JSON encoding instead of Protobuf (binary).
    json=true

    # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
    server="tcp://127.0.0.1:1883/"

    # Connect with the given username (optional)
    username=""

    # Connect with the given password (optional)
    password=""

    # Quality of service level
    #
    # 0: at most once
    # 1: at least once
    # 2: exactly once
    #
    # Note: an increase of this value will decrease the performance.
    # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
    qos=0

    # Clean session
    #
    # Set the "clean session" flag in the connect message when this client
    # connects to an MQTT broker. By setting this flag you are indicating
    # that no messages saved by the broker for this client should be delivered.
    clean_session=false

    # Client ID
    #
    # Set the client id to be used by this client when connecting to the MQTT
    # broker. A client id must be no longer than 23 characters. If left blank,
    # a random id will be generated by ChirpStack.
    client_id=""

    # Keep alive interval.
    #
    # This defines the maximum time that that should pass without communication
    # between the client and server.
    keep_alive_interval="30s"

    # CA certificate file (optional)
    #
    # Use this when setting up a secure connection (when server uses ssl://...)
    # but the certificate used by the server is not trusted by any CA certificate
    # on the server (e.g. when self generated).
    ca_cert=""

    # TLS certificate file (optional)
    tls_cert=""

    # TLS key file (PKCS#8) (optional)
    tls_key=""


    # Configuration for MQTT clients.
    [integration.mqtt.client]

      # CA certificate and key file (optional).
      #
      # If setting the CA certificate and key file options, ChirpStack 
      # will generate client certificates which can be used by the MQTT clients for
      # authentication and authorization. The Common Name of the certificate will
      # be set to the ID of the application.
      #
      # The ca_key is expected to be in PKCS#8 format (you can use openssl to
      # convert to PKCS#8).
      ca_cert=""
      ca_key=""

      # Certificate lifetime.
      #
      # This defines how long (after generating) the certificate remains valid.
      client_cert_lifetime="11months 30days 3h 50m 24s"


  # PostgreSQL integration configuration.
  [integration.postgresql]

    # PostgreSQL DSN.
    #
    # Format example: postgres://<USERNAME>:<PASSWORD>@<HOSTNAME>/<DATABASE>?sslmode=<SSLMODE>.
    #
    # SSL mode options:
    #  * disable - no SSL
    #  * require - Always SSL (skip verification)
    #  * verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA)
    #  * verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate)
    dsn="postgresql://chirpstack_integration:chirpstack_integration@localhost/chirpstack_integration?sslmode=disable"

    # Max open connections.
    #
    # This sets the max. number of open connections that are allowed in the
    # PostgreSQL connection pool.
    max_open_connections=10

    # CA certificate (optional).
    #
    # Set this to the path of the CA certificate in case you are using TLS and
    # the server-certificate is not signed by a CA in the platform certificate
    # store.
    ca_cert=""


  # AMQP / RabbitMQ integration configuration.
  [integration.amqp]

    # Server URL.
    #
    # See for a specification of all the possible options:
    # https://www.rabbitmq.com/uri-spec.html
    url="amqp://guest:guest@localhost:5672"

    # Event routing key.
    #
    # This is the event routing-key template used when publishing device
    # events. Messages will be published to the "amq.topic" exchange.
    event_routing_key="application.{{application_id}}.device.{{dev_eui}}.event.{{event}}"

    # Use JSON encoding instead of Protobuf (binary).
    json=true


  # Kafka integration configuration.
  [integration.kafka]

    # Brokers.
    brokers=[
      "localhost:9092",
    ]

    # TLS.
    #
    # Set this to true when the Kafka client must connect using TLS to the Broker.
    tls=false

    # Topic for events.
    topic="chirpstack"

    # Template for keys included in Kafka messages.
    # Kafka uses the key for distributing messages over partitions. You can use
    # this to ensure some subset of messages end up in the same partition, so
    # they can be consumed in-order. And Kafka can use the key for data retention
    # decisions.  A header "event" with the event type is included in each
    # message. There is no need to parse it from the key.
    event_key="application.{{application_id}}.device.{{dev_eui}}.event.{{event}}"

    # Username (optional).
    username=""

    # Password.
    password=""

    # Mechanism.
    #
    # Valid options are:
    # * PLAIN
    # * SCRAM-SHA-256
    # * SCRAM-SHA-512
    mechanism="PLAIN"

    # Use JSON encoding instead of Protobuf (binary).
    json=true


# Codec configuration.
[codec]

  # JS codec configuration.
  [codec.js]

    # Maximum execution time.
    max_execution_time="100ms"


# User authentication configuration.
[user_authentication]

  # Enabled authentication backend.
  #
  # Options are:
  #  * internal       - Internal authentication backend (default).
  #  * openid_connect - OpenID Connect based backend.
  #  * oauth2         - OAuth2 based backend.
  enabled="internal"

  # OpenID Connect.
  [user_authentication.openid_connect]

    # Registration enabled.
    #
    # Enabling this will automatically register the user when it is not yet present
    # in the ChirpStack database. There is no registration form as the user information
    # is automatically received using the OpenID Connect provided information.
    # The user will not be associated with any organization, but in order to
    # facilitate the automatic onboarding of users, it is possible to configure a
    # registration callback URL (next config option).
    registration_enabled=false

    # Registration callback URL.
    #
    # This (optional) endpoint will be called on the registration of the user and
    # can implement the association of the user with an organization, create a new
    # organization, ...
    # ChirpStack will make a HTTP POST call to this endpoint,
    # with the following URL parameters:
    # - user_id, of the newly created user in ChirpStack.
    #
    # The POST body contains a JSON payload with the OpenID Connect UserInfo payload.
    registration_callback_url=""

    # Provider URL.
    # This is the URL of the OpenID Connect provider.
    # Example: https://auth.example.org
    provider_url=""

    # Client ID.
    client_id=""

    # Client secret.
    client_secret=""

    # Redirect URL.
    #
    # This must contain the ChirpStack web-interface hostname
    # with '/auth/oidc/callback' path, e.g. https://example.com/auth/oidc/callback.
    redirect_url=""

    # Logout URL.
    #
    # When set, ChirpStack will redirect to this URL instead
    # of redirecting to the login page.
    logout_url=""

    # Login redirect.
    #
    # If set to true, then ChirpStack will immediately redirect to the OAuth2
    # provider for login.
    login_redirect=false

    # Login label.
    #
    # The login label is used in the web-interface login form.
    login_label=""

    # Assume e-mail verified.
    #
    # If set to true, then ChirpStack will ignore the email_verified received
    # from the OpenID Connect provider, assuming it will be true. Some
    # providers do not provide this field, in which case setting this value
    # is needed.
    assume_email_verified=false

    # Scopes.
    #
    # This configures the scopes that are used during login. You must at least define
    # "email" and "profile".
    scopes=[
      "email",
      "profile",
    ]

  # OAuth2 backend.
  [user_authentication.oauth2]

    # Provider.
    #
    # Options are:
    #  * clerk
    provider=""

    # Registration enabled.
    #
    # Enabling this will automatically register the user when it is not yet present
    # in the ChirpStack database. There is no registration form as the user information
    # is automatically received using the OAuth2 provided information.
    # The user will not be associated with any organization, but in order to
    # facilitate the automatic onboarding of users, it is possible to configure a
    # registration callback URL (next config option).
    registration_enabled=false

    # Registration callback URL.
    #
    # This (optional) endpoint will be called on the registration of the user and
    # can implement the association of the user with an organization, create a new
    # organization, ...
    # ChirpStack will make a HTTP POST call to this endpoint,
    # with the following URL parameters:
    # - user_id, of the newly created user in ChirpStack.
    #
    # The POST body contains a JSON payload with the OAuth2 payload.
    registration_callback_url=""

    # OAuth2 client ID.
    client_id=""

    # OAuth2 client secret.
    client_secret=""

    # OAuth2 auth URL.
    auth_url=""

    # OAuth2 token URL.
    token_url=""

    # Userinfo URL.
    #
    # This is the URL that ChirpStack will request to receive the user information.
    userinfo_url=""
    
    # Redirect URL.
    #
    # This must contain the ChirpStack web-interface hostname
    # with '/auth/oauth2/callback' path, e.g. https://example.com/auth/oauth2/callback.
    redirect_url=""

    # Logout URL.
    #
    # When set, ChirpStack will redirect to this URL instead
    # of redirecting to the login page.
    logout_url=""

    # Login redirect.
    #
    # If set to true, then ChirpStack will immediately redirect to the OAuth2
    # provider for login.
    login_redirect=false

    # Login label.
    #
    # The login label is used in the web-interface login form.
    login_label=""

    # Assume e-mail verified.
    #
    # If set to true, then ChirpStack will ignore the email_verified received
    # from the userinfo URL, assuming it will be true.
    assume_email_verified=false

    # Scopes.
    #
    # This configures the scopes that are used during login. You must at least define
    # "email".
    scopes=[
      "email",
    ]


# Join Server configuration.
[join_server]

    # Per Join Server configuration (this can be repeated).
    #
    # ChirpStack will try to match the Join-Request JoinEUI against each
    # join_eui_prefix in the same order as they appear in the configuration.
    #
    # If you configure a 'catch-all' Join Server, then this entry must appear
    # as the last item in the list.
    #
    # Example:
    # [[join_server.servers]]
    #
    #   # JoinEUI prefix that must be routed to the Join Server.
    #   #
    #   # Example '0102030405060700/56` means that the 56MSB of the
    #   # join_eui_prefix will be used to match against the JoinEUI.
    #   # Thus the following JoinEUI range will be forwarded to the
    #   # configured Join Server:
    #   #   0102030405060700 - 01020304050607ff
    #   join_eui_prefix="0102030405060708/64"
    #
    #   # Server endpoint.
    #   server="https://example.com:1234/join/endpoint"

    #   # Use the async interface scheme.
    #   async_interface=false

    #   # Async interface request timeout.
    #   async_interface_timeout="1s"

    #   # CA certificate (optional).
    #   #
    #   # Set this to validate the join-server server certificate (e.g. if the
    #   # certificate was self-signed).
    #   ca_cert="/path/to/ca.pem"

    #   # TLS client-certificate (optional).
    #   #
    #   # Set this to enable client-certificate authentication with the join-server.
    #   tls_cert="/path/to/tls_cert.pem"

    #   # TLS client-certificate key (optional).
    #   #
    #   # Set this to enable client-certificate authentication with the join-server.
    #   tls_key="/path/to/tls_key.pem"


# Backend Interfaces configuration (optional).
[backend_interfaces]

  # interface:port to bind the Backend Interfaces API to.
  #
  # Note: this interface is used both for passive-roaming and when
  # integrating with Join Servers that implement the async interface.
  # Leaving this option blank will disable the Backend Interfaces API,
  # which is fine in most cases.
  bind=""

  # CA certificate (path).
  ca_cert=""

  # TLS certificate (path).
  tls_cert=""

  # TLS key (PKCS#8) (path).
  tls_key=""


# Roaming configuration.
[roaming]

  # Resolve NetID domain suffix.
  resolve_net_id_domain_suffix=""


  # Default roaming server.
  [roaming.default]

    # Enable default roaming server.
    enabled=false

    # Async timeout (set to 0 to disable async interface).
    async_timeout="0s"

    # Passive-roaming session lifetime (set to 0 for stateless).
    passive_roaming_lifetime="0s"
   
    # Passive-roaming KEK label (optional).
    #
    # If set, the session-keys will be encrypted using the given KEK.
    passive_roaming_kek_label=""

    # Passive-roaming validate MIC.
    #
    # If set ChirpStack will validate the MIC (for non-stateless roaming
    # agreements). As well it means it will expose the NwkSKey / FNwkSIntKey
    # on PRStartAns.
    passive_roaming_validate_mic=false
   
    # Server.
    #
    # If set, this will bypass the DNS resolving of the server.
    server=""
   
    # Use target role suffix.
    #
    # Depending the context of the remote server, this will add
    # the /sns or /fns path to the server endpoint.
    use_target_role_suffix=false
   
    # CA certificate (path).
    ca_cert=""
  
    # TLS certificate (path).
    tls_cert=""
  
    # TLS key (PKCS#8) (path).
    tls_key=""
   
    # Authorization header.
    #
    # Optional value of the Authorization header, e.g. token or password.
    authorization_header=""


  # Per server roaming configuration (this can be repeated).
  # Example:
  # [[roaming.servers]]
  #
  #  # NetID of the roaming server.
  #  net_id="010203"
  #
  #  # Async timeout (set to 0 to disable async interface).
  #  async_timeout="0s"
  #
  #  # Passive-roaming session lifetime (set to 0 for stateless).
  #  passive_roaming_lifetime="0s"
  #
  #  # Passive-roaming KEK label (optional).
  #  #
  #  # If set, the session-keys will be encrypted using the given KEK.
  #  passive_roaming_kek_label=""

  #  # Passive-roaming validate MIC.
  #  #
  #  # If set ChirpStack will validate the MIC (for non-stateless roaming
  #  # agreements). As well it means it will expose the NwkSKey / FNwkSIntKey
  #  # on PRStartAns.
  #  passive_roaming_validate_mic=false
  #
  #  # Server.
  #  #
  #  # If set, this will bypass the DNS resolving of the server.
  #  server="https://example.com:1234"
  #
  #  # Use target role suffix.
  #  #
  #  # Depending the context of the remote server, this will add
  #  # the /sns or /fns path to the server endpoint.
  #  use_target_role_suffix=false
  #
  #  # CA certificate (path).
  #  ca_cert=""
  #
  #  # TLS certificate (path).
  #  tls_cert=""
  #
  #  # TLS key (PKCS#8) (path).
  #  tls_key=""
  #
  #  # Authorization header.
  #  #
  #  # Optional value of the Authorization header, e.g. token or password.
  #  authorization_header=""


# Key encryption keys (KEKs).
#
# KEKs can be used to encrypt session-keys between two endpoints,
# for example a Join Server and Network Server, or between two
# Network Servers in case of a roaming agreement. If used, the
# sender will encrypt the session-key with the KEK and indicates
# to the receiver the label of the KEK that was used for encryption,
# such that the receiver is able to decrypt the session-key.
#
# Example (can be repeated):
# [[keks]]
#
#   # KEK label.
#   label="kek-label"

#   # Encryption key.
#   kek="01020304050607080102030405060708"

# UI configuration.
[ui]
  # Tileserver URL.
  #
  # This configures the tileserver used in the UI to display maps.
  # The default value uses the OSM tiles.
  tileserver_url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"

  # Map attribution.
  #
  # This configures the map attribution. The default attribution relates to the
  # default tileserver_url (OSM). If you configure a different tile-server, you
  # might need to update the map_attribution.
  map_attribution="&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"


Example region_eu868.toml configuration


# This file contains an example EU868 configuration.
[[regions]]

  # Name is an user-defined identifier for this region.
  name="eu868"

  # Common-name refers to the common-name of this region as defined by
  # the LoRa Alliance.
  common_name="EU868"


  # Gateway configuration.
  [regions.gateway]

    # Force gateways as private.
    #
    # If enabled, gateways can only be used by devices under the same tenant.
    force_gws_private=false


    # Gateway backend configuration.
    [regions.gateway.backend]

      # The enabled backend type.
      enabled="mqtt"

      # MQTT configuration.
      [regions.gateway.backend.mqtt]

        # Event topic template.
        event_topic="eu868/gateway/+/event/+"

        # Command topic template.
        command_topic="eu868/gateway/{{ gateway_id }}/command/{{ command }}"

        # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
        server="tcp://localhost:1883"

        # Connect with the given username (optional)
        username=""

        # Connect with the given password (optional)
        password=""

        # Quality of service level
        #
        # 0: at most once
        # 1: at least once
        # 2: exactly once
        #
        # Note: an increase of this value will decrease the performance.
        # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
        qos=0

        # Clean session
        #
        # Set the "clean session" flag in the connect message when this client
        # connects to an MQTT broker. By setting this flag you are indicating
        # that no messages saved by the broker for this client should be delivered.
        clean_session=true

        # Client ID
        #
        # Set the client id to be used by this client when connecting to the MQTT
        # broker. A client id must be no longer than 23 characters. When left blank,
        # a random id will be generated. This requires clean_session=true.
        client_id=""

        # CA certificate file (optional)
        #
        # Use this when setting up a secure connection (when server uses ssl://...)
        # but the certificate used by the server is not trusted by any CA certificate
        # on the server (e.g. when self generated).
        ca_cert=""

        # TLS certificate file (optional)
        tls_cert=""

        # TLS key file (optional)
        tls_key=""


    # Gateway channel configuration.
    #
    # Note: this configuration is only used in case the gateway is using the
    # ChirpStack Concentratord daemon. In any other case, this configuration 
    # is ignored.
    [[regions.gateway.channels]]
      frequency=868100000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=868300000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=868500000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=867100000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=867300000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=867500000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=867700000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]

    [[regions.gateway.channels]]
      frequency=867900000
      bandwidth=125000
      modulation="LORA"
      spreading_factors=[7, 8, 9, 10, 11, 12]
  
    [[regions.gateway.channels]]
      frequency=868300000
      bandwidth=250000
      modulation="LORA"
      spreading_factors=[7]
    
    [[regions.gateway.channels]]
      frequency=868800000
      bandwidth=125000
      modulation="FSK"
      datarate=50000


  # Region specific network configuration.
  [regions.network]
    
    # Installation margin (dB) used by the ADR engine.
    #
    # A higher number means that the network-server will keep more margin,
    # resulting in a lower data-rate but decreasing the chance that the
    # device gets disconnected because it is unable to reach one of the
    # surrounded gateways.
    installation_margin=10

    # RX window (Class-A).
    #
    # Set this to:
    # 0: RX1 / RX2
    # 1: RX1 only
    # 2: RX2 only
    rx_window=0

    # RX1 delay (1 - 15 seconds).
    rx1_delay=1

    # RX1 data-rate offset
    rx1_dr_offset=0

    # RX2 data-rate
    rx2_dr=0

    # RX2 frequency (Hz)
    rx2_frequency=869525000

    # Prefer RX2 on RX1 data-rate less than.
    #
    # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
    # is smaller than the configured value, then the Network Server will
    # first try to schedule the downlink for RX2, failing that (e.g. the gateway
    # has already a payload scheduled at the RX2 timing) it will try RX1.
    rx2_prefer_on_rx1_dr_lt=0

    # Prefer RX2 on link budget.
    #
    # When the link-budget is better for RX2 than for RX1, the Network Server will first
    # try to schedule the downlink in RX2, failing that it will try RX1.
    rx2_prefer_on_link_budget=false

    # Downlink TX Power (dBm)
    #
    # When set to -1, the downlink TX Power from the configured band will
    # be used.
    #
    # Please consult the LoRaWAN Regional Parameters and local regulations
    # for valid and legal options. Note that the configured TX Power must be
    # supported by your gateway(s).
    downlink_tx_power=-1

    # ADR is disabled.
    adr_disabled=false

    # Minimum data-rate.
    min_dr=0

    # Maximum data-rate.
    max_dr=5


    # Rejoin-request configuration (LoRaWAN 1.1)
    [regions.network.rejoin_request]

      # Request devices to periodically send rejoin-requests.
      enabled=false

      # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
      # uplink messages. Valid values are 0 to 15.
      max_count_n=0

      # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
      # seconds. Valid values are 0 to 15.
      #
      # 0  = roughly 17 minutes
      # 15 = about 1 year
      max_time_n=0
    

    # Class-B configuration.
    [regions.network.class_b]

      # Ping-slot data-rate. 
      ping_slot_dr=0

      # Ping-slot frequency (Hz)
      #
      # set this to 0 to use the default frequency plan for the configured region
      # (which could be frequency hopping).
      ping_slot_frequency=0


    # Below is the common set of extra channels. Please make sure that these
    # channels are also supported by the gateways.
    [[regions.network.extra_channels]]
    frequency=867100000
    min_dr=0
    max_dr=5

    [[regions.network.extra_channels]]
    frequency=867300000
    min_dr=0
    max_dr=5

    [[regions.network.extra_channels]]
    frequency=867500000
    min_dr=0
    max_dr=5

    [[regions.network.extra_channels]]
    frequency=867700000
    min_dr=0
    max_dr=5

    [[regions.network.extra_channels]]
    frequency=867900000
    min_dr=0
    max_dr=5