Configuration

mesgd.config defines the node's listeners, key locations, administrator accounts, and optional services. It is an Erlang list of {Key, Value} tuples. Configuration lookups read the file, but components that retain a value at startup do not automatically adopt later changes. Restart the node after changing listener settings, OAuth client secrets, or the auth key file; administrator-name changes apply on the next authorization check.

The example file in the mesgd source is for a local machine. Keep its cookie and any real client secrets off the website and out of git.

Listeners and identity

KeyExampleWhat you are setting
domain"localhost"The name mesgd uses when it describes itself
port4433HTTPS port for accounts and WebSocket
cacert, cert, keycerts/*.pemTLS chain and private key for that listener
nodemesgd@localhostDistributed Erlang node name; defaults to mesgd@localhost
nodes[mesgd@localhost]Nodes that share account tables. See Cluster
cookiean atomDistribution cookie, unless MESGD_COOKIE_FILE is set
keystore"./keys"Directory for JWK files and auth.key
mesgd_jwk"mesgd.json"Service signing and encryption key file inside the keystore
admin_jwk"admin.json"Administrator PKI identity. This does not grant the admin role
disable_authfalseOnly the atom true lets a client skip a missing credential
public_pathsa list of pathsExact paths that skip the missing-credential check

Set disable_auth only for a test that has no client SDK. On a public node, leave it off and put paths you intend to expose in public_paths.

Console, statistics, and the agent UI

KeyExampleWhat you are setting
console_port5544Management console port
console_cacert, console_cert, console_keycertificate pathsTLS for the console listener
console_root"console"HTML, CSS, and scripts the console serves
stats_history_dira directory pathWhere mesgd appends statistics. Absent, that is statistics/ under the keystore
stats_retention_seconds86400How long to keep history, from 60 to 604800 seconds. Any other value stops the statistics store at startup
agent_ui_enabledtrueServe /agent-ui and /auth/agent-state/. Absent, or any value other than the atom true, those URLs are 404

Accounts

KeyWhat you are setting
{admin, Name}An administrator username. Public signup cannot take it
auth_adminsMore administrator usernames, exact and case-sensitive, as binaries
auth_keyfileThe 32-byte key that seals authenticator secrets. Defaults to auth.key inside the keystore, or keys/auth.key when no keystore is set
auth_issuerThe label in authenticator URIs. The default is mesgd
session_ttlBearer session lifetime in seconds. Absent, 86400, which is 24 hours. An integer from 60 to 2592000. Any other value stops the account service. mesgd reads it when it issues the session, so a session already issued keeps the expiry it was given
oauth_providersGoogle and GitHub client settings. OAuth stays off when this key is absent

mesgd reads {admin, Name} and auth_admins on every check. A change applies to the next request, including a session that was already issued. A provider email or a provider subject is not an administrator name.

The auth key must be a regular file, readable only by its owner, and exactly 32 bytes. mesgd creates a missing file with those permissions. Back it up apart from the database. If you lose it, stored authenticator secrets cannot be opened. Replacing the file does not re-encrypt secrets that are already stored. Every node that serves accounts uses the same file. See Cluster.

OAuth secrets come from the environment:

{oauth_providers, #{
    google => #{
        client_id => {env, "MESGD_GOOGLE_CLIENT_ID"},
        client_secret => {env, "MESGD_GOOGLE_CLIENT_SECRET"},
        redirect_uri => "https://mesgd.example/auth/oauth/google/callback"
    },
    github => #{
        client_id => {env, "MESGD_GITHUB_CLIENT_ID"},
        client_secret => {env, "MESGD_GITHUB_CLIENT_SECRET"},
        redirect_uri => "https://mesgd.example/auth/oauth/github/callback"
    }
}}.

Register each redirect URI with the provider. If a secret is missing, the OAuth worker fails at startup and the secret is not written to the log. After the provider returns, mesgd sends the browser to /account on the same origin. You can set completion_uri to another HTTPS URL on that origin, outside /auth. See OAuth.

Distribution cookie

The mesgd command needs the same distribution cookie as the node, or mesgd user and mesgd status cannot connect.

When MESGD_COOKIE_FILE is set, the command reads the cookie from that file. Otherwise it reads {cookie, Atom} from mesgd.config. ./mesgd start applies the cookie after the node name is up. Remote commands (user, otp, console, status) set the cookie on their own short-lived node before they connect.

mesgd:start/0 only starts distribution with the node name. A node you start some other way keeps the VM cookie until something sets it. The command and the node have to share a cookie.

Where accounts are stored

On a fresh start, mesgd creates a Mnesia schema in the configured Mnesia directory. The default is Mnesia.NODE in the working directory. Set the Mnesia dir application environment to a stable absolute path before you start, so a restart does not look in a new place. When nodes lists more than one node, account tables, OAuth identities, and the admin audit follow Cluster.