# vim: set ft=toml
### Tuwunel Configuration
###
### THIS FILE IS GENERATED. CHANGES/CONTRIBUTIONS IN THE REPO WILL BE
### OVERWRITTEN!
###
### You should rename this file before configuring your server. Changes to
### documentation and defaults can be contributed in source code at
### src/core/config/mod.rs. This file is generated when building.
###
### Any values pre-populated are the default values for said config option.
###
### At the minimum, you MUST edit all the config options to your environment
### that say "YOU NEED TO EDIT THIS".
###
### For more information, see:
### https://tuwunel.chat/configuration.html


[global]

# The server_name is the pretty name of this server. It is used as a
# suffix for user and room IDs/aliases.
#
# See the docs for reverse proxying and delegation:
# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy
#
# Also see the `[global.well_known]` config section at the very bottom.
#
# Examples of delegation:
# - https://matrix.org/.well-known/matrix/server
# - https://matrix.org/.well-known/matrix/client
#
# YOU NEED TO EDIT THIS. THIS CANNOT BE CHANGED AFTER WITHOUT A DATABASE
# WIPE.
#
# example: "girlboss.ceo"
#
server_name = "rustybever.be"

# This is the only directory where tuwunel will save its data, including
# media. Note: this was previously "/var/lib/matrix-conduit".
#
database_path = "{{ tuwunel_data_dir }}"

# Text which will be added to the end of the user's displayname upon
# registration with a space before the text. In Conduit, this was the
# lightning bolt emoji.
#
# To disable, set this to "" (an empty string).
#
new_user_displayname_suffix = ""

# The default address (IPv4 or IPv6) tuwunel will listen on.
#
# If you are using Docker or a container NAT networking setup, this must
# be "0.0.0.0".
#
# To listen on multiple addresses, specify a vector e.g. ["127.0.0.1",
# "::1"]
#
#address = ["127.0.0.1", "::1"]

# The port(s) tuwunel will listen on.
#
# For reverse proxying, see:
# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy
#
# If you are using Docker, don't change this, you'll need to map an
# external port to this.
#
# To listen on multiple ports, specify a vector e.g. [8080, 8448]
#
port = 8025

# The UNIX socket tuwunel will listen on.
#
# Remember to make sure that your reverse proxy has access to this socket
# file, either by adding your reverse proxy to the 'tuwunel' group or
# granting world R/W permissions with `unix_socket_perms` (666 minimum).
#
# example: "/run/tuwunel/tuwunel.sock"
#
#unix_socket_path =

# The default permissions (in octal) to create the UNIX socket with.
#
#unix_socket_perms = 660

# Error on startup if any config option specified is unknown to Tuwunel.
#
# This is false by default to allow easier deprecation or removal of
# config options in the future without breaking existing deployments. The
# default behaviour is to simply warn on startup.
#
#error_on_unknown_config_opts = false

# tuwunel supports online database backups using RocksDB's Backup engine
# API. To use this, set a database backup path that tuwunel can write
# to.
#
# For more information, see:
# https://tuwunel.chat/maintenance.html#backups
#
# example: "/opt/tuwunel-db-backups"
#
#database_backup_path =

# The amount of online RocksDB database backups to keep/retain, if using
# "database_backup_path", before deleting the oldest one.
#
#database_backups_to_keep = 1

# Set this to any float value to multiply tuwunel's in-memory LRU caches
# with such as "auth_chain_cache_capacity".
#
# May be useful if you have significant memory to spare to increase
# performance.
#
# If you have low memory, reducing this may be viable.
#
# By default, the individual caches such as "auth_chain_cache_capacity"
# are scaled by your CPU core count.
#
#cache_capacity_modifier = 1.0

# Set this to any float value in megabytes for tuwunel to tell the
# database engine that this much memory is available for database read
# caches.
#
# May be useful if you have significant memory to spare to increase
# performance.
#
# Similar to the individual LRU caches, this is scaled up with your CPU
# core count.
#
# This defaults to 128.0 + (64.0 * CPU core count).
#
#db_cache_capacity_mb = varies by system

# Set this to any float value in megabytes for tuwunel to tell the
# database engine that this much memory is available for database write
# caches.
#
# May be useful if you have significant memory to spare to increase
# performance.
#
# Similar to the individual LRU caches, this is scaled up with your CPU
# core count.
#
# This defaults to 48.0 + (4.0 * CPU core count).
#
#db_write_buffer_capacity_mb = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#pdu_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#auth_chain_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#shorteventid_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#eventidshort_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#eventid_pdu_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#shortstatekey_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#statekeyshort_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#servernameevent_data_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#stateinfo_cache_capacity = varies by system

# This item is undocumented. Please contribute documentation for it.
#
#roomid_spacehierarchy_cache_capacity = varies by system

# Minimum timeout a client can request for long-polling sync. Requests
# will be clamped up to this value if smaller.
#
#client_sync_timeout_min = 5000

# Default timeout for long-polling sync if a client does not request
# another in their query-string.
#
#client_sync_timeout_default = 30000

# Maximum timeout a client can request for long-polling sync. Requests
# will be clamped down to this value if larger.
#
#client_sync_timeout_max = 90000

# Maximum entries stored in DNS memory-cache. The size of an entry may
# vary so please take care if raising this value excessively. Only
# decrease this when using an external DNS cache. Please note that
# systemd-resolved does *not* count as an external cache, even when
# configured to do so.
#
#dns_cache_entries = 32768

# Minimum time-to-live in seconds for entries in the DNS cache. The
# default may appear high to most administrators; this is by design as the
# exotic loads of federating to many other servers require a higher TTL
# than many domains have set. Even when using an external DNS cache the
# problem is shifted to that cache which is ignorant of its role for
# this application and can adhere to many low TTL's increasing its load.
#
#dns_min_ttl = 10800

# Minimum time-to-live in seconds for NXDOMAIN entries in the DNS cache.
# This value is critical for the server to federate efficiently.
# NXDOMAIN's are assumed to not be returning to the federation and
# aggressively cached rather than constantly rechecked.
#
# Defaults to 3 days as these are *very rarely* false negatives.
#
#dns_min_ttl_nxdomain = 259200

# Number of DNS nameserver retries after a timeout or error.
#
#dns_attempts = 10

# The number of seconds to wait for a reply to a DNS query. Please note
# that recursive queries can take up to several seconds for some domains,
# so this value should not be too low, especially on slower hardware or
# resolvers.
#
#dns_timeout = 10

# Fallback to TCP on DNS errors. Set this to false if unsupported by
# nameserver.
#
#dns_tcp_fallback = true

# Enable to query all nameservers until the domain is found. Referred to
# as "trust_negative_responses" in hickory_resolver. This can avoid
# useless DNS queries if the first nameserver responds with NXDOMAIN or
# an empty NOERROR response.
#
#query_all_nameservers = true

# Enable using *only* TCP for querying your specified nameservers instead
# of UDP.
#
# If you are running tuwunel in a container environment, this config
# option may need to be enabled. For more details, see:
# https://tuwunel.chat/troubleshooting.html#potential-dns-issues-when-using-docker
#
#query_over_tcp_only = false

# DNS A/AAAA record lookup strategy
#
# Takes a number of one of the following options:
# 1 - Ipv4Only (Only query for A records, no AAAA/IPv6)
#
# 2 - Ipv6Only (Only query for AAAA records, no A/IPv4)
#
# 3 - Ipv4AndIpv6 (Query for A and AAAA records in parallel, uses whatever
# returns a successful response first)
#
# 4 - Ipv6thenIpv4 (Query for AAAA record, if that fails then query the A
# record)
#
# 5 - Ipv4thenIpv6 (Query for A record, if that fails then query the AAAA
# record)
#
# If you don't have IPv6 networking, then for better DNS performance it
# may be suitable to set this to Ipv4Only (1) as you will never ever use
# the AAAA record contents even if the AAAA record is successful instead
# of the A record.
#
#ip_lookup_strategy = 5

# List of domain patterns resolved via the alternative path without any
# persistent cache, very small memory cache, and no enforced TTL. This
# is intended for internal network and application services which require
# these specific properties. This path does not support federation or
# general purposes.
#
# example: ["*\.dns\.podman$"]
#
#dns_passthru_domains = []

# Whether to resolve appservices via the alternative path; setting this is
# superior to providing domains in `dns_passthru_domains` if all
# appservices intend to be matched anyway. The overhead of matching regex
# and maintaining the list of domains can be avoided.
#
#dns_passthru_appservices = false

# Enable or disable case randomization for DNS queries. This is a security
# mitigation where answer spoofing is prevented by having to exactly match
# the question. Occasional errors seen in logs which may have lead you
# here tend to be from overloading DNS. Nevertheless for servers which
# are truly incapable this can be set to false.
#
# This currently defaults to false due to user reports regarding some
# popular DNS caches which may or may not be patched soon. It may again
# default to true in an upcoming release.
#
#dns_case_randomization = false

# Max request size for file uploads in bytes.
#
#max_request_size = 24 MiB

# This item is undocumented. Please contribute documentation for it.
#
#max_fetch_prev_events = 192

# Default/base connection timeout (seconds). This is used only by URL
# previews and update/news endpoint checks.
#
#request_conn_timeout = 10

# Default/base request timeout (seconds). The time waiting to receive more
# data from another server. This is used only by URL previews,
# update/news, and misc endpoint checks.
#
#request_timeout = 35

# Default/base request total timeout (seconds). The time limit for a whole
# request. This is set very high to not cancel healthy requests while
# serving as a backstop. This is used only by URL previews and update/news
# endpoint checks.
#
#request_total_timeout = 320

# Default/base idle connection pool timeout (seconds). This is used only
# by URL previews and update/news endpoint checks.
#
#request_idle_timeout = 5

# Default/base max idle connections per host. This is used only by URL
# previews and update/news endpoint checks. Defaults to 1 as generally the
# same open connection can be re-used.
#
#request_idle_per_host = 1

# Federation well-known resolution connection timeout (seconds).
#
#well_known_conn_timeout = 6

# Federation HTTP well-known resolution request timeout (seconds).
#
#well_known_timeout = 10

# Federation client request timeout (seconds). You most definitely want
# this to be high to account for extremely large room joins, slow
# homeservers, your own resources etc.
#
#federation_timeout = 300

# Federation client idle connection pool timeout (seconds).
#
#federation_idle_timeout = 25

# Federation client max idle connections per host. Defaults to 1 as
# generally the same open connection can be re-used.
#
#federation_idle_per_host = 1

# Federation sender request timeout (seconds). The time it takes for the
# remote server to process sent transactions can take a while.
#
#sender_timeout = 180

# Federation sender idle connection pool timeout (seconds).
#
#sender_idle_timeout = 180

# Federation sender transaction retry backoff limit (seconds).
#
#sender_retry_backoff_limit = 86400

# Appservice URL request connection timeout. Defaults to 35 seconds as
# generally appservices are hosted within the same network.
#
#appservice_timeout = 35

# Appservice URL idle connection pool timeout (seconds).
#
#appservice_idle_timeout = 300

# Notification gateway pusher idle connection pool timeout.
#
#pusher_idle_timeout = 15

# Maximum time to receive a request from a client (seconds).
#
#client_receive_timeout = 75

# Maximum time to process a request received from a client (seconds).
#
#client_request_timeout = 240

# Maximum time to transmit a response to a client (seconds)
#
#client_response_timeout = 120

# Grace period for clean shutdown of client requests (seconds).
#
#client_shutdown_timeout = 10

# Grace period for clean shutdown of federation requests (seconds).
#
#sender_shutdown_timeout = 5

# Enables registration. If set to false, no users can register on this
# server.
#
# If set to true without a token configured, users can register with no
# form of 2nd-step only if you set the following option to true:
# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`
#
# If you would like registration only via token reg, please configure
# `registration_token` or `registration_token_file`.
#
allow_registration = true

# Enabling this setting opens registration to anyone without restrictions.
# This makes your server vulnerable to abuse
#
#yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = false

# A static registration token that new users will have to provide when
# creating an account. If unset and `allow_registration` is true,
# you must set
# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`
# to true to allow open registration without any conditions.
#
# YOU NEED TO EDIT THIS OR USE registration_token_file.
#
# example: "o&^uCtes4HPf0Vu@F20jQeeWE7"
#
registration_token = "{{ tuwunel_registration_token }}"

# Path to a file on the system that gets read for additional registration
# tokens. Multiple tokens can be added if you separate them with
# whitespace
#
# tuwunel must be able to access the file, and it must not be empty
#
# example: "/etc/tuwunel/.reg_token"
#
#registration_token_file =

# Controls whether encrypted rooms and events are allowed.
#
#allow_encryption = true

# Controls whether locally-created rooms should be end-to-end encrypted by
# default. This option is equivalent to the one found in Synapse.
#
# Options:
# - "all": All created rooms are encrypted.
# - "invite": Any room created with `private_chat` or
#   `trusted_private_chat` presets.
# - Other values default to no effect.
#
#encryption_enabled_by_default_for_room_type = false

# Controls whether federation is allowed or not. It is not recommended to
# disable this after installation due to potential federation breakage but
# this is technically not a permanent setting.
#
#allow_federation = true

# Sets the default `m.federate` property for newly created rooms when the
# client does not request one. If `allow_federation` is set to false at
# the same this value is set to false it then always overrides the client
# requested `m.federate` value to false.
#
# Rooms are fixed to the setting at the time of their creation and can
# never be changed; changing this value only affects new rooms.
#
#federate_created_rooms = true

# Allows federation requests to be made to itself
#
# This isn't intended and is very likely a bug if federation requests are
# being sent to yourself. This currently mainly exists for development
# purposes.
#
#federation_loopback = false

# Always calls /forget on behalf of the user if leaving a room. This is a
# part of MSC4267 "Automatically forgetting rooms on leave"
#
#forget_forced_upon_leave = false

# Set this to true to require authentication on the normally
# unauthenticated profile retrieval endpoints (GET)
# "/_matrix/client/v3/profile/{userId}".
#
# This can prevent profile scraping.
#
#require_auth_for_profile_requests = false

# Set this to true to allow your server's public room directory to be
# federated. Set this to false to protect against /publicRooms spiders,
# but will forbid external users from viewing your server's public room
# directory. If federation is disabled entirely (`allow_federation`), this
# is inherently false.
#
#allow_public_room_directory_over_federation = false

# Set this to true to allow your server's public room directory to be
# queried without client authentication (access token) through the Client
# APIs. Set this to false to protect against /publicRooms spiders.
#
#allow_public_room_directory_without_auth = false

# Allows room directory searches to match on partial room_id's when the
# search term starts with '!'.
#
#allow_public_room_search_by_id = true

# Set this to false to limit results of rooms when searching by ID to
# those that would be found by an alias or other query; specifically
# those listed in the public rooms directory. By default this is set to
# true allowing any joinable room to match. This satisfies the Principle
# of Least Expectation when pasting a room_id into a search box with
# intent to join; many rooms simply opt-out of public listings. Therefor
# to prevent this feature from abuse, knowledge of several characters of
# the room_id is required before any results are returned.
#
#allow_unlisted_room_search_by_id = true

# Show all local users in user directory. With this set to false, only
# users in public rooms or those that share a room with the user making
# the search will be shown.
#
#show_all_local_users_in_user_directory = false

# Allow guests/unauthenticated users to access TURN credentials.
#
# This is the equivalent of Synapse's `turn_allow_guests` config option.
# This allows any unauthenticated user to call the endpoint
# `/_matrix/client/v3/voip/turnServer`.
#
# It is unlikely you need to enable this as all major clients support
# authentication for this endpoint and prevents misuse of your TURN server
# from potential bots.
#
#turn_allow_guests = false

# Set this to true to lock down your server's public room directory and
# only allow admins to publish rooms to the room directory. Unpublishing
# is still allowed by all users with this enabled.
#
#lockdown_public_room_directory = false

# Set this to true to allow federating device display names / allow
# external users to see your device display name. If federation is
# disabled entirely (`allow_federation`), this is inherently false. For
# privacy reasons, this is best left disabled.
#
#allow_device_name_federation = false

# Config option to allow or disallow incoming federation requests that
# obtain the profiles of our local users from
# `/_matrix/federation/v1/query/profile`
#
# Increases privacy of your local user's such as display names, but some
# remote users may get a false "this user does not exist" error when they
# try to invite you to a DM or room. Also can protect against profile
# spiders.
#
# This is inherently false if `allow_federation` is disabled
#
#allow_inbound_profile_lookup_federation_requests = true

# Allow standard users to create rooms. Appservices and admins are always
# allowed to create rooms
#
#allow_room_creation = true

# Set to false to disable users from joining or creating room versions
# that aren't officially supported by tuwunel. Unstable room versions may
# have flawed specifications or our implementation may be non-conforming.
# Correct operation may not be guaranteed, but incorrect operation may be
# tolerable and unnoticed.
#
# tuwunel officially supports room versions 6+. tuwunel has slightly
# experimental (though works fine in practice) support for versions 3 - 5.
#
#allow_unstable_room_versions = true

# Set to true to enable experimental room versions.
#
# Unlike unstable room versions these versions are either under
# development, protype spec-changes, or somehow present a serious risk to
# the server's operation or database corruption. This is for developer use
# only.
#
#allow_experimental_room_versions = false

# Default room version tuwunel will create rooms with.
#
# The default is prescribed by the spec, but may be selected by developer
# recommendation. To prevent stale documentation we no longer list it
# here. It is only advised to override this if you know what you are
# doing, and by doing so, updates with new versions are precluded.
#
#default_room_version =

# This item is undocumented. Please contribute documentation for it.
#
#allow_jaeger = false

# This item is undocumented. Please contribute documentation for it.
#
#jaeger_filter = "info"

# If the 'perf_measurements' compile-time feature is enabled, enables
# collecting folded stack trace profile of tracing spans using
# tracing_flame. The resulting profile can be visualized with inferno[1],
# speedscope[2], or a number of other tools.
#
# [1]: https://github.com/jonhoo/inferno
# [2]: www.speedscope.app
#
#tracing_flame = false

# This item is undocumented. Please contribute documentation for it.
#
#tracing_flame_filter = "info"

# This item is undocumented. Please contribute documentation for it.
#
#tracing_flame_output_path = "./tracing.folded"

# Examples:
#
# - No proxy (default):
#
#       proxy = "none"
#
# - For global proxy, create the section at the bottom of this file:
#
#       [global.proxy]
#       global = { url = "socks5h://localhost:9050" }
#
# - To proxy some domains:
#
#       [global.proxy]
#       [[global.proxy.by_domain]]
#       url = "socks5h://localhost:9050"
#       include = ["*.onion", "matrix.myspecial.onion"]
#       exclude = ["*.myspecial.onion"]
#
# Include vs. Exclude:
#
# - If include is an empty list, it is assumed to be `["*"]`.
#
# - If a domain matches both the exclude and include list, the proxy will
#   only be used if it was included because of a more specific rule than
#   it was excluded. In the above example, the proxy would be used for
#   `ordinary.onion`, `matrix.myspecial.onion`, but not
#   `hello.myspecial.onion`.
#
#proxy = "none"

# Servers listed here will be used to gather public keys of other servers
# (notary trusted key servers).
#
# Currently, tuwunel doesn't support inbound batched key requests, so
# this list should only contain other Synapse servers.
#
# example: ["matrix.org", "tchncs.de"]
#
#trusted_servers = ["matrix.org"]

# Whether to query the servers listed in trusted_servers first or query
# the origin server first. For best security, querying the origin server
# first is advised to minimize the exposure to a compromised trusted
# server. For maximum federation/join performance this can be set to true,
# however other options exist to query trusted servers first under
# specific high-load circumstances and should be evaluated before setting
# this to true.
#
#query_trusted_key_servers_first = false

# Whether to query the servers listed in trusted_servers first
# specifically on room joins. This option limits the exposure to a
# compromised trusted server to room joins only. The join operation
# requires gathering keys from many origin servers which can cause
# significant delays. Therefor this defaults to true to mitigate
# unexpected delays out-of-the-box. The security-paranoid or those willing
# to tolerate delays are advised to set this to false. Note that setting
# query_trusted_key_servers_first to true causes this option to be
# ignored.
#
#query_trusted_key_servers_first_on_join = true

# Only query trusted servers for keys and never the origin server. This is
# intended for clusters or custom deployments using their trusted_servers
# as forwarding-agents to cache and deduplicate requests. Notary servers
# do not act as forwarding-agents by default, therefor do not enable this
# unless you know exactly what you are doing.
#
#only_query_trusted_key_servers = false

# Maximum number of keys to request in each trusted server batch query.
#
#trusted_server_batch_size = 192

# Maximum number of request batches in flight simultaneously when querying
# a trusted server.
#
#trusted_server_batch_concurrency = 2

# Max log level for tuwunel. Allows debug, info, warn, or error.
#
# See also:
# https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
#
# **Caveat**:
# For release builds, the tracing crate is configured to only implement
# levels higher than error to avoid unnecessary overhead in the compiled
# binary from trace macros. For debug builds, this restriction is not
# applied.
#
#log = "info"

# Output logs with ANSI colours.
#
#log_colors = true

# Sets the log format to compact mode.
#
#log_compact = false

# Configures the span events which will be outputted with the log.
#
#log_span_events = "none"

# Configures whether TUWUNEL_LOG EnvFilter matches values using regular
# expressions. See the tracing_subscriber documentation on Directives.
#
#log_filter_regex = true

# Toggles the display of ThreadId in tracing log output.
#
#log_thread_ids = false

# Redirects logging to standard error (stderr). The default is false for
# stdout. For those using our systemd features the redirection to stderr
# occurs as necessary and setting this option should not be required. We
# offer this option for all other users who desire such redirection.
#
#log_to_stderr = false

# Setting to false disables the logging/tracing system at a lower level.
# In contrast to configuring an empty `log` string where the system is
# still operating but muted, when this option is false the system was not
# initialized and is not operating. Changing this option has no effect
# after startup. This option is intended for developers and expert use
# only: configuring an empty log string is preferred over using this.
#
#log_enable = true

# Setting to false disables the logging/tracing system at a lower level
# similar to `log_enable`. In this case the system is configured normally,
# but not registered as the global handler in the final steps. This option
# is for developers and expert use only.
#
#log_global_default = true

# OpenID token expiration/TTL in seconds.
#
# These are the OpenID tokens that are primarily used for Matrix account
# integrations (e.g. Vector Integrations in Element), *not* OIDC/OpenID
# Connect/etc.
#
#openid_token_ttl = 3600

# Allow an existing session to mint a login token for another client.
# This requires interactive authentication, but has security ramifications
# as a malicious client could use the mechanism to spawn more than one
# session. Enabled by default.
#
#login_via_existing_session = true

# Whether to enable the login token route to accept login tokens at all.
# Login tokens may be generated by the server for authorization flows such
# as SSO; disabling tokens may break such features.
#
# This option is distinct from `login_via_existing_session` and does not
# carry the same security implications; the intent is to leave this
# enabled while disabling the former to prevent clients from commanding
# login token creation but without preventing the server from doing so.
#
#login_via_token = true

# Login token expiration/TTL in milliseconds.
#
# These are short-lived tokens for the m.login.token endpoint.
# This is used to allow existing sessions to create new sessions.
# see login_via_existing_session.
#
#login_token_ttl = 120000

# Access token TTL in seconds.
#
# For clients that support refresh-tokens, the access-token provided on
# login will be invalidated after this amount of time and the client will
# be soft-logged-out until refreshing it.
#
#access_token_ttl = 604800

# Static TURN username to provide the client if not using a shared secret
# ("turn_secret"), It is recommended to use a shared secret over static
# credentials.
#
#turn_username = false

# Static TURN password to provide the client if not using a shared secret
# ("turn_secret"). It is recommended to use a shared secret over static
# credentials.
#
#turn_password = false

# Vector list of TURN URIs/servers to use.
#
# Replace "example.turn.uri" with your TURN domain, such as the coturn
# "realm" config option. If using TURN over TLS, replace the URI prefix
# "turn:" with "turns:".
#
# example: ["turn:example.turn.uri?transport=udp",
# "turn:example.turn.uri?transport=tcp"]
#
#turn_uris = []

# TURN secret to use for generating the HMAC-SHA1 hash apart of username
# and password generation.
#
# This is more secure, but if needed you can use traditional static
# username/password credentials.
#
#turn_secret = false

# TURN secret to use that's read from the file path specified.
#
# This takes priority over "turn_secret" first, and falls back to
# "turn_secret" if invalid or failed to open.
#
# example: "/etc/tuwunel/.turn_secret"
#
#turn_secret_file =

# TURN TTL, in seconds.
#
#turn_ttl = 86400

# List/vector of room IDs or room aliases that tuwunel will make newly
# registered users join. The rooms specified must be rooms that you have
# joined at least once on the server, and must be public.
#
# example: ["#tuwunel:tuwunel.chat",
# "!eoIzvAvVwY23LPDay8:tuwunel.chat"]
#
#auto_join_rooms = []

# Config option to automatically deactivate the account of any user who
# attempts to join a:
# - banned room
# - forbidden room alias
# - room alias or ID with a forbidden server name
#
# This may be useful if all your banned lists consist of toxic rooms or
# servers that no good faith user would ever attempt to join, and
# to automatically remediate the problem without any admin user
# intervention.
#
# This will also make the user leave all rooms. Federation (e.g. remote
# room invites) are ignored here.
#
# Defaults to false as rooms can be banned for non-moderation-related
# reasons and this performs a full user deactivation.
#
#auto_deactivate_banned_room_attempts = false

# RocksDB log level. This is not the same as tuwunel's log level. This
# is the log level for the RocksDB engine/library which show up in your
# database folder/path as `LOG` files. tuwunel will log RocksDB errors
# as normal through tracing or panics if severe for safety.
#
#rocksdb_log_level = "error"

# This item is undocumented. Please contribute documentation for it.
#
#rocksdb_log_stderr = false

# Max RocksDB `LOG` file size before rotating in bytes. Defaults to 4MB in
# bytes.
#
#rocksdb_max_log_file_size = 4194304

# Time in seconds before RocksDB will forcibly rotate logs.
#
#rocksdb_log_time_to_roll = 0

# Set this to true to use RocksDB config options that are tailored to HDDs
# (slower device storage).
#
# It is worth noting that by default, tuwunel will use RocksDB with
# Direct IO enabled. *Generally* speaking this improves performance as it
# bypasses buffered I/O (system page cache). However there is a potential
# chance that Direct IO may cause issues with database operations if your
# setup is uncommon. This has been observed with FUSE filesystems, and
# possibly ZFS filesystem. RocksDB generally deals/corrects these issues
# but it cannot account for all setups. If you experience any weird
# RocksDB issues, try enabling this option as it turns off Direct IO and
# feel free to report in the tuwunel Matrix room if this option fixes
# your DB issues.
#
# For more information, see:
# https://github.com/facebook/rocksdb/wiki/Direct-IO
#
#rocksdb_optimize_for_spinning_disks = false

# Enables direct-io to increase database performance via unbuffered I/O.
#
# For more details about direct I/O and RockDB, see:
# https://github.com/facebook/rocksdb/wiki/Direct-IO
#
# Set this option to false if the database resides on a filesystem which
# does not support direct-io like FUSE, or any form of complex filesystem
# setup such as possibly ZFS.
#
#rocksdb_direct_io = true

# Amount of threads that RocksDB will use for parallelism on database
# operations such as cleanup, sync, flush, compaction, etc. Set to 0 to
# use all your logical threads. Defaults to your CPU logical thread count.
#
#rocksdb_parallelism_threads = varies by system

# Maximum number of LOG files RocksDB will keep. This must *not* be set to
# 0. It must be at least 1. Defaults to 3 as these are not very useful
# unless troubleshooting/debugging a RocksDB bug.
#
#rocksdb_max_log_files = 3

# Type of RocksDB database compression to use.
#
# Available options are "zstd", "bz2", "lz4", or "none".
#
# It is best to use ZSTD as an overall good balance between
# speed/performance, storage, IO amplification, and CPU usage. For more
# performance but less compression (more storage used) and less CPU usage,
# use LZ4.
#
# For more details, see:
# https://github.com/facebook/rocksdb/wiki/Compression
#
# "none" will disable compression.
#
#rocksdb_compression_algo = "zstd"

# Level of compression the specified compression algorithm for RocksDB to
# use.
#
# Default is 32767, which is internally read by RocksDB as the default
# magic number and translated to the library's default compression level
# as they all differ. See their `kDefaultCompressionLevel`.
#
# Note when using the default value we may override it with a setting
# tailored specifically tuwunel.
#
#rocksdb_compression_level = 32767

# Level of compression the specified compression algorithm for the
# bottommost level/data for RocksDB to use. Default is 32767, which is
# internally read by RocksDB as the default magic number and translated to
# the library's default compression level as they all differ. See their
# `kDefaultCompressionLevel`.
#
# Since this is the bottommost level (generally old and least used data),
# it may be desirable to have a very high compression level here as it's
# less likely for this data to be used. Research your chosen compression
# algorithm.
#
# Note when using the default value we may override it with a setting
# tailored specifically tuwunel.
#
#rocksdb_bottommost_compression_level = 32767

# Whether to enable RocksDB's "bottommost_compression".
#
# At the expense of more CPU usage, this will further compress the
# database to reduce more storage. It is recommended to use ZSTD
# compression with this for best compression results. This may be useful
# if you're trying to reduce storage usage from the database.
#
# See https://github.com/facebook/rocksdb/wiki/Compression for more details.
#
#rocksdb_bottommost_compression = true

# Database recovery mode (for RocksDB WAL corruption).
#
# Use this option when the server reports corruption and refuses to start.
# Set mode 2 (PointInTime) to cleanly recover from this corruption. The
# server will continue from the last good state, several seconds or
# minutes prior to the crash. Clients may have to run "clear-cache &
# reload" to account for the rollback. Upon success, you may reset the
# mode back to default and restart again. Please note in some cases the
# corruption error may not be cleared for at least 30 minutes of operation
# in PointInTime mode.
#
# As a very last ditch effort, if PointInTime does not fix or resolve
# anything, you can try mode 3 (SkipAnyCorruptedRecord) but this will
# leave the server in a potentially inconsistent state.
#
# The default mode 1 (TolerateCorruptedTailRecords) will automatically
# drop the last entry in the database if corrupted during shutdown, but
# nothing more. It is extraordinarily unlikely this will desynchronize
# clients. To disable any form of silent rollback set mode 0
# (AbsoluteConsistency).
#
# The options are:
# 0 = AbsoluteConsistency
# 1 = TolerateCorruptedTailRecords (default)
# 2 = PointInTime (use me if trying to recover)
# 3 = SkipAnyCorruptedRecord (you now voided your tuwunel warranty)
#
# For more information on these modes, see:
# https://github.com/facebook/rocksdb/wiki/WAL-Recovery-Modes
#
# For more details on recovering a corrupt database, see:
# https://tuwunel.chat/troubleshooting.html#database-corruption
#
#rocksdb_recovery_mode = 1

# Enables or disables paranoid SST file checks. This can improve RocksDB
# database consistency at a potential performance impact due to further
# safety checks ran.
#
# For more information, see:
# https://github.com/facebook/rocksdb/wiki/Online-Verification#columnfamilyoptionsparanoid_file_checks
#
#rocksdb_paranoid_file_checks = false

# Enables or disables checksum verification in rocksdb at runtime.
# Checksums are usually hardware accelerated with low overhead; they are
# enabled in rocksdb by default. Older or slower platforms may see gains
# from disabling.
#
#rocksdb_checksums = true

# Enables the "atomic flush" mode in rocksdb. This option is not intended
# for users. It may be removed or ignored in future versions. Atomic flush
# may be enabled by the paranoid to possibly improve database integrity at
# the cost of performance.
#
#rocksdb_atomic_flush = false

# Database repair mode (for RocksDB SST corruption).
#
# Use this option when the server reports corruption while running or
# panics. If the server refuses to start use the recovery mode options
# first. Corruption errors containing the acronym 'SST' which occur after
# startup will likely require this option.
#
# - Backing up your database directory is recommended prior to running the
#   repair.
#
# - Disabling repair mode and restarting the server is recommended after
#   running the repair.
#
# See https://tuwunel.chat/troubleshooting.html#database-corruption for more details on recovering a corrupt database.
#
#rocksdb_repair = false

# This item is undocumented. Please contribute documentation for it.
#
#rocksdb_read_only = false

# This item is undocumented. Please contribute documentation for it.
#
#rocksdb_secondary = false

# Enables idle CPU priority for compaction thread. This is not enabled by
# default to prevent compaction from falling too far behind on busy
# systems.
#
#rocksdb_compaction_prio_idle = false

# Enables idle IO priority for compaction thread. This prevents any
# unexpected lag in the server's operation and is usually a good idea.
# Enabled by default.
#
#rocksdb_compaction_ioprio_idle = true

# Enables RocksDB compaction. You should never ever have to set this
# option to false. If you for some reason find yourself needing to use
# this option as part of troubleshooting or a bug, please reach out to us
# in the tuwunel Matrix room with information and details.
#
# Disabling compaction will lead to a significantly bloated and
# explosively large database, gradually poor performance, unnecessarily
# excessive disk read/writes, and slower shutdowns and startups.
#
#rocksdb_compaction = true

# Level of statistics collection. Some admin commands to display database
# statistics may require this option to be set. Database performance may
# be impacted by higher settings.
#
# Option is a number ranging from 0 to 6:
# 0 = No statistics.
# 1 = No statistics in release mode (default).
# 2 to 3 = Statistics with no performance impact.
# 3 to 5 = Statistics with possible performance impact.
# 6 = All statistics.
#
#rocksdb_stats_level = 1

# Ignores the list of dropped columns set by developers.
#
# This should be set to true when knowingly moving between versions in
# ways which are not recommended or otherwise forbidden, or for
# diagnostic and development purposes; requiring preservation across such
# movements.
#
# The developer's list of dropped columns is meant to safely reduce space
# by erasing data no longer in use. If this is set to true that storage
# will not be reclaimed as intended.
#
#rocksdb_never_drop_columns = false

# Configures RocksDB to not preallocate WAL logs.
#
# Normally, RocksDB allocates certain types of files by calling
# fallocate, writing the file contents, then truncating the logs to the
# proper size. This causes pathological disk space usage on btrfs due
# how it interacts with its Copy-on-Write implementation.
#
# It is recommended to set this to false if you run the server on btrfs,
# and not touch it otherwise.
#
#rocksdb_allow_fallocate = true

# This is a password that can be configured that will let you login to the
# server bot account (currently `@conduit`) for emergency troubleshooting
# purposes such as recovering/recreating your admin room, or inviting
# yourself back.
#
# See https://tuwunel.chat/troubleshooting.html#lost-access-to-admin-room
# for other ways to get back into your admin room.
#
# Once this password is unset, all sessions will be logged out for
# security purposes.
#
# example: "F670$2CP@Hw8mG7RY1$%!#Ic7YA"
#
#emergency_password =

# This item is undocumented. Please contribute documentation for it.
#
#notification_push_path = "/_matrix/push/v1/notify"

# For compatibility and special purpose use only. Setting this option to
# true will not filter messages sent to pushers based on rules or actions.
# Everything will be sent to the pusher. This option is offered for
# several reasons, but should not be necessary:
# - Bypass to workaround bugs or outdated server-side ruleset support.
# - Allow clients to evaluate pushrules themselves (due to the above).
# - Hosting or companies which have custom pushers and internal needs.
#
# Note that setting this option to true will not affect the record of
# notifications found in the notifications pane.
#
#push_everything = false

# Setting to false disables the heroes calculation made by sliding and
# legacy client sync. The heroes calculation is mandated by the Matrix
# specification and your client may not operate properly unless this
# option is set to true.
#
# This option is intended for custom software deployments seeking purely
# to minimize unused resources; the overall savings are otherwise
# negligible.
#
#calculate_heroes = true

# Allow local (your server only) presence updates/requests.
#
# Note that presence on tuwunel is very fast unlike Synapse's. If using
# outgoing presence, this MUST be enabled.
#
#allow_local_presence = true

# Allow incoming federated presence updates/requests.
#
# This option receives presence updates from other servers, but does not
# send any unless `allow_outgoing_presence` is true. Note that presence on
# tuwunel is very fast unlike Synapse's.
#
#allow_incoming_presence = true

# Allow outgoing presence updates/requests.
#
# This option sends presence updates to other servers, but does not
# receive any unless `allow_incoming_presence` is true. Note that presence
# on tuwunel is very fast unlike Synapse's. If using outgoing presence,
# you MUST enable `allow_local_presence` as well.
#
#allow_outgoing_presence = true

# How many seconds without presence updates before you become idle.
# Defaults to 5 minutes.
#
#presence_idle_timeout_s = 300

# How many seconds without presence updates before you become offline.
# Defaults to 30 minutes.
#
#presence_offline_timeout_s = 1800

# Enable the presence idle timer for remote users.
#
# Disabling is offered as an optimization for servers participating in
# many large rooms or when resources are limited. Disabling it may cause
# incorrect presence states (i.e. stuck online) to be seen for some remote
# users.
#
#presence_timeout_remote_users = true

# Suppresses push notifications for users marked as active. (Experimental)
#
# When enabled, users with `Online` presence and recent activity
# (based on presence state and sync activity) won’t receive push
# notifications, reducing duplicate alerts while they're active
# on another client.
#
# Disabled by default to preserve legacy behavior.
#
#suppress_push_when_active = false

# Allow receiving incoming read receipts from remote servers.
#
#allow_incoming_read_receipts = true

# Allow sending read receipts to remote servers.
#
#allow_outgoing_read_receipts = true

# Allow outgoing typing updates to federation.
#
#allow_outgoing_typing = true

# Allow incoming typing updates from federation.
#
#allow_incoming_typing = true

# Maximum time federation user can indicate typing.
#
#typing_federation_timeout_s = 30

# Minimum time local client can indicate typing. This does not override a
# client's request to stop typing. It only enforces a minimum value in
# case of no stop request.
#
#typing_client_timeout_min_s = 15

# Maximum time local client can indicate typing.
#
#typing_client_timeout_max_s = 45

# Set this to true for tuwunel to compress HTTP response bodies using
# zstd. This option does nothing if tuwunel was not built with
# `zstd_compression` feature. Please be aware that enabling HTTP
# compression may weaken TLS. Most users should not need to enable this.
# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH
# before deciding to enable this.
#
#zstd_compression = false

# Set this to true for tuwunel to compress HTTP response bodies using
# gzip. This option does nothing if tuwunel was not built with
# `gzip_compression` feature. Please be aware that enabling HTTP
# compression may weaken TLS. Most users should not need to enable this.
# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH before
# deciding to enable this.
#
# If you are in a large amount of rooms, you may find that enabling this
# is necessary to reduce the significantly large response bodies.
#
#gzip_compression = false

# Set this to true for tuwunel to compress HTTP response bodies using
# brotli. This option does nothing if tuwunel was not built with
# `brotli_compression` feature. Please be aware that enabling HTTP
# compression may weaken TLS. Most users should not need to enable this.
# See https://breachattack.com/ and https://wikipedia.org/wiki/BREACH
# before deciding to enable this.
#
#brotli_compression = false

# Set to true to allow user type "guest" registrations. Some clients like
# Element attempt to register guest users automatically.
#
#allow_guest_registration = false

# Set to true to log guest registrations in the admin room. Note that
# these may be noisy or unnecessary if you're a public homeserver.
#
#log_guest_registrations = false

# Set to true to allow guest registrations/users to auto join any rooms
# specified in `auto_join_rooms`.
#
#allow_guests_auto_join_rooms = false

# Enable the legacy unauthenticated Matrix media repository endpoints.
# These endpoints consist of:
# - /_matrix/media/*/config
# - /_matrix/media/*/upload
# - /_matrix/media/*/preview_url
# - /_matrix/media/*/download/*
# - /_matrix/media/*/thumbnail/*
#
# The authenticated equivalent endpoints are always enabled.
#
# Defaults to false.
#
#allow_legacy_media = false

# Fallback to requesting legacy unauthenticated media from remote servers.
# Unauthenticated media was removed in ~2024Q3; enabling this adds
# considerable federation requests which are unlikely to succeed.
#
#request_legacy_media = false

# This item is undocumented. Please contribute documentation for it.
#
#freeze_legacy_media = true

# Check consistency of the media directory at startup:
# 1. When `media_compat_file_link` is enabled, this check will upgrade
#    media when switching back and forth between Conduit and tuwunel. Both
#    options must be enabled to handle this.
# 2. When media is deleted from the directory, this check will also delete
#    its database entry.
#
# If none of these checks apply to your use cases, and your media
# directory is significantly large setting this to false may reduce
# startup time.
#
#media_startup_check = true

# Enable backward-compatibility with Conduit's media directory by creating
# symlinks of media.
#
# This option is only necessary if you plan on using Conduit again.
# Otherwise setting this to false reduces filesystem clutter and overhead
# for managing these symlinks in the directory. This is now disabled by
# default. You may still return to upstream Conduit but you have to run
# tuwunel at least once with this set to true and allow the
# media_startup_check to take place before shutting down to return to
# Conduit.
#
#media_compat_file_link = false

# Prune missing media from the database as part of the media startup
# checks.
#
# This means if you delete files from the media directory the
# corresponding entries will be removed from the database. This is
# disabled by default because if the media directory is accidentally moved
# or inaccessible, the metadata entries in the database will be lost with
# sadness.
#
#prune_missing_media = false

# Vector list of regex patterns of server names that tuwunel will refuse
# to download remote media from.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#prevent_media_downloads_from = []

# List of forbidden server names via regex patterns that we will block
# incoming AND outgoing federation with, and block client room joins /
# remote user invites.
#
# This check is applied on the room ID, room alias, sender server name,
# sender user's server name, inbound federation X-Matrix origin, and
# outbound federation handler.
#
# Basically "global" ACLs.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#forbidden_remote_server_names = []

# List of forbidden server names via regex patterns that we will block all
# outgoing federated room directory requests for. Useful for preventing
# our users from wandering into bad servers or spaces.
#
# example: ["badserver\.tld$", "badphrase", "19dollarfortnitecards"]
#
#forbidden_remote_room_directory_server_names = []

# Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you
# do not want tuwunel to send outbound requests to. Defaults to
# RFC1918, unroutable, loopback, multicast, and testnet addresses for
# security.
#
# Please be aware that this is *not* a guarantee. You should be using a
# firewall with zones as doing this on the application layer may have
# bypasses.
#
# Currently this does not account for proxies in use like Synapse does.
#
# To disable, set this to be an empty vector (`[]`).
#
# Defaults to:
# ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12",
# "192.168.0.0/16", "100.64.0.0/10", "192.0.0.0/24", "169.254.0.0/16",
# "192.88.99.0/24", "198.18.0.0/15", "192.0.2.0/24", "198.51.100.0/24",
# "203.0.113.0/24", "224.0.0.0/4", "::1/128", "fe80::/10", "fc00::/7",
# "2001:db8::/32", "ff00::/8", "fec0::/10"]
#
#ip_range_denylist =

# Optional IP address or network interface-name to bind as the source of
# URL preview requests. If not set, it will not bind to a specific
# address or interface.
#
# Interface names only supported on Linux, Android, and Fuchsia platforms;
# all other platforms can specify the IP address. To list the interfaces
# on your system, use the command `ip link show`.
#
# example: `"eth0"` or `"1.2.3.4"`
#
#url_preview_bound_interface =

# Vector list of domains allowed to send requests to for URL previews.
#
# This is a *contains* match, not an explicit match. Putting "google.com"
# will match "https://google.com" and
# "http://mymaliciousdomainexamplegoogle.com" Setting this to "*" will
# allow all URL previews. Please note that this opens up significant
# attack surface to your server, you are expected to be aware of the risks
# by doing so.
#
#url_preview_domain_contains_allowlist = []

# Vector list of explicit domains allowed to send requests to for URL
# previews.
#
# This is an *explicit* match, not a contains match. Putting "google.com"
# will match "https://google.com", "http://google.com", but not
# "https://mymaliciousdomainexamplegoogle.com". Setting this to "*" will
# allow all URL previews. Please note that this opens up significant
# attack surface to your server, you are expected to be aware of the risks
# by doing so.
#
#url_preview_domain_explicit_allowlist = []

# Vector list of explicit domains not allowed to send requests to for URL
# previews.
#
# This is an *explicit* match, not a contains match. Putting "google.com"
# will match "https://google.com", "http://google.com", but not
# "https://mymaliciousdomainexamplegoogle.com". The denylist is checked
# first before allowlist. Setting this to "*" will not do anything.
#
#url_preview_domain_explicit_denylist = []

# Vector list of URLs allowed to send requests to for URL previews.
#
# Note that this is a *contains* match, not an explicit match. Putting
# "google.com" will match "https://google.com/",
# "https://google.com/url?q=https://mymaliciousdomainexample.com", and
# "https://mymaliciousdomainexample.com/hi/google.com" Setting this to "*"
# will allow all URL previews. Please note that this opens up significant
# attack surface to your server, you are expected to be aware of the risks
# by doing so.
#
#url_preview_url_contains_allowlist = []

# Maximum amount of bytes allowed in a URL preview body size when
# spidering. Defaults to 256KB in bytes.
#
#url_preview_max_spider_size = 256000

# Option to decide whether you would like to run the domain allowlist
# checks (contains and explicit) on the root domain or not. Does not apply
# to URL contains allowlist. Defaults to false.
#
# Example usecase: If this is enabled and you have "wikipedia.org" allowed
# in the explicit and/or contains domain allowlist, it will allow all
# subdomains under "wikipedia.org" such as "en.m.wikipedia.org" as the
# root domain is checked and matched. Useful if the domain contains
# allowlist is still too broad for you but you still want to allow all the
# subdomains under a root domain.
#
#url_preview_check_root_domain = false

# List of forbidden room aliases and room IDs as strings of regex
# patterns.
#
# Regex can be used or explicit contains matches can be done by just
# specifying the words (see example).
#
# This is checked upon room alias creation, custom room ID creation if
# used, and startup as warnings if any room aliases in your database have
# a forbidden room alias/ID.
#
# example: ["19dollarfortnitecards", "b[4a]droom", "badphrase"]
#
#forbidden_alias_names = []

# List of forbidden username patterns/strings.
#
# Regex can be used or explicit contains matches can be done by just
# specifying the words (see example).
#
# This is checked upon username availability check, registration, and
# startup as warnings if any local users in your database have a forbidden
# username.
#
# example: ["administrator", "b[a4]dusernam[3e]", "badphrase"]
#
#forbidden_usernames = []

# List of server names to deprioritize joining through.
#
# If a client requests a join through one of these servers,
# they will be tried last.
#
# Useful for preventing failed joins due to timeouts
# from a certain homeserver.
#
#deprioritize_joins_through_servers = ["matrix\.org"]

# Maximum make_join requests to attempt within each join attempt. Each
# attempt tries a different server, as each server is only tried once;
# though retries can occur when the join request as a whole is retried.
#
#max_make_join_attempts_per_join_attempt = 48

# Maximum join attempts to conduct per client join request. Each join
# attempt consists of one or more make_join requests limited above, and a
# single send_join request. This value allows for additional servers to
# act as the join-server prior to reporting the last error back to the
# client, which can be frustrating for users. Therefor the default value
# is greater than one, but less than excessively exceeding the client's
# request timeout, though that may not be avoidable in some cases.
#
#max_join_attempts_per_join_request = 3

# Retry failed and incomplete messages to remote servers immediately upon
# startup. This is called bursting. If this is disabled, said messages may
# not be delivered until more messages are queued for that server. Do not
# change this option unless server resources are extremely limited or the
# scale of the server's deployment is huge. Do not disable this unless you
# know what you are doing.
#
#startup_netburst = true

# Messages are dropped and not reattempted. The `startup_netburst` option
# must be enabled for this value to have any effect. Do not change this
# value unless you know what you are doing. Set this value to -1 to
# reattempt every message without trimming the queues; this may consume
# significant disk. Set this value to 0 to drop all messages without any
# attempt at redelivery.
#
#startup_netburst_keep = 50

# Block non-admin local users from sending room invites (local and
# remote), and block non-admin users from receiving remote room invites.
#
# Admins are always allowed to send and receive all room invites.
#
#block_non_admin_invites = false

# Allow admins to enter commands in rooms other than "#admins" (admin
# room) by prefixing your message with "\!admin" or "\\!admin" followed up
# a normal tuwunel admin command. The reply will be publicly visible to
# the room, originating from the sender.
#
# example: \\!admin debug ping puppygock.gay
#
#admin_escape_commands = true

# Automatically activate the tuwunel admin room console / CLI on
# startup. This option can also be enabled with `--console` tuwunel
# argument.
#
#admin_console_automatic = false

# List of admin commands to execute on startup.
#
# This option can also be configured with the `--execute` tuwunel
# argument and can take standard shell commands and environment variables
#
# For example: `./tuwunel --execute "server admin-notice tuwunel has
# started up at $(date)"`
#
# example: admin_execute = ["debug ping puppygock.gay", "debug echo hi"]`
#
#admin_execute = []

# Ignore errors in startup commands.
#
# If false, tuwunel will error and fail to start if an admin execute
# command (`--execute` / `admin_execute`) fails.
#
#admin_execute_errors_ignore = false

# List of admin commands to execute on SIGUSR2.
#
# Similar to admin_execute, but these commands are executed when the
# server receives SIGUSR2 on supporting platforms.
#
#admin_signal_execute = []

# Controls the max log level for admin command log captures (logs
# generated from running admin commands). Defaults to "info" on release
# builds, else "debug" on debug builds.
#
#admin_log_capture = "info"

# The default room tag to apply on the admin room.
#
# On some clients like Element, the room tag "m.server_notice" is a
# special pinned room at the very bottom of your room list. The tuwunel
# admin room can be pinned here so you always have an easy-to-access
# shortcut dedicated to your admin room.
#
#admin_room_tag = "m.server_notice"

# Whether to grant the first user to register admin privileges by joining
# them to the admin room. Note that technically the next user to register
# when the admin room is empty (or only contains the server-user) is
# granted, and only when the admin room is enabled.
#
#grant_admin_to_first_user = true

# Whether the admin room is created on first startup. Users should not set
# this to false. Developers can set this to false during integration tests
# to reduce activity and output.
#
#create_admin_room = true

# Whether to enable federation on the admin room. This cannot be changed
# after the admin room is created.
#
#federate_admin_room = true

# Sentry.io crash/panic reporting, performance monitoring/metrics, etc.
# This is NOT enabled by default. tuwunel's default Sentry reporting
# endpoint domain is `o4509498990067712.ingest.us.sentry.io`.
#
#sentry = false

# Sentry reporting URL, if a custom one is desired.
#
#sentry_endpoint = ""

# Report your tuwunel server_name in Sentry.io crash reports and
# metrics.
#
#sentry_send_server_name = false

# Performance monitoring/tracing sample rate for Sentry.io.
#
# Note that too high values may impact performance, and can be disabled by
# setting it to 0.0 (0%) This value is read as a percentage to Sentry,
# represented as a decimal. Defaults to 15% of traces (0.15)
#
#sentry_traces_sample_rate = 0.15

# Whether to attach a stacktrace to Sentry reports.
#
#sentry_attach_stacktrace = false

# Send panics to Sentry. This is true by default, but Sentry has to be
# enabled. The global `sentry` config option must be enabled to send any
# data.
#
#sentry_send_panic = true

# Send errors to sentry. This is true by default, but sentry has to be
# enabled. This option is only effective in release-mode; forced to false
# in debug-mode.
#
#sentry_send_error = true

# Controls the tracing log level for Sentry to send things like
# breadcrumbs and transactions
#
#sentry_filter = "info"

# Enable the tokio-console. This option is only relevant to developers.
#
#	For more information, see:
# https://tuwunel.chat/development.html#debugging-with-tokio-console
#
#tokio_console = false

# Arbitrary argument vector for integration testing. Functionality in the
# server is altered or informed for the requirements of integration tests.
# - "smoke" performs a shutdown after startup admin commands rather than
#   hanging on client handling.
#
#test = []

# Controls whether admin room notices like account registrations, password
# changes, account deactivations, room directory publications, etc will be
# sent to the admin room. Update notices and normal admin command
# responses will still be sent.
#
#admin_room_notices = true

# Save original events before applying redaction to them.
#
# They can be retrieved with `admin debug get-retained-pdu` or MSC2815.
#
#save_unredacted_events = true

# Redaction retention period in seconds.
#
# By default the unredacted events are stored for 60 days.
#
#redaction_retention_seconds = 5184000

# Allows users with `redact` power level to request unredacted events with
# MSC2815.
#
# Server admins can request unredacted events regardless of the value of
# this option.
#
#allow_room_admins_to_request_unredacted_events = true

# Prevents local users from sending redactions.
#
# This check does not apply to server admins.
#
#disable_local_redactions = false

# Enable database pool affinity support. On supporting systems, block
# device queue topologies are detected and the request pool is optimized
# for the hardware; db_pool_workers is determined automatically.
#
#db_pool_affinity = true

# Sets the number of worker threads in the frontend-pool of the database.
# This number should reflect the I/O capabilities of the system,
# such as the queue-depth or the number of simultaneous requests in
# flight. Defaults to 32 times the number of CPU cores.
#
# Note: This value is only used if db_pool_affinity is disabled or not
# detected on the system, otherwise it is determined automatically.
#
#db_pool_workers = 32

# When db_pool_affinity is enabled and detected, the size of any worker
# group will not exceed the determined value. This is necessary when
# thread-pooling approach does not scale to the full capabilities of
# high-end hardware; using detected values without limitation could
# degrade performance.
#
# The value is multiplied by the number of cores which share a device
# queue, since group workers can be scheduled on any of those cores.
#
#db_pool_workers_limit = 64

# Limits the total number of workers across all worker groups. When the
# sum of all groups exceeds this value the worker counts are reduced until
# this constraint is satisfied.
#
# By default this value is only effective on larger systems (e.g. 16+
# cores) where it will tamper the overall thread-count. The thread-pool
# model will never achieve hardware capacity but this value can be raised
# on huge systems if the scheduling overhead is determined to not
# bottleneck and the worker groups are divided too small.
#
#db_pool_max_workers = 2048

# Determines the size of the queues feeding the database's frontend-pool.
# The size of the queue is determined by multiplying this value with the
# number of pool workers. When this queue is full, tokio tasks conducting
# requests will yield until space is available; this is good for
# flow-control by avoiding buffer-bloat, but can inhibit throughput if
# too low.
#
#db_pool_queue_mult = 4

# Sets the initial value for the concurrency of streams. This value simply
# allows overriding the default in the code. The default is 32, which is
# the same as the default in the code. Note this value is itself
# overridden by the computed stream_width_scale, unless that is disabled;
# this value can serve as a fixed-width instead.
#
#stream_width_default = 32

# Scales the stream width starting from a base value detected for the
# specific system. The base value is the database pool worker count
# determined from the hardware queue size (e.g. 32 for SSD or 64 or 128+
# for NVMe). This float allows scaling the width up or down by multiplying
# it (e.g. 1.5, 2.0, etc). The maximum result can be the size of the pool
# queue (see: db_pool_queue_mult) as any larger value will stall the tokio
# task. The value can also be scaled down (e.g. 0.5)  to improve
# responsiveness for many users at the cost of throughput for each.
#
# Setting this value to 0.0 causes the stream width to be fixed at the
# value of stream_width_default. The default scale is 1.0 to match the
# capabilities detected for the system.
#
#stream_width_scale = 1.0

# Sets the initial amplification factor. This controls batch sizes of
# requests made by each pool worker, multiplying the throughput of each
# stream. This value is somewhat abstract from specific hardware
# characteristics and can be significantly larger than any thread count or
# queue size. This is because each database query may require several
# index lookups, thus many database queries in a batch may make progress
# independently while also sharing index and data blocks which may or may
# not be cached. It is worthwhile to submit huge batches to reduce
# complexity. The maximum value is 32768, though sufficient hardware is
# still advised for that.
#
#stream_amplification = 1024

# Number of sender task workers; determines sender parallelism. Default is
# '0' which means the value is determined internally, likely matching the
# number of tokio worker-threads or number of cores, etc. Override by
# setting a non-zero value.
#
#sender_workers = 0

# Enables listener sockets; can be set to false to disable listening. This
# option is intended for developer/diagnostic purposes only.
#
#listening = true

# Enables configuration reload when the server receives SIGUSR1 on
# supporting platforms.
#
#config_reload_signal = true

# Sets the `Access-Control-Allow-Origin` header included by this server in
# all responses. A list of multiple values can be specified. The default
# is an empty list. The actual header defaults to `*` upon an empty list.
#
# There is no reason to configure this without specific intent. Incorrect
# values may degrade or disrupt clients.
#
#access_control_allow_origin = []

# Backport state-reset security fixes to all room versions.
#
# This option applies the State Resolution 2.1 mitigation developed during
# project Hydra for room version 12 to all prior State Resolution 2.0 room
# versions (all room versions supported by this server). These mitigations
# increase resilience to state-resets without any new definition of
# correctness; therefor it is safe to set this to true for existing rooms.
#
# Furthermore, state-reset attacks are not consistent as they result in
# rooms without any single consensus, therefor it is unnecessary to set
# this to false to match other servers which set this to false or simply
# lack support; even if replicating the post-reset state suffered by other
# servers is somehow desired.
#
# This option exists for developer and debug use, and as a failsafe in
# lieu of hardcoding it.
#
#hydra_backports = true

# Delete rooms when the last user from this server leaves. This feature is
# experimental and for the purpose of least-surprise is not enabled by
# default but can be enabled for deployments interested in conserving
# space. It may eventually default to true in a future release.
#
# Note that not all pathways which can remove the last local user
# currently invoke this operation, so in some cases you may find the room
# still exists.
#
#delete_rooms_after_leave = false

# Limits the number of One Time Keys per device (not per-algorithm). The
# reference implementation maintains 50 OTK's at any given time, therefor
# our default is at least five times that. There is no known reason for an
# administrator to adjust this value; it is provided here rather than
# hardcoding it.
#
#one_time_key_limit = 256

# (EXPERIMENTAL) Setting this option to true replaces the list of identity
# providers displayed on a client's login page with a single button "Sign
# in with single sign-on" linking to the URL
# `/_matrix/client/v3/login/sso/redirect`. All configured providers are
# attempted for authorization. All authorizations associate with the same
# Matrix user. NOTE: All authorizations must succeed, as there is no
# reliable way to skip a provider.
#
# This option is disabled by default, allowing the client to list
# configured providers and permitting privacy-conscious users to authorize
# only their choice.
#
# Note that fluffychat always displays a single button anyway. You do not
# need to enable this to use fluffychat; instead we offer a
# default-provider option, see `default` in the provider config section.
#
#single_sso = false

# Setting this option to true replaces the list of identity providers on
# the client's login screen with a single button "Sign in with single
# sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The
# deployment is expected to intercept this URL with their reverse-proxy to
# provide a custom webpage listing providers; each entry linking or
# redirecting back to one of the configured identity providers at
# /_matrix/client/v3/login/sso/redirect/<client_id>`.
#
# This option defaults to false, allowing the client to generate the list
# of providers or hide all SSO-related options when none configured.
#
#sso_custom_providers_page = false

# Under development; do not enable.
#
#sso_aware_preferred = false



#[global.tls]

# Path to a valid TLS certificate file.
#
# example: "/path/to/my/certificate.crt"
#
#certs =

# Path to a valid TLS certificate private key.
#
# example: "/path/to/my/certificate.key"
#
#key =

# Whether to listen and allow for HTTP and HTTPS connections (insecure!)
#
#dual_protocol = false



#[global.well_known]

# The server URL that the client well-known file will serve. This should
# not contain a port, and should just be a valid HTTPS URL.
#
# example: "https://matrix.example.com"
#
#client =

# The server base domain of the URL with a specific port that the server
# well-known file will serve. This should contain a port at the end, and
# should not be a URL.
#
# example: "matrix.example.com:443"
#
#server =

# The URL of the support web page. This and the below generate the content
# of `/.well-known/matrix/support`.
#
# example: "https://example.com/support"
#
#support_page =

# The name of the support role.
#
# example: "m.role.admin"
#
#support_role =

# The email address for the above support role.
#
# example: "admin@example.com"
#
#support_email =

# The Matrix User ID for the above support role.
#
# example "@admin:example.com"
#
#support_mxid =

# Element Call / MatrixRTC configuration (MSC4143).
# Configures the LiveKit SFU server for voice/video calls.
#
# Requires a LiveKit server with JWT authentication.
# The `livekit_service_url` should point to your LiveKit JWT endpoint.
#
# Note: You must also set `client` above to your homeserver URL.
#
# Example:
# ```toml
# [global.well_known]
# client = "https://matrix.yourdomain.com"
#
# [[global.well_known.rtc_transports]]
# type = "livekit"
# livekit_service_url = "https://livekit.yourdomain.com"
# ```
#
#rtc_transports = []



#[global.blurhashing]

# blurhashing x component, 4 is recommended by https://blurha.sh/
#
#components_x = 4

# blurhashing y component, 3 is recommended by https://blurha.sh/
#
#components_y = 3

# Max raw size that the server will blurhash, this is the size of the
# image after converting it to raw data, it should be higher than the
# upload limit but not too high. The higher it is the higher the
# potential load will be for clients requesting blurhashes. The default
# is 33.55MB. Setting it to 0 disables blurhashing.
#
#blurhash_max_raw_size = 33554432



#[global.ldap]

# Whether to enable LDAP login.
#
# example: "true"
#
#enable = false

# URI of the LDAP server.
#
# example: "ldap://ldap.example.com:389"
#
#uri =

# Root of the searches.
#
# example: "ou=users,dc=example,dc=org"
#
#base_dn =

# Bind DN if anonymous search is not enabled.
#
# You can use the variable `{username}` that will be replaced by the
# entered username. In such case, the password used to bind will be the
# one provided for the login and not the one given by
# `bind_password_file`. Beware: automatically granting admin rights will
# not work if you use this direct bind instead of a LDAP search.
#
# example: "cn=ldap-reader,dc=example,dc=org" or
# "cn={username},ou=users,dc=example,dc=org"
#
#bind_dn = ""

# Path to a file on the system that contains the password for the
# `bind_dn`.
#
# The server must be able to access the file, and it must not be empty.
#
#bind_password_file = ""

# Search filter to limit user searches.
#
# You can use the variable `{username}` that will be replaced by the
# entered username for more complex filters.
#
# example: "(&(objectClass=person)(memberOf=matrix))"
#
#filter = "(objectClass=*)"

# Attribute to use to uniquely identify the user.
#
# example: "uid" or "cn"
#
#uid_attribute = "uid"

# Attribute containing the mail of the user.
#
# example: "mail"
#
#mail_attribute = "mail"

# Attribute containing the distinguished name of the user.
#
# example: "givenName" or "sn"
#
#name_attribute = "givenName"

# Root of the searches for admin users.
#
# Defaults to `base_dn` if empty.
#
# example: "ou=admins,dc=example,dc=org"
#
#admin_base_dn =

# The LDAP search filter to find administrative users for tuwunel.
#
# If left blank, administrative state must be configured manually for each
# user.
#
# You can use the variable `{username}` that will be replaced by the
# entered username for more complex filters.
#
# example: "(objectClass=tuwunelAdmin)" or "(uid={username})"
#
#admin_filter =



#[global.jwt]

# Enable JWT logins
#
#enable = false

# Validation key, also called 'secret' in Synapse config. The type of key
# can be configured in 'format', but defaults to the common HMAC which
# is a plaintext shared-secret, so you should keep this value private.
#
#key =

# Format of the 'key'. Only HMAC, ECDSA, and B64HMAC are supported
# Binary keys cannot be pasted into this config, so B64HMAC is an
# alternative to HMAC for properly random secret strings.
# - HMAC is a plaintext shared-secret private-key.
# - B64HMAC is a base64-encoded version of HMAC.
# - ECDSA is a PEM-encoded public-key.
# - EDDSA is a PEM-encoded Ed25519 public-key.
#
#format = "HMAC"

# Automatically create new user from a valid claim, otherwise access is
# denied for an unknown even with an authentic token.
#
#register_user = true

# JWT algorithm
#
#algorithm = "HS256"

# Optional audience claim list. The token must claim one or more values
# from this list when set.
#
#audience = []

# Optional issuer claim list. The token must claim one or more values
# from this list when set.
#
#issuer = []

# Require expiration claim in the token. This defaults to false for
# synapse migration compatibility.
#
#require_exp = false

# Require not-before claim in the token. This defaults to false for
# synapse migration compatibility.
#
#require_nbf = false

# Validate expiration time of the token when present. Whether or not it is
# required depends on require_exp, but when present this ensures the token
# is not used after a time.
#
#validate_exp = true

# Validate not-before time of the token when present. Whether or not it is
# required depends on require_nbf, but when present this ensures the token
# is not used before a time.
#
#validate_nbf = true

# Bypass validation for diagnostic/debug use only.
#
#validate_signature = true



#[[global.identity_provider]]

# The brand-name of the service (e.g. Apple, Facebook, GitHub, GitLab,
# Google) or the software (e.g. keycloak, MAS) providing the identity.
# When a brand is recognized we apply certain defaults to this config
# for your convenience. For certain brands we apply essential internal
# workarounds specific to that provider; it is important to configure this
# field properly when a provider needs to be recognized (like GitHub for
# example).
#
# Several configured providers can share the same brand name. It is not
# case-sensitive. As a convenience for common simple deployments we can
# identify this provider by brand in addition to the unique `client_id` if
# and only if there is a single provider for the brand; see notes for
# `client_id`.
#
#brand =

# The ID of your OAuth application which the provider generates upon
# registration. This ID then uniquely identifies this configuration
# instance itself, becoming the identity provider's ID and must be unique
# and remain unchanged.
#
# As a convenience we also identify this config by `brand` if and only if
# there is a single provider configured for a `brand`. Note carefully that
# multiple providers configured with the same `brand` is not an error and
# this provider will simply not be found when querying by `brand`.
#
#client_id =

# Secret key the provider generated for you along with the `client_id`
# above. Unlike the `client_id`, the `client_secret` can be changed here
# whenever the provider regenerates one for you.
#
#client_secret =

# Secret key to use that's read from the file path specified.
#
# This takes priority over "client_secret" first, and falls back to
# "client_secret" if invalid or failed to open.
#
# example: "/etc/tuwunel/.client_secret"
#
#client_secret_file =

# Issuer URL the provider publishes for you. We have pre-supplied default
# values for some of the canonical public providers, making this field
# optional based on the `brand` set above. Otherwise it is required to
# find self-hosted providers. It must be identical to what is configured
# and expected by the provider and must never change because we associate
# identities to it. If the `/.well-known/openid-configuration` is not
# found behind this URL see `base_path` below as a workaround.
#
#issuer_url =

# The callback URL configured when registering the OAuth application with
# the provider. Tuwunel's callback URL must be strictly formatted exactly
# as instructed. The URL host must point directly at the matrix server and
# use the following path:
# `/_matrix/client/unstable/login/sso/callback/<client_id>` where
# `<client_id>` is the same one configured for this provider above.
#
#callback_url =

# When more than one identity_provider has been configured and
# `single_sso` is false and `sso_custom_providers_page` is false this will
# determine the behavior of the `/_matrix/client/v3/login/sso/redirect`
# endpoint (note the url lacks a trailing `client_id`).
#
# When only one identity_provider is configured it will be interpreted
# as the default and this does not need to be set. Otherwise a default
# *must* be selected for some clients (e.g. fluffychat) to work properly
# when the above conditions require it. To operate out-of-the-box we
# default to one configured provider if none are explicitly default; a
# warning will be logged on startup for this condition.
#
# (EXPERIMENTAL) Multiple providers can be set to default. All providers
# configured with this option set to `true` will associate with the same
# Matrix account when a client flows through
# `/_matrix/client/v3/login/sso/redirect`.
#
# When a user authorizes any provider configured default, the flow will
# include all other providers configured default as well for association.
# NOTE: authorization must succeed for ALL default providers.
#
#default = false

# Optional display-name for this provider instance seen on the login page
# by users. It defaults to `brand`. When configuring multiple providers
# using the same `brand` this can be set to distinguish them.
#
#name =

# Optional icon for the provider. The canonical providers have a default
# icon based on the `brand` supplied above when this is not supplied. Note
# that it uses an MXC url which is curious in the auth-media era and may
# not be reliable.
#
#icon =

# Optional list of scopes to authorize. An empty array does not impose any
# restrictions from here, effectively defaulting to all scopes you
# configured for the OAuth application at the provider. This setting
# allows for restricting to a subset of those scopes for this instance.
# Note the user can further restrict scopes during their authorization.
#
#scope = []

# Optional list of userinfo claims which shape and restrict the way we
# compute a Matrix UserId for new registrations. Reviewing Tuwunel's
# documentation will be necessary for a complete description in detail. An
# empty array imposes no restriction here, avoiding generated fallbacks as
# much as possible. For simplicity we reserve a claim called "unique"
# which can be listed alone to ensure *only* generated ID's are used for
# registrations.
#
#userid_claims = []

# Optional extra path components after the issuer_url leading to the
# location of the `.well-known` directory used for discovery. If the path
# starts with a slash it will be treated as absolute, meaning overwriting
# any path in the issuer_url. The path needs to end with a slash. This
# will be empty for specification-compliant providers. We have supplied
# any known values based on `brand` (e.g. `login/oauth/` for GitHub).
#
#base_path =

# Overrides the `.well-known` location where the provider's openid
# configuration is found. It is very unlikely you will need to set this;
# available for developers or special purposes only.
#
#discovery_url =

# Overrides the authorize URL requested during the grant phase. This is
# generally discovered or derived automatically, but may be required as a
# workaround for any non-standard or undiscoverable provider.
#
#authorization_url =

# Overrides the access token URL; the same caveats apply as with the other
# URL overrides.
#
#token_url =

# Overrides the revocation URL; the same caveats apply as with the other
# URL overrides.
#
#revocation_url =

# Overrides the introspection URL; the same caveats apply as with the
# other URL overrides.
#
#introspection_url =

# Overrides the userinfo URL; the same caveats apply as with the other URL
# overrides.
#
#userinfo_url =

# Whether to perform discovery and adjust this provider's configuration
# accordingly. This defaults to true. When true, it is an error when
# discovery fails and authorizations will not be attempted to the
# provider.
#
#discovery = true

# The duration in seconds before a grant authorization session expires.
#
#grant_session_duration = 300



#[global.appservice.<ID>]

# The URL for the application service.
#
# Optionally set to `null` if no traffic is required.
#
#url =

# A unique token for application services to use to authenticate requests
# to Homeservers.
#
#as_token =

# A unique token for Homeservers to use to authenticate requests to
# application services.
#
#hs_token =

# The localpart of the user associated with the application service.
#
#sender_localpart =

# Whether requests from masqueraded users are rate-limited.
#
# The sender is excluded.
#
#rate_limited = false

# The external protocols which the application service provides (e.g.
# IRC).
#
#protocols = []

# Whether the application service wants to receive ephemeral data.
#
#receive_ephemeral = false

# Whether the application service wants to do device management, as part
# of MSC4190.
#
#device_management = false



#[[global.appservice.<ID>.<users|rooms|aliases>]]

# Whether this application service has exclusive access to events within
# this namespace.
#
#exclusive = false

# A regular expression defining which values this namespace includes.
#
#regex =
