Configuration Reference

Mezite is configured through a YAML file, typically located at /etc/mezite/mezite.yaml. Every setting can also be overridden via environment variables. This page documents every field, its type, default value, and the corresponding environment variable.


Config Loading Order

Settings are resolved in the following order, with later sources taking precedence:

  1. Built-in defaults — Sensible values baked into the binary.
  2. Config file — Loaded from the path given by --config.
  3. Environment variables — Prefixed with MEZITE_, these override any value set in the config file.
Environment variables always win. This makes it easy to inject secrets (like database passwords and CA passphrases) without writing them to disk.

Minimal Config

The smallest useful configuration — just enough to start a combined-mode server with SQLite (the default):

mezite.yaml — minimal (SQLite) yaml
cluster_name: my-cluster

ssh:
  enabled: true

For PostgreSQL, set the driver and connection fields:

mezite.yaml — minimal (PostgreSQL) yaml
cluster_name: my-cluster

database:
  driver: postgres
  host: localhost
  port: 5432
  user: mezite
  password: mezite
  name: mezite
  sslmode: disable

ssh:
  enabled: true

Full Example

Below is a complete mezite.yaml with every field and its default value. In practice you only need to specify values that differ from the defaults.

mezite.yaml — complete reference yaml
# ─── Cluster ─────────────────────────────────────────────
cluster_name: my-cluster

# ─── Logging ─────────────────────────────────────────────
log:
  level: info
  format: json

# ─── Database ────────────────────────────────────────────
database:
  driver: sqlite          # sqlite (default) or postgres
  host: localhost          # PostgreSQL only
  port: 5432               # PostgreSQL only
  user: mezite             # PostgreSQL only
  password: mezite         # PostgreSQL only
  name: mezite             # PostgreSQL only
  sslmode: require         # PostgreSQL only

# ─── Auth Service ────────────────────────────────────────
auth:
  grpc_allow_http: false

# Top-level: CA private key encryption passphrase
ca_key_passphrase: ""

# ─── Proxy Service ───────────────────────────────────────
proxy:
  public_addr: ""              # required for OIDC, WebAuthn, etc.
  listen_addr: 0.0.0.0:3080
  ssh_listen_addr: 0.0.0.0:3023
  tunnel_listen_addr: 0.0.0.0:3024
  apps_domain: ""              # parent domain for application access (empty = off)
  apps_oidc_connector: ""      # SSO connector that gates browser app access
  # apps_keypair:              # optional dedicated wildcard keypair for *.<apps_domain>
  #   cert_file: /etc/mezite/apps-wildcard.crt
  #   key_file: /etc/mezite/apps-wildcard.key

# ─── SSH Service ─────────────────────────────────────────
ssh:
  enabled: false

Cluster

FieldTypeDefaultEnv VarDescription
cluster_namestringmeziteMEZITE_CLUSTER_NAMEUnique identifier for this cluster. Embedded in all certificates and used to namespace audit events. Must be a valid DNS label.
data_dirstring/var/lib/meziteMEZITE_DATA_DIROn-disk directory used for the SQLite database, local session recordings, and the join-state file. Must be writable by the user mezhub runs as.

Logging

Logging keys below apply to the mezhub server. The mezd agent emits its own structured logs at production defaults; it does not read MEZITE_LOG_LEVEL or MEZITE_LOG_FORMAT.

FieldTypeDefaultEnv VarDescription
log.levelstringinfoMEZITE_LOG_LEVELMinimum log level for mezhub. One of debug, info, warn, error.
log.formatstringjsonMEZITE_LOG_FORMATLog serialization format for mezhub. json for structured output, text for human-readable.
log.outputstringstderr--Destination for mezhub logs. Config-file only — there is no dedicated env var.

Database

Mezite supports SQLite and PostgreSQL backends. SQLite is the simplest option for self-hosted deployments (zero external dependencies). PostgreSQL 16+ is recommended for production and managed deployments.

FieldTypeDefaultEnv VarDescription
database.driverstringsqliteMEZITE_DB_DRIVERDatabase backend: sqlite or postgres.
database.urlstring""MEZITE_DB_URLConnection URL. For SQLite: file path. For PostgreSQL: DSN. When empty, built from fields below (PG) or defaults to <data_dir>/mezhub.db (SQLite).
database.hoststringlocalhostMEZITE_DB_HOSTPostgreSQL hostname or IP address.
database.portinteger5432MEZITE_DB_PORTPostgreSQL port.
database.userstringmeziteMEZITE_DB_USERDatabase user (PostgreSQL only).
database.passwordstring""MEZITE_DB_PASSWORDDatabase password (PostgreSQL only).
database.namestringmeziteMEZITE_DB_NAMEName of the PostgreSQL database.
database.sslmodestringrequireMEZITE_DB_SSLMODEPostgreSQL TLS mode. Accepts: disable, require, verify-ca, verify-full.
database.max_open_conns / database.max_idle_connsinteger25 / 5--Connection-pool sizing. Config-file only. Raise max_open_conns only alongside the server's own max_connections.
database.conn_max_lifetimeduration5m--How long a pooled connection is reused before being recycled. Keep it below any idle-connection timeout enforced by a proxy such as PgBouncer or RDS Proxy.
SQLite (simplest — no external database) bash
export MEZITE_DB_DRIVER=sqlite
export MEZITE_DB_URL=/var/lib/mezite/mezhub.db
PostgreSQL (production) bash
export MEZITE_DB_DRIVER=postgres
export MEZITE_DB_HOST=db.internal.example.com
export MEZITE_DB_PORT=5432
export MEZITE_DB_USER=mezite
export MEZITE_DB_PASSWORD='$(vault kv get -field=password secret/mezite/db)'
export MEZITE_DB_NAME=mezite
export MEZITE_DB_SSLMODE=verify-full

Auth

Local username/password authentication is always available out of the box; SSO connectors (OIDC, SAML, LDAP, GitHub OAuth) are configured at runtime with mezctl connectors create, not via this YAML file. See the SSO Guide for the connector schema.

First-issue SSH certificate TTL is set per call to IssueUserCerts. It defaults to 12h and is hard-capped at 24h regardless of any role or cluster setting. Per-role max_session_ttl is a separate knob that tightens cross-cluster certificate issuance further; it does not raise the 24h ceiling. The schema field auth.session_ttl is currently reserved — it appears for forward compatibility but is not read by any code path today.

FieldTypeDefaultEnv VarDescription
auth.grpc_allow_httpbooleanfalseMEZITE_GRPC_ALLOW_HTTPAllow plaintext h2c (HTTP/2 cleartext) on the gRPC listener. This is HTTP/2 in the clear — use only when a TLS-terminating load balancer or service mesh fronts mezhub. If anything other than that fronts the listener, leave this off and present a certificate to clients directly.
auth.lock_fail_modestringstrictMEZITE_AUTH_LOCK_FAIL_MODEWhat the lock enforcer does when the lock store is unreachable and the live lock view cannot be consulted. strict (the default) denies access — fail-closed, so a momentary outage cannot let a locked identity through. best_effort allows access — fail-open — but every such bypass is written to the audit log and logged at error level, so it is never silent. Governs the SSH, app-TCP, web-session and cross-cluster use paths; certificate minting always fails closed regardless of this setting.
auth.session_ttlduration12h--Reserved. Present in the schema for forward compatibility, but not read by any code path today — certificate lifetime is set per call to IssueUserCerts as described above.
ca_key_passphrase (top-level)string""MEZITE_CA_KEY_PASSPHRASEPassphrase used to encrypt Certificate Authority private keys at rest in the database.

Proxy

FieldTypeDefaultEnv VarDescription
proxy.public_addrstring""MEZITE_PROXY_PUBLIC_ADDRThe public address that clients use to reach this proxy (e.g. mezite.example.com:443). Used to derive the WebAuthn relying-party ID/origin and the cluster's GetServerInfo enrollment URL. The OIDC issuer URL is configured separately via proxy.oidc_issuer_url.
proxy.listen_addrstring0.0.0.0:3080--Bind address for the HTTPS listener.
proxy.ssh_listen_addrstring0.0.0.0:3023--Bind address for the SSH listener.
proxy.tunnel_listen_addrstring0.0.0.0:3024--Bind address for the reverse-tunnel listener.
proxy.oidc_issuer_urlstring""MEZITE_OIDC_ISSUER_URLPublic issuer URL surfaced at /.well-known/openid-configuration and used in workload-identity JWT SVIDs. No trailing slash.
proxy.trusted_ip_headerstring""--HTTP header to read real client IP from (e.g. Fly-Client-IP, X-Forwarded-For). Config-file only — there is no dedicated env var for this field.
proxy.single_portbooleanfalseMEZITE_SINGLE_PORTEnable ALPN single-port routing on the HTTPS listener. When on, the proxy demultiplexes SSH, agent tunnel, and HTTPS traffic onto proxy.listen_addr using TLS ALPN protocol IDs, so a cluster can be reached entirely on :443. The individual ssh_listen_addr and tunnel_listen_addr sockets still bind unless their ports are unset; clients reaching the proxy on :443 are routed by ALPN.
proxy.proxy_protocolstringoff--Mode for HAProxy PROXY protocol v1/v2 headers on the SSH and tunnel listeners. Accepted values are off (default; PROXY headers ignored) and on (PROXY headers required from trusted source ranges). When set to on, pair with proxy.proxy_protocol_trusted_cidrs so only trusted load-balancer source ranges can rewrite the client IP. See Reverse Proxy.
proxy.proxy_protocol_trusted_cidrslist of strings(empty)--IPs or CIDRs permitted to send PROXY headers when proxy.proxy_protocol is on. Required in that case — connections from any other source are rejected.
proxy.apps_domainstring""MEZITE_PROXY_APPS_DOMAINParent domain for application access hostnames (e.g. apps.example.com makes apps reachable at <app>.apps.example.com). Empty disables application-access host routing; nothing else about the cluster changes. Requires a wildcard DNS record and a TLS certificate covering *.<apps_domain>.
proxy.apps_keypair.cert_file / proxy.apps_keypair.key_filestring""MEZITE_PROXY_APPS_CERT_FILE / MEZITE_PROXY_APPS_KEY_FILEOptional dedicated wildcard (or multi-SAN) keypair for *.<apps_domain>, SNI-selected for app subdomains. When unset, the proxy's main HTTPS certificate must cover the apps wildcard in its SANs. Both fields are required together, and only take effect when apps_domain is set — otherwise the proxy refuses to start.
proxy.apps_oidc_connectorstring""MEZITE_PROXY_APPS_OIDC_CONNECTORName of the SSO connector the browser application-access gate redirects unauthenticated users to. Required for the browser app gate to start a login.
proxy.tls_modestringon--Whether the proxy terminates TLS itself. on (the default) presents a certificate to clients. off serves plaintext — use only behind a TLS-terminating load balancer that fronts every listener. Config-file only.
proxy.https_keypair.cert_file / proxy.https_keypair.key_filestring""--External keypair for the main HTTPS listener (e.g. a cert-manager Secret mount). When unset, the proxy serves a certificate issued by the cluster's internal Host CA. Config-file only.
proxy.max_conns_per_ipinteger100--Cap on concurrent connections from a single source IP.
proxy.idle_timeout / proxy.read_timeout / proxy.write_timeout / proxy.read_header_timeoutduration30s / 30s / 60s / 10s--HTTP server timeouts on the proxy listener.
proxy.max_session_durationduration24h--Hard ceiling on a single session's wall-clock length. A role's max_session_ttl can tighten this but not raise it.

SSH

FieldTypeDefaultEnv VarDescription
ssh.enabledbooleanfalse--Enable the built-in SSH service on this node.
ssh.listen_addrstring""--Bind address for the built-in SSH service. Only meaningful when ssh.enabled is true.
ssh.labelsmap(empty)--Labels advertised by the built-in SSH service, matched by node_labels in role rules.
ssh.keep_alive_intervalduration5mMEZITE_SSH_KEEP_ALIVE_INTERVALHow often a keepalive is sent on an idle SSH connection.
ssh.keep_alive_count_maxinteger3MEZITE_SSH_KEEP_ALIVE_COUNT_MAXConsecutive missed keepalives tolerated before the connection is torn down. With the defaults a dead peer is detected after roughly 15 minutes.

Recording

Controls where session recordings are written and how/when the agent uploads them. See the Session Recording guide for end-to-end behavior.

FieldTypeDefaultEnv VarDescription
recording.backendstringlocalMEZITE_RECORDING_BACKENDStorage backend: local (filesystem under data_dir) or s3.
recording.s3.bucketstring""MEZITE_S3_BUCKETS3 bucket name.
recording.s3.regionstringus-east-1MEZITE_S3_REGIONS3 region.
recording.s3.endpointstring""MEZITE_S3_ENDPOINTCustom endpoint URL for MinIO or other S3-compatible stores. Empty uses AWS defaults.
recording.s3.access_keystring""MEZITE_S3_ACCESS_KEYStatic access key. Leave empty to use the default AWS SDK credential chain (IRSA, IAM role, env, ~/.aws).
recording.s3.secret_keystring""MEZITE_S3_SECRET_KEYStatic secret key. Paired with access_key.
recording.s3.prefixstring""MEZITE_S3_PREFIXOptional key prefix under the bucket (e.g. cluster-a/recordings/).
recording.s3.force_path_stylebooleanfalseMEZITE_S3_FORCE_PATH_STYLEUse path-style addressing (https://endpoint/bucket/key) instead of virtual-host style. Required for MinIO and some on-prem stores.
recording.s3.auto_create_bucketbooleanfalseMEZITE_S3_AUTO_CREATE_BUCKETCreate the bucket on startup if it does not exist. Off in production; intended for dev and tests.
recording_enc_key (top-level)string""MEZITE_RECORDING_ENC_KEYHex-encoded 32-byte AES-256-GCM key. When set, the agent encrypts every recording chunk before handing it to the storage backend (covers both local and s3). Leaving this empty disables recording encryption; the recording is written in the clear to the backend.
--string--MEZITE_RECORDING_MODESet on mezd, not mezhub. Recording mode is normally a cluster-wide setting (session_recording, set via mezctl config set — see Session Recording) that agents pick up automatically; this variable pins one agent's mode and ignores the cluster setting entirely. Values: off, proxy, node (buffer locally, upload after the session ends), or node-sync (stream chunks to the auth service in real time). Leave unset (the default) unless this specific node needs to diverge from the fleet.

Audit Log Sinks

Audit events are always written to the cluster database. In addition, events can be mirrored to one or more external sinks for SIEM, alerting, or long-term archive. See the Audit Logging guide.

FieldTypeDefaultEnv VarDescription
audit_hmac_key (top-level)string""MEZITE_AUDIT_HMAC_KEYHex-encoded HMAC key for the tamper-detection chain on persisted audit events. Strongly recommended in production. Rotating this key invalidates the existing chain — keep the old value alongside the new one during transition.
--string--MEZITE_AUDIT_SINK_FILE_PATHWhen set, every audit event is appended to this file in newline-delimited JSON format (one JSON object per line). Useful for shipping to a log forwarder or for offline archival.
--string--MEZITE_AUDIT_SINK_WEBHOOK_URLWhen set, every audit event is POSTed as JSON to this URL. Common target for Splunk HEC, Datadog Logs intake, Elastic ingest, or a tenant-side Lambda. The receiving endpoint should be idempotent — transient retries can deliver the same event more than once.
--duration5sMEZITE_AUDIT_SINK_WEBHOOK_TIMEOUTHTTP timeout for the webhook sink. Slow endpoints stall the mirror; the in-process audit pipeline keeps emitting to the database regardless.
audit_export.backendstring""MEZITE_AUDIT_EXPORT_BACKENDSet to s3 to mirror every audit event to an S3-compatible bucket for long-term archive. Empty (the default) disables the export sink.
audit_export.s3.bucket / audit_export.s3.region / audit_export.s3.endpoint / audit_export.s3.prefixstring""MEZITE_AUDIT_EXPORT_S3_BUCKET / _REGION / _ENDPOINT / _PREFIXDestination for the export sink. endpoint targets MinIO or another S3-compatible store; leave empty for AWS.
audit_export.s3.access_key / audit_export.s3.secret_keystring""MEZITE_AUDIT_EXPORT_S3_ACCESS_KEY / _SECRET_KEYStatic credentials. Leave empty to use the default AWS SDK credential chain (IRSA, instance role, env, ~/.aws).
audit_export.s3.kms_key_arnstring""MEZITE_AUDIT_EXPORT_S3_KMS_KEY_ARNKMS key to encrypt exported objects with (SSE-KMS). Empty uses the bucket's default encryption.
audit_export.s3.force_path_stylebooleanfalseMEZITE_AUDIT_EXPORT_S3_FORCE_PATH_STYLEUse path-style addressing. Required for MinIO and some on-prem stores.
The export sink is the supported route to long-term audit archive.

KMS-Backed CA Keys

By default, CA signing keys live in the cluster database, AES-256-GCM encrypted with the key derived from MEZITE_CA_KEY_PASSPHRASE. For higher assurance — and for managed deployments — the cluster can be configured so that every CA signing operation calls AWS KMS instead, with the raw private key material never leaving the KMS HSM boundary.

FieldTypeDefaultEnv VarDescription
kms.enabledbooleanfalseMEZITE_KMS_ENABLEDRoute CA signing through AWS KMS. When on, both kms.region and kms.alias_prefix are required (validated at startup).
kms.regionstring""MEZITE_KMS_REGIONAWS region the KMS keys live in (e.g. eu-west-2).
kms.alias_prefixstring""MEZITE_KMS_ALIAS_PREFIXPrefix used when building per-tenant KMS aliases. Must not start with alias/ (the CA layer prepends it) and must end with -. The final alias shape is alias/<prefix><tenant>-<ca-type>.
--string--MEZITE_KMS_EXTRA_TAGSComma-separated key=value pairs to apply on KMS CreateKey for each new CA key. Used by the managed plane to attach the tenant tag the per-tenant IAM policy keys off of.

Managed Mode

Set on cloud-managed tenants. When on, the cluster fails to start unless kms.enabled is also true — managed tenants are required to sign with KMS-backed keys so the platform operator can revoke a tenant out-of-band. Leave this off for self-hosted deployments.

FieldTypeDefaultEnv VarDescription
managed_mode (top-level)booleanfalseMEZITE_MANAGED_MODEEnable managed-tenant behaviour. Forces kms.enabled=true; refuses to boot otherwise.

Client Tools

The client version this cluster expects, published on the unauthenticated GET /v1/webapi/ping endpoint. msh reads it at login and reports when the binary in the user's hand is behind — see Client version compatibility. It is advisory: the cluster does not refuse older clients, and nothing is ever installed or changed on a user's machine.

FieldTypeDefaultEnv VarDescription
client_tools.modestringenabledMEZITE_CLIENT_TOOLS_MODEenabled publishes the policy; disabled tells clients to leave their own version alone. Use disabled where client binaries are owned by a package manager or a configuration-management system.
client_tools.target_versionstringautoMEZITE_CLIENT_TOOLS_TARGET_VERSIONThe client version this cluster expects. auto tracks the running server's own version, so upgrading mezhub is enough — there is no second value to keep in step.
client_tools.min_versionstring(unset)MEZITE_CLIENT_TOOLS_MIN_VERSIONThe oldest client version this cluster supports. Clients below it get a warning rather than a hint. Leave unset to advertise no floor.
Pinning an explicit client version yaml
client_tools:
  mode: enabled
  target_version: 0.2.24   # or "auto" to track this server's version
  min_version: 0.2.20

A version that is neither auto nor a MAJOR.MINOR.PATCH version is rejected at start-up rather than at the first client request, so a typo surfaces immediately. So is a min_version above an explicit target_version, which would tell clients to install a version the same policy then refuses to support.


Moderation and Access Requests

FieldTypeDefaultEnv VarDescription
moderation.transfer_approval_timeoutduration5mMEZITE_TRANSFER_APPROVAL_TIMEOUTHow long the proxy waits for moderator approval on an SFTP transfer before denying. Capped at 5 minutes — the agent enforces the same ceiling locally, so a longer value would let the agent deny a transfer the proxy still considers pending.
--duration7dMEZITE_ACCESS_REQUEST_MAX_DURATIONMaximum duration an access-request grant can be issued for. A request asking for a longer window is rejected; a shorter window is honoured as-is.
--duration24hMEZITE_HOST_CERT_TTLTTL on agent host certificates. Lower values shorten the window an attacker who exfiltrates a node's signing material can keep impersonating that host. An unparseable or non-positive value falls back to the 24h default rather than failing the boot.

Workload Identity (mezd identity)

The mezd identity daemon runs on a workload node, exposes a Unix socket that local workloads can call to fetch short-lived X.509/JWT SPIFFE SVIDs, and renews those SVIDs on a timer. These knobs are read by mezd identity only, not by mezhub.

VariableRequiredDescription
MEZITE_IDENTITY_TOKENYesBootstrap join token used to authenticate the daemon to mezhub on first start.
MEZITE_IDENTITY_DIRNoDirectory holding the persisted identity material between renewals.
MEZITE_IDENTITY_TTLNoRequested SVID TTL (server may clamp lower).
MEZITE_IDENTITY_RENEWAL_INTERVALNoHow often the daemon renews. Should be well under MEZITE_IDENTITY_TTL.
MEZITE_IDENTITY_ONE_SHOTNoRun a single renewal and exit. Useful for CI helpers and Machine ID-style use cases where another process holds the SVID lifecycle.
MEZITE_WORKLOAD_SOCKETNoPath of the Unix socket workloads connect to. Default /var/run/mezite/workload.sock.

Bootstrap and Operations

VariableDescription
MEZITE_ADMIN_PASSWORDWhen set on first boot, seeds the bootstrap admin account with this password. After the cluster is initialised the variable can be removed; subsequent admin accounts are created via mezctl users create.
MEZITE_BOOTSTRAP_JOIN_TOKENWhen set on first boot, creates a node-role join token with this value so an initial mezd can register without first invoking mezctl tokens create.
MEZITE_DATA_DIROverride for the on-disk data directory (default /var/lib/mezite) used by SQLite, local recordings, and the join-state file.
MEZITE_METRICS_ADDRWhen set (e.g. :9100), exposes a Prometheus /metrics endpoint on the given address.
MEZITE_METRICS_TOKENOptional bearer token required to scrape the metrics endpoint. Leave unset to expose metrics without authentication on an internal listener.
MEZITE_HTTPSAFE_ALLOW_PRIVATE / MEZITE_HTTPSAFE_ALLOW_LOOPBACKTest-and-dev overrides for the outbound HTTP allowlist that normally blocks mezhub from calling private or loopback addresses (used by OIDC discovery, SAML metadata, webhook sinks). Off in production.

Port Reference

PortProtocolComponentDescription
3025gRPCAuth ServiceInternal auth API. Should not be exposed publicly.
3080HTTPSProxy ServiceWeb UI, REST API, OIDC callbacks.
3023SSHProxy ServiceSSH client connections via msh.
3024gRPCProxy ServiceAgent reverse-tunnel connections.
5432PostgreSQLDatabaseState store (only when using PostgreSQL backend).

Agent Configuration

The mezd binary is configured entirely via environment variables.

VariableRequiredDescription
MEZITE_JOIN_TOKENYes (first run)One-time join token. Only needed on first join.
MEZITE_AUTH_ADDRYesAddress of the Auth service (e.g. mezite.example.com:3025).
MEZITE_PROXY_ADDRYesAddress of the Proxy tunnel listener (e.g. mezite.example.com:3024).
MEZITE_NODE_NAMENoNode name shown in msh ls. Defaults to hostname.
MEZITE_NODE_LABELSNoComma-separated key=value labels for RBAC matching (e.g. env=prod,role=web).
MEZITE_DATA_DIRNoData directory for identity and recordings. Default: /var/lib/mezite.
MEZITE_RECORDING_MODENoPer-agent override for recording mode: node (async upload after session) or node-sync (real-time streaming to the auth service, the cluster default). Leave unset so the agent follows the cluster-wide session_recording setting instead. See Session Recording.
MEZITE_TLS_WRAPNoWrap tunnel connection in TLS. Required when connecting through a TLS-terminating load balancer. See Reverse Proxy.
MEZITE_BPF_ENABLEDNoEnable eBPF enhanced recording (Linux only, requires privileged mode). Captures command executions in addition to terminal I/O.
MEZITE_PAM_SERVICENoPAM service name for session hooks (Linux only).
MEZITE_AUTH_H2CNoRun gRPC auth in h2c (HTTP/2 cleartext) mode. Use when a TLS-terminating load balancer sits in front (Fly.io, ALB, Istio/Linkerd service mesh). Also suitable for local development.
Agent startup example bash
MEZITE_JOIN_TOKEN=d4f8a2e1-7b3c-4d9e-a5f6-1234567890ab \
MEZITE_AUTH_ADDR=mezite.example.com:3025 \
MEZITE_PROXY_ADDR=mezite.example.com:3024 \
MEZITE_NODE_NAME=web-server-01 \
MEZITE_NODE_LABELS="env=production,role=webserver" \
mezd start

Environment Variables

VariableConfig EquivalentDescription
MEZITE_CLUSTER_NAMEcluster_nameCluster name
MEZITE_DB_DRIVERdatabase.driverDatabase backend (sqlite or postgres)
MEZITE_DB_URLdatabase.urlConnection URL (file path for SQLite, DSN for PostgreSQL)
MEZITE_DB_HOSTdatabase.hostPostgreSQL host
MEZITE_DB_PORTdatabase.portPostgreSQL port
MEZITE_DB_USERdatabase.userPostgreSQL user
MEZITE_DB_PASSWORDdatabase.passwordPostgreSQL password
MEZITE_DB_NAMEdatabase.namePostgreSQL database name
MEZITE_DB_SSLMODEdatabase.sslmodePostgreSQL TLS mode
MEZITE_LOG_LEVELlog.levelLog verbosity
MEZITE_LOG_FORMATlog.formatLog format (json or text)
MEZITE_CA_KEY_PASSPHRASEca_key_passphrase (top-level)CA private key encryption passphrase
MEZITE_AUTH_H2C-Run gRPC in h2c mode (required behind a TLS-terminating LB). Process-level env var read directly by mezhub at startup; not a config-file field.
MEZITE_GRPC_ALLOW_HTTPauth.grpc_allow_httpAllow plaintext h2c on the gRPC listener (also enabled by MEZITE_AUTH_H2C).
MEZITE_PROXY_PUBLIC_ADDRproxy.public_addrPublic proxy address. Derives the WebAuthn RP ID/origin and the GetServerInfo enrollment URL; the OIDC issuer URL is set separately via MEZITE_OIDC_ISSUER_URL.
MEZITE_OIDC_ISSUER_URLproxy.oidc_issuer_urlPublic issuer URL surfaced at /.well-known/openid-configuration. No trailing slash.
MEZITE_AUDIT_HMAC_KEYaudit_hmac_key (top-level)Hex-encoded HMAC key for the audit-log tamper-detection chain.
MEZITE_RECORDING_BACKENDrecording.backendRecording storage backend: local (default) or s3
MEZITE_S3_BUCKETrecording.s3.bucketS3 bucket for recording storage
MEZITE_S3_REGIONrecording.s3.regionS3 region (default: us-east-1)
MEZITE_S3_ENDPOINTrecording.s3.endpointCustom S3 endpoint (for MinIO or other S3-compatible stores)
MEZITE_RECORDING_ENC_KEYrecording_enc_key (top-level)32-byte hex-encoded AES-256 key for recording encryption at rest
Example: SQLite with env vars (simplest self-hosted) bash
MEZITE_CLUSTER_NAME=production \
MEZITE_DB_DRIVER=sqlite \
MEZITE_DB_URL=/var/lib/mezite/mezhub.db \
MEZITE_LOG_LEVEL=info \
MEZITE_CA_KEY_PASSPHRASE='another-secret' \
mezhub
Example: PostgreSQL with env vars bash
MEZITE_CLUSTER_NAME=production \
MEZITE_DB_HOST=db.internal.example.com \
MEZITE_DB_PORT=5432 \
MEZITE_DB_USER=mezite \
MEZITE_DB_PASSWORD='hunter2' \
MEZITE_DB_NAME=mezite \
MEZITE_DB_SSLMODE=verify-full \
MEZITE_LOG_LEVEL=info \
MEZITE_LOG_FORMAT=json \
MEZITE_CA_KEY_PASSPHRASE='another-secret' \
mezhub

Production Config

SSO connectors are not configured in mezite.yaml — create them at runtime with mezctl connectors create once the hub is up. See the SSO Guide.

mezite.yaml — production yaml
cluster_name: production

log:
  level: info
  format: json

database:
  driver: postgres
  host: db.internal.example.com
  port: 5432
  user: mezite
  # password set via MEZITE_DB_PASSWORD
  name: mezite
  sslmode: verify-full

# ca_key_passphrase set via MEZITE_CA_KEY_PASSPHRASE

proxy:
  public_addr: mezite.example.com:443
  listen_addr: 0.0.0.0:3080
  ssh_listen_addr: 0.0.0.0:3023
  tunnel_listen_addr: 0.0.0.0:3024
  oidc_issuer_url: https://mezite.example.com

ssh:
  enabled: false  # dedicated proxy node, not an SSH target

Next Steps

  • Quickstart — Apply this configuration in a working setup.
  • Architecture — Understand how auth, proxy, and agent components interact.
  • SSH Access Guide — Deep dive into SSH certificate authentication and session recording.
  • SSO Guide — Configure OIDC or SAML authentication.
  • Application Access — Publish internal web and TCP apps using the proxy.apps_* settings above.