Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration Reference

Hammerhead uses YAML v1.2.2 for configuration. While not the prettiest option for configuration, other languages have been tried before and found to be even worse, so you’ll live (and likely also already know the syntax anyway).

The default configuration is generated at ./config.yaml (i.e. in the directory hammerhead is executed in). The default configuration does not contain all possible values, but will contain all required values with at least placeholder value.

This reference will list every config option available, with a description, and an example.


Required keys:


Environment Variables

There are a number of environment variables that you can set to have even more granular control over some aspects of Hammerhead, detailed below:

GOMAXPROCS

GOMAXPROCS (integer, optional): Overrides the maximum number of threads available to the program.

This is a very low-level tuning parameter you likely do not need to touch.

From the Golang documentation:

The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit.

If not provided, the value is determined via an appropriate default value from a combination of (source)

  • the number of logical CPUs on the machine,
  • the process’s CPU affinity mask,
  • and, on Linux, the process’s average CPU throughput limit based on cgroup CPU quota, if any.

Hammerhead uses this value a lot to determine the maximum number of concurrent threads that a routine can spawn for operations that may spawn an unbounded number of threads (such as global profile updates). In cases where this limit is explicitly checked for, as many threads as required will be created, but only up to N will be executed - the rest will be waiting on a semaphore.

Keep in mind not all operations that split into concurrent routines respect this limit, only those that expect to spawn a lot.

If you are on a single or even dual-core machine, you may wish to raise this. You can see the calculated value at runtime by running hammerhead -version, or by checking POST /_hammerhead/v0/admin/metrics for max_threads.

HAMMERHEAD_TEST_DB_URI

HAMMERHEAD_TEST_DB_URI (string, optional): The fully qualified postgres:// connection URI for a test database.

Used for integration testing - set this if you are running the test suite with go test. Otherwise, database tests will be skipped.

HAMMERHEAD_COMPLEMENT

HAMMERHEAD_COMPLEMENT (literal 1, optional): When value equals 1, enables complement mode.

Enables “complement mode” - changes some internal settings to better suit the complement test suite. Currently, does nothing.

Caution

Enabling this in production will result in an INSECURE server!

HAMMERHEAD_ALLOW_MULTIPLE_SIGNING_KEYS

HAMMERHEAD_ALLOW_MULTIPLE_SIGNING_KEYS (literal 1, optional): When value equals 1, permits having multiple active signing keys.

By default, when starting up, Hammerhead will immediately invalidate all but one signing key if multiple active and valid ones are found. If, for whatever reason, you do not wish for this to happen, setting this env var will skip this process. This voids your warranty.

HAMMERHEAD_CLIENT_IP_HEADERS

HAMMERHEAD_CLIENT_IP_HEADERS (string, optional): A comma separated list of header names to trust as sources of true incoming client IPs.

By default, only X-Forwarded-For and X-Real-Ip are checked for client IPs. If your reverse proxy uses another one, you will have to specify it here. Note that specifying headers here overrides the built-in ones.

Example:

HAMMERHEAD_CLIENT_IP_HEADERS=X-My-Custom-Header,X-Forwarded-For,X-Real-Ip

HAMMERHEAD_TRUSTED_PROXIES

HAMMERHEAD_TRUSTED_PROXIES (string, optional): A comma separated list of network ranges (CIDR) that will be trusted to provide proxy information (see [HAMMERHEAD_CLIENT_IP_HEADERS]).

When not provided, defaults to only loopback addresses (127.0.0.0/8 and ::1/128).

Example:

HAMMERHEAD_TRUSTED_PROXIES=172.16.0.0/12,127.0.0.0/8,::1/128

HAMMERHEAD_TRUST_CLOUDFLARE

HAMMERHEAD_TRUST_CLOUDFLARE (literal 1, optional): When enabled, enable Cloudflare direct proxy support.

It is not recommended that you do this, but if you are using Cloudflare as a proxy (i.e. have the orange cloud), and don’t have a proxy like Caddy in front of the service that handles the incoming request properly, you can set HAMMERHEAD_TRUST_CLOUDFLARE=1. This will add Cloudflare’s IP ranges to your HAMMERHEAD_TRUSTED_PROXIES, and also appends Cf-Connecting-Ip to HAMMERHEAD_CLIENT_IP_HEADERS.

It is recommended you leave this disabled unless you know you need it.


caches

caches (mapping, optional): Controls the sizes and lifetimes of some runtime caches.

Hammerhead caches some data in memory to avoid excessive round-trips to the database, especially when fetching that data may end up being expensive (e.g. fetching a lot of events in rapid succession). Generally, the size of these internal caches scales with your available resources (or, more accurately, every cache defaults to 4096*N, where N is the number of logical processors).

There are no magic numbers, if you need to tune your caches, you should do so with trial and error. What works best is different for each deployment.

Each cache map has two keys, max_entries, and max_ttl. max_entries (integer, optional) controls how many entries can be in the cache before old ones start being evicted. By default, it is 4096*N, where N is the number of logical CPUs. Set this to zero to disable limiting the size of caches (not recommended). max_ttl controls how long entries are allowed to remain in the cache before they are evicted. Set to zero to disable TTL eviction.

Warning

TTL-based cache evictions are checked on each cache operation (both read and write), which means they are inherently more computationally expensive than simple size-based limits.

On the other hand, size-based eviction is only evaluated on write operation, making them generally cheaper, but may result in Hammerhead holding on to memory purely for “stale” cache entries.

It is recommended you leave caches as their default values unless you are encountering memory constraint issues.

Examples:

caches:
  events:
    max_entries: 8192
    max_ttl: 5m

You can monitor the cache size and hit/insert/eviction rate via /metrics.

events

events (mapping, optional): Controls the event cache.

The event cache is a key-value map of {event_id: event_data}. Each value may be up to 64KiB. Generally you want quite a large event cache, and this is the first thing that will be hit during operations that involve events (so, most of them), for example: state resolution, fetching events, client sync loops, message pagination.

See caches for more details.

Example:

caches:
  events:
    max_entries: 8192

devices

devices (mapping, optional): Controls the devices cache.

There are three caches for devices which allow for faster device lookups for incoming requests. Note that the devices cache will be very hot when end-to-end encryption workloads are involved, so you should avoid lowering this one unless you know for sure you won’t be dealing with end-to-end encryption.

The default values for this cache are likely excessive when federation is not involved.

See caches for more details.

Example:

caches:
  devices:
    max_entries: 4096

accounts

accounts (mapping, optional): Controls the accounts cache.

There are two caches for accounts which enable faster account lookups. This cache will always be hot, as accounts are looked up for each incoming request. As one of these caches is an access token to Account mapping (so that Bearer tokens can be instantly related to an account), having values that do not match your devices cache may cause weird behaviour.

See caches for more details.

Example:

caches:
  accounts:
    max_entries: 4096

database

database (mapping, required): The configuration for the PostgreSQL database connection.

Examples:

database:
  url: postgresql://user:password@hostname:port/dbname?sslmode=disable
database:
  url: postgresql://user:password@hostname:port/dbname?sslmode=disable
  max_idle_connections: 2
  max_idle_lifetime: 5m
  max_open_connections: 5
  max_open_lifetime: 5m

database.url

url (string, required): The URI to connect to.

This string SHOULD be prefixed with postgresql://, but postgres:// will work for compatibility reasons.

This connection string is passed directly to the database driver, so you can configure other connection-related settings in this URL (using libpq style query args - see https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS for more info).

Example:

database:
  url: postgresql://user:password@hostname:port/dbname?sslmode=disable

database.max_idle_connections

database.max_idle_connections (integer, optional): The maximum number of idle (not actively running a query) connections to keep open in the connection pool.

See: max_open_connections

database.max_open_connections

database.max_open_connections (integer, optional): The maximum number of active (running a query) connections the connection pool is allowed to have.

These options configure the maximum number of parallel connections available to Hammerhead. Generally, you shouldn’t need too many (2+2 may be a good starting point), and you should also be conscious of the additional resource usage incurred by having more postgres connections on the postgres server. More connections will allow for more concurrent operations, but you should only really be concerned about that if your server is exceptionally high traffic, and you’re seeing lots of warnings about transactions taking a long time.

By default, there is no connection pooling - this is expected to change.

Examples:

database:
  max_idle_connections: 2
database:
  max_open_connections: 2
database:
  max_idle_connections: 2
  max_open_connections: 2

database.max_idle_lifetime

database.max_idle_connections (string (duration), optional): The maximum lifetime of an idle connection.

See: max_open_lifetime

database.max_open_lifetime

database.max_open_connections (string (duration), optional): The maximum lifetime of an active connection.

Controls how long connections live for before being destroyed. You can usually leave this disabled if you aren’t running a fancy postgres server configuration, but if you are, you probably know what these values should be anyway.

Example:

database:
  max_idle_lifetime: 5m
database:
  max_open_lifetime: 5m
database:
  max_idle_lifetime: 5m
  max_open_lifetime: 5m

debug

debug (boolean, optional): Enable or disable debug mode.

While you can still get debug logs and whatnot with this option disabled, setting debug: true will enable additional runtime checks that may affect how the server operates. It is designed to be used with a step-through debugger in mind, so sometimes some conditions that would usually be handled by logging an error will instead cause actual panics and potentially crashes. An example of a side effect of enabling this option is that request handlers that don’t write a response body will cause a crash - with debug disabled, this will log an error instead.

You usually only want to enable this if you are actively debugging Hammerhead.

Example:

debug: true

default_room_version

default_room_version (string, optional): Defines the default room version for new rooms.

While clients can specify the room version they want to create when calling /createRoom, if they do not, the room version specified here will be used instead.

Note

You probably don’t need to set this - the latest version that Hammerhead fully supports is used by default, meaning generally you should just update your server if the default version is not new enough. Overriding the default value may have unintended consequences.

Example:

default_room_version: 12

dont_expose_metrics

dont_expose_metrics (boolean, optional): If true, don’t expose /metrics.

Disables the Prometheus metrics exporter route.

Example:

dont_expose_metrics: true

experiments

experiments (mapping, optional): Enabled experiments.

See: Experiments

Example:

experiments:
  msc1234:
    enabled: true

listeners

listeners (sequence mapping, required): Configures the addresses that Hammerhead will listen to.

Both TCP and unix listeners are supported. You can even mix and match them!

TCP listener:

  • host (optional): The host to listen on. Usually 127.0.0.1 or ::1, or 0.0.0.0 & :: for all addresses. Defaults to an empty string, which implicitly means all addresses, both IPv4 and IPv6.
  • port (required): The port to listen on. Must be between 1 and 65536.

Unix listener:

  • socket (required): The path to the socket file. Hammerhead must be able to create, read, write, and delete this path.

Both listeners can enable native TLS by setting tls: true.

Note

Native TLS is primarily only included for running the test suite. TLS should normally be terminated by your reverse proxy, unless you have an advanced use case.

Tip

All routes (client-to-server, appservices, key-server, server-to-server) are handled by all listeners. If you are used to the Synapse style of having to define which listeners handle which routes, you need not do that here. 127.0.0.1:8008 and 127.0.0.2:8448 both run through the same router, for example.

Example:

listeners:
  - host: 0.0.0.0  # tcp://*:8008 (any IPv4 address)
    port: 8008
  - host: "::"  # tcp://[*]:8008 (any IPv6 address)
    port: 8008
  - host: 0.0.0.0  # tcp+tls://*:8008 (any IPv4 address, with TLS)
    port: 8448
    tls: true
  - host: "::"  # tcp+tls://[*]:8448 (any IPv6 address, with TLS)
    port: 8448
    tls: true
  - port: 8998  # tcp+tls://@:8448 (any IPv4 or IPv6 address)
  - socket: /tmp/hammerhead.sock # (unix socket at /tmp/hammerhead.sock)

logging

logging (mapping, optional): The configuration for zerolog using zeroconfig.

See zeroconfig for the full schema.

If there are no loggers configured, a coloured “pretty” stdout logger will be configured for you. If you are in debug mode (or Hammerhead was built with a dirty working tree), an additional trace-level JSON logger will be configured for you too.

Example:

logging:
  writers:
    # - type: journald  # uncomment if you're using journald.
    - type: stdout
      format: pretty-colored
      min_level: info
    - type: file
      format: json
      min_level: debug
      filename: hammerhead.log  # JSON-line file
      max_size: 100
      max_age: 30
      max_backups: 3
      compress: true

max_request_bytes

max_request_bytes (integer, optional): The maximum size of a request (in bytes) to read before aborting. Defaults to 100MiB (104857600).

Since request bodies are buffered into memory (including media) before they’re worked on, it is generally necessary to limit the size of request bodies that will be read. If a request sends a body larger than this, it will only be partially read, and then rejected when the server realises it’s too large (at least one byte over the limit).

Caution

Setting this value too high will either result in the OOM reaper coming knocking, and terminating the server process, or potentially undefined behaviour ranging from catchable alloc failures, to critical panics.

Examples:

max_request_bytes: 26214400  # 25MiB
max_request_bytes: 52428800  # 50MiB
max_request_bytes: 104857600  # 100MiB (higher values are typically excessive and unsafe)
max_request_bytes: 536870912  # 512MiB
max_request_bytes: 1073741824  # 1GiB

media_repo

media_repo (mapping, optional): The configuration for the media repository.

Hammerhead’s media repository is quite a complex component that is incredibly flexible, so there are a number of configuration options to play with. Fear not, only a couple are necessary.

media_repo.root_path

root_path (string, optional): The root path to where media should be stored.

This can either be a fully qualified absolute path, or a relative path, or even point at a symlink. As long as the subdirectories local, remote, and external can be created at that location.

If the root_path does not exist, it will be created with 750 file permissions (rwxr-x---). The root path must not end in a trailing slash.

If the root path is not provided, the media repository will be disabled (but existing data will remain, if it exists).

Example:

media_repo:
  root_path: /mnt/media/hammerhead

media_repo.temp_path

temp_path (string, optional): The path to where temporary media files should be stored.

This can either be a fully qualified absolute path, or a relative path, or even point at a symlink. Temporary directories starting with the prefix hammerhead_media_ must be creatable by the server.

If the temp_path does not exist, it will be created with 750 file permissions (rwxr-x---).

“temporary media files” are typically files that are being actively uploaded (i.e. before they’re properly saved), and thumbnails that are being worked on. It is unlikely that files will remain in this directory for more than a few seconds at a time.

It is safe to put the temporary directory on an ephemeral file system.

If the path is omitted, the system temporary directory (typically /tmp on Linux) will be used.

Example:

media_repo:
  temp_path: /mnt/media/hammerhead

media_repo.max_size_bytes

max_size_bytes (unsigned 64-bit integer, optional): The maximum size (in bytes) of a single media item. Defaults to 100MiB (104857600).

Controls the maximum size of file uploads. Attempts to upload media files that are larger than this value will be rejected, even if the uploader is an administrator. The server will attempt to reject large uploads if their advertised Content-Length exceeds this value, but in cases where the Content-Length header is unavailable, the server will read up to max_size_bytes+1 bytes to determine whether the file is too large.

Important

The value of max_size_bytes MUST be less than or equal to max_request_bytes. Setting a value higher than max_request_bytes would cause the router component to reject the request for being too large before it could be passed to the media repository component for validation.

The server will refuse to start if this condition is not met.

Examples:

media_repo:
  max_size_bytes: 8388608  # 8MiB
media_repo:
  max_size_bytes: 26214400  # 25MiB
media_repo:
  max_size_bytes: 52428800  # 50MiB
media_repo:
  max_size_bytes: 104857600  # 100MiB
media_repo:
  max_size_bytes: 536870912  # 512MiB
media_repo:
  max_size_bytes: 1073741824  # 1GiB

media_repo.security

security (mapping, optional): Configures the security-related settings for the media repository.

Because the media repository is a complex component that exclusively handles potentially untrusted user input, there are several security configurations available. The configuration for this is structured in such a way that the default values are typically sufficient for most people.

media_repo.security.disable_remote_media

disable_remote_media (boolean, optional): If enabled, disables external/remote media functionality. Defaults to false.

When remote media is disabled, federated media will not be fetched, federated requests for media will be rejected, and server-side URL previews will be disabled.

Example:

media_repo:
  security:
    disable_remote_media: true

media_repo.security.disallow_mime_types

disallow_mime_types (sequence of strings, optional): Prevents files matching any of the given glob patterns from being uploaded to the media repository.

When a user attempts to upload a file, if the claimed Content-Type matches any of the given glob patterns, it will be rejected, even if they are an administrator.

Warning

The content type of encrypted files is application/octet-stream. Using a glob pattern that blocks this will effectively prevent users from uploading encrypted files.

Furthermore, Hammerhead does not currently support MIME sniffing, so malicious users can work around this restriction by lying about or omitting the relevant header.

Example:

media_repo:
  security:
    disallow_mime_types:
      - image/*  # ban all images
      - application/vnd.microsoft.portable-executable  # ban EXE files
      - application/zip
      - application/x-zip-compressed
      - application/gzip
      - application/zstd  # ban compressed types

media_repo.security.only_admins

only_admins (boolean, optional): If true, only server administrators can upload media.

When enabled, regular users are unable to upload media. This can be used to restrict media uploads to only trusted users.

Example:

media_repo:
  security:
    only_admins: true

media_repo.security.disable_checksums

disable_checksums (boolean, optional): If true, disable checksum generation and comparison.

Hammerhead makes use of SHA256 checksums to verify the integrity of media when utilising it. Typically, this means a SHA256 checksum is generated when the file has finished uploaded, and is then verified before it is transmitted to requesting clients. This prevents the file being tampered with on disk (although this is easily circumvented by just modifying the hash in the database). Over federation, Hammerhead will include this SHA256 hash in the metadata part of the download, before sending the media content itself. This means other Hammerhead servers that download media from this server will be able to verify the integrity of the downloaded file before processing it. This is not a Matrix behaviour and is currently exclusive to Hammerhead.

Turning off checksums may improve performance as it avoids an extra disk round-trip, however this opens up the potential for corrupted or tampered files to be served.

Files that fail checksum validation are not immediately deleted, however will cause an error.

Example:

media_repo:
  security:
    disable_checksums: true  # not recommended

media_repo.security.minimum_account_age

minimum_account_age (string (duration), optional): The minimum age an account must be before it can upload files.

Restricts uploading media to accounts that have existed for longer than the given duration, excluding administrators.

Example:

media_repo:
  security:
    minimum_account_age: 5m  # 5 minutes

media_repo.security.disable_server_side_thumbnails

disable_server_side_thumbnails (boolean, optional): Disables server-side thumbnail generation.

Disabling server-side thumbnails may be desirable to reduce the amount of processing done on user-generated content, which is a large attack surface. The downside of this is that thumbnails will generally be unavailable for uploaded media, such as user avatars, resulting in increased bandwidth and unhappy impatient users.

Example:

media_repo:
  security:
    disallow_server_side_thumbnails: true

media_repo.security.acl

acl (mapping, optional): An ACL event body that defines which servers are and aren’t allowed to communicate media.

Sets an access-control-list in the same way as room ACLs - servers in the allow are always allowed, unless they are denied in the deny list. You cannot create an ACL that bans the local server.

The ACL is bidirectional - forbidden servers won’t be able to download media from you, but you also won’t be able to download media from them.

Examples:

# Explicit denylist
media_repo:
  security:
    acl:
      allow: ["*"]  # Allow all servers
      deny:
        - evil.matrix.example  # Don't allow media communication with evil.matrix.example specifically.
        - "*.bad.matrix.example"  # Don't allow media communication with any server name under "bad.matrix.example".
# Explicit denylist
media_repo:
  security:
    acl:
      allow:
        - "SERVER_NAME_HERE"  # Your server name has to be explicitly listed
        - "good.matrix.example"  # Allow media communication with good.matrix.example
      # No need for an explicit `deny` here.

media_repo.security.enable_streaming

enable_streaming (boolean, optional): Allow streaming media over federation.

When enabled, media can be streamed directly to the requesting client before the server has finished downloading it over federation. This is incompatible with checksum verification, which will instead be ignored in this case. The benefit of this feature is that users can start streaming files from remote servers almost immediately, rather than having to wait for the homeserver to finish downloading it before uploading it again, which is particularly useful for videos. However, the lack of checksum verification, or preprocessing as a whole, means that other security protections may not be effective, and potentially invalid or illegal data may be sent to the client unknowingly.

You should evaluate how this fits into your threat model before changing this value.

Example:

media_repo:
  security:
    enable_streaming: true

old_verify_keys

old_verify_keys (mapping, optional): A mapping of previous signing key IDs to when they expired.

A map of old signature keys that can be used to verify events. You should prefer to import the keys via the command hammerhead -import-signing-key, but if you do not have the private key any more you can advertise it here instead.

The keys of the map are the key IDs (e.g. ed25519:foo), and the value has two required keys:

  • key: The full public signing key of this key.
  • expired_ts: The unix timestamp (milliseconds) when this key expired

Example:

old_verify_keys:
  - ed25519:auto:
      key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw
      expired_ts: 1576767829750

registration

registration (mapping, optional): The registration settings for this server.

Controls the registration requirements for the server. If omitted, registration is disabled.

Example:

registration:
  enabled: true
  token: ed03d0b58fa20618be08fe20c1eb05a0
  password_requirements:
    min_entropy: 70
  admin_pre_shared_secret: 38d7630f8c5bdb50df2d99e65fd0e60f

registration.enabled

enabled (boolean, optional): Whether registration is enabled at all. Defaults to false.

If registration is disabled, no new accounts can be created without the admin API, even if requirements like a token are set.

Example:

registration:
  enabled: true

registration.i_have_a_very_good_reason_or_i_am_stupid_and_want_to_allow_unsafe_open_registration

i_have_a_very_good_reason_or_i_am_stupid_and_want_to_allow_unsafe_open_registration (boolean, optional): If set to true, registration will be unsafely open.

Enables registration without any registration requirements. This is dangerous, as this means your only defence against automated bots mass-registering on your server is rate-limits, and you have no way to prevent untrusted users registering and potentially being abusive. You should never need to enable this!

Example:

registration:
  i_have_a_very_good_reason_or_i_am_stupid_and_want_to_allow_unsafe_open_registration: false

registration.token

token (string, optional): The pre-shared secret to challenge registrations with.

A pre-shared token that is required as a second step to register an account. This allows you to give out an “invite code” to people you trust, so that they can create accounts themselves. This is the recommended way to have registration enabled.

If omitted or empty, the registration token will be disabled.

Example:

registration:
  token: ed03d0b58fa20618be08fe20c1eb05a0

registration.password_requirements

password_requirements (mapping, optional): Controls the requirements for passwords on this server.

Allows you to set minimum password length and entropy requirements. Not applied to accounts created via the admin API.

Example:

registration:
  password_requirements:
    min_entropy: 50  # require at least 50 bits of entropy
    min_length: 0  # disable length requirements

registration.password_requirements.argon2id

argon2id (mapping, optional): Controls the parameters passed to the Argon2id password hashing algorithm.

Allows you to change the time cost, memory cost, and parallelism values of the Argon2id algorithm. When a field is omitted, it defaults to whatever is recommended by RFC9106 § 7.4. It is not recommended you adjust this unless you have a very good reason to.

Hammerhead does not validate that you set “secure” values, in case the definition of “secure values” differs in the future. As such, you can shoot yourself in the foot with this. Furthermore, hashes are immutable once created - if you set an insane memory cost (like the recommended 2 gigabytes), the generated hash will always use that value during verification.

Fields:

  • t (32-bit unsigned integer): the T parameter (time cost). Must be at least 1 (0 uses default value).
  • m (32-bit unsigned integer): the M parameter (memory cost, in kibibytes). Note that this is normalised to at least 8*p (per RFC9106). Consequently, cannot be lower than 8 (0 uses default value).
  • p (8-bit unsigned integer): the parallelism degree. Must be at least 1 (0 uses default value).

registration.admin_pre_shared_secret

admin_pre_shared_secret (string, optional): A pre-generated authentication token that can only be used with the admin API to create new users.

When set, POST /_hammerhead/v0/admin/users/create will accept this value as a Bearer token, rather than requiring a token for an existing admin account. This can be used to bootstrap create the first admin user, or by automated tools to create new users without necessarily needing a service account.

Example:

registration:
  admin_pre_shared_secret: 38d7630f8c5bdb50df2d99e65fd0e60f
curl -H 'Authorization: Bearer 38d7630f8c5bdb50df2d99e65fd0e60f' \
    --json '{"localpart":"admin","admin": true}' \
    http://localhost:8008/_hammerhead/v0/admin/users/create

room_directory.admin_only

admin_only (boolean, optional): If enabled, only server admins are able to publish to the room directory.

When enabled, only admin users can publish rooms to the public room directory (i.e. room list). Note that when enabled, users can still create and use aliases, they just cannot publish them.

Example:

room_directory:
  admin_only: true

server_name

server_name (string, required): The name of this server.

This is not necessarily your domain name - it is the part of the ID that appears at the end of user IDs, and room aliases. For example, @user:matrix.example would have the server name matrix.example, even if traffic was ultimately served from hammerhead.matrix.example.

The server name can be an IP address (not recommended) or DNS name, optionally with a port. Typically, you will use a DNS name without a port here (you configure the port later).

Caution

You cannot change the server name after registering the first user.

Examples:

server_name: matrix.example
server_name: matrix.example:8448  # not recommended

static_room_directory

static_room_directory (mapping, optional): Configures the “static room directory”.

Defines all the rooms and their metadata that can be used to serve room queries over federation. Allows you to define resolvable aliases for rooms the server is not yet in. See also: https://github.com/tulir/mauliasproxy.

Important

This option has no effect if experiments.federation is not enabled!

static_room_directory is a mapping of { localpart: {room_id: '...', via: ['...']} }. The localpart here is the part after #, but before : (like with user IDs). room_id is the underlying room ID, like !example:example.net, and via is a list of server names that can help prospective members join the room.

Example:

static_room_directory:
  main:
    room_id: '!hammerhead-1:nexy7574.co.uk'
    via: ["nexy7574.co.uk", "synapse.nexy7574.co.uk", "asgard.chat", "corellia.timedout.uk", "starstruck.systems"]

In this example, #main:SERVER_NAME will resolve to !hammerhead-1:nexy7574.co.uk, and will tell remote servers asking about this room to join through any of the provided servers.

tls

tls (mapping, optional): Configures TLS options for TLS listeners.

Configures the certificate file and key file for serving TLS directly from listeners. You can generate a self-signed certificate with

openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 365 -out cert.pem

Example:

tls:
  cert_file: path/to/cert.pem
  key_file: path/to/key.pem

well_known

well_known (mapping, optional): Controls the values returned to the well-known helper routes.

well_known.client

client (string, optional): The base URL for client-to-server interactions.

Example:

well_known:
  client: https://client.matrix.example