Skip to Content
DocsAdmin GuideConfiguration

Configuration

Quazzar Cloud OS is configured through two files:

FileFormatWhat it holds
/etc/quazzar/quazzar.envKEY=value linesEnvironment variables for quazzar.service. The full list is in Environment variables.
/etc/quazzar/quazzar.yamlYAMLServer, data, database, proxy and logging settings. Environment variables of the same setting override it.

Configuration File

quazzar.service reads /etc/quazzar/quazzar.env through systemd’s EnvironmentFile=. Edit it with:

sudo nano /etc/quazzar/quazzar.env

Changes apply after a restart:

sudo systemctl restart quazzar

The file uses systemd’s format: one KEY=value per line, no export, no spaces around =, # starts a comment. Shell syntax such as $HOME is not expanded.

What the package installs

The quazzar package (.deb or .rpm) installs /etc/quazzar/quazzar.env as a template, owned by root:quazzar with mode 0640. Every variable the node reads is listed there, commented out, with its default value and a one-line explanation. To change a setting, uncomment its line and edit the value.

Only these lines are active after a fresh install:

QUAZZAR_ADDR=:8080 # legacy, not read (see below) QUAZZAR_DATA_DIR=/var/lib/quazzar QUAZZAR_LOG_LEVEL=info DOCKER_HOST=unix:///var/run/docker.sock

QUAZZAR_JWT_SECRET is commented out: the node generates its own random session secret. Older packages shipped an active QUAZZAR_JWT_SECRET=CHANGE_ME placeholder; see JWT signing secret for what happens to it now.

QUAZZAR_ADDR is still in the file so existing files stay unchanged, but current releases do not read it. Set the listen port with QUAZZAR_PORT or server.port in quazzar.yaml.

Preserved on upgrade

/etc/quazzar/quazzar.env and /etc/quazzar/quazzar.yaml are package configuration files: dpkg conffiles on Debian/Ubuntu, %config(noreplace) on RPM distros.

  • If you have not edited the file, an upgrade replaces it with the new template. Your active lines are the same as before, and new variables appear as commented-out lines.
  • If you have edited the file, an upgrade keeps your copy and saves the new template next to it as quazzar.env.dpkg-dist (Debian/Ubuntu) or quazzar.env.rpmnew (RPM). Compare the two with diff to see new variables.

The in-app updater and install.sh keep your copy without asking. A manual sudo apt upgrade asks what to do about a changed configuration file: press Enter (the default, N) to keep yours.


JWT signing secret

The JWT signing secret signs session cookies. By default you do not set it: the node generates a random secret on first start and persists it to disk at $QUAZZAR_DATA_DIR/jwt-secret (default /var/lib/quazzar/jwt-secret, mode 0600), so sessions survive apt upgrade and restarts.

Set QUAZZAR_JWT_SECRET only to pin a secret, for example when your orchestrator manages it. It must be at least 32 random characters:

QUAZZAR_JWT_SECRET=<output of: openssl rand -hex 32>

A strong value set in the environment wins and the file is ignored. A weak value is ignored: the node logs an error and uses the persisted random secret instead. Weak means, after trimming whitespace and ignoring case, a known placeholder (CHANGE_ME, changeme, change-me, secret, <64-byte hex string>), empty, or shorter than 32 characters.

Older packages shipped an active QUAZZAR_JWT_SECRET=CHANGE_ME. Because that value is public, anyone could forge session tokens on a node that kept it. The package upgrade comments that exact line out in /etc/quazzar/quazzar.env (a real secret is never touched), and quazzard ignores it even if it is still there. Check a node with:

grep JWT_SECRET /etc/quazzar/quazzar.env

Changing the secret invalidates every existing access token. On a node, the browser’s refresh token usually signs people back in without a prompt; pages may reload. Back up /var/lib/quazzar/jwt-secret before any host migration. If the placeholder was ever active, see Security hardening → If the placeholder was ever active.


Passkey domain

Passkeys are tied to a domain (the WebAuthn relying-party ID). By default Cloud OS uses the reverse proxy’s base domain when the browser is on that domain or one of its subdomains, and the exact host name otherwise. To use a different shared parent domain, set:

QUAZZAR_WEBAUTHN_RP_ID=example.com

A passkey registered at os.example.com then also works at home.example.com. Passkeys never work on bare IP addresses or on plain http://, except for localhost. See Sign-in & Lock Screen.


Reverse Proxy

Cloud OS includes a built-in Caddy reverse proxy that provides automatic HTTPS and subdomain-based routing for installed apps. When configured with a base domain like cloud.example.com, an app named “nextcloud” becomes accessible at nextcloud.cloud.example.com.

DNS requirements for automatic HTTPS:

  1. A record for your base domain pointing to the server IP
  2. Wildcard A record (*.cloud.example.com) pointing to the same IP
  3. Ports 80 and 443 open

If you use an external reverse proxy (nginx, Traefik, Cloudflare Tunnel), disable the built-in proxy and route traffic to the Cloud OS port directly. If that proxy runs on another machine, add it to trusted_proxies (below), or every client will look like the proxy to the sign-in rate limits.

Trusted proxies

Cloud OS identifies the client of a request — for sign-in rate limits (password, 2FA, passkey, QR, approve-on-another-device, cluster join), session records and audit entries — by the TCP address the connection comes from. It believes an X-Forwarded-For / X-Real-IP header only when that connection comes from a trusted proxy; from anyone else the header is ignored, so it can’t be used to dodge rate limits or forge audit IPs.

The default trusts loopback only (127.0.0.0/8, ::1), which covers the bundled Caddy. To trust a load balancer or a proxy on another host:

server: trusted_proxies: ["127.0.0.0/8", "::1/128", "10.0.5.20", "172.17.0.0/16"]

or QUAZZAR_TRUSTED_PROXIES=127.0.0.0/8,::1/128,10.0.5.20. Entries are IP addresses or CIDR ranges; none trusts no proxy at all. Behind several trusted hops, the client is the right-most X-Forwarded-For entry that is not itself a trusted proxy. An invalid entry stops the service at startup.

Caddy admin unix socket

The managed Caddy process now binds its admin endpoint to a unix socket at /var/run/quazzar-caddy-admin.sock instead of 127.0.0.1:2019. This avoids a port collision with the distro caddy.service that ships with some Debian / Ubuntu variants.

On every start, Quazzar best-effort stops the distro caddy.service to reclaim ports 80 and 443. If Quazzar is offline (or crashed) when you SSH in, you can restart it safely with:

sudo systemctl restart quazzar.service

When the managed Caddy’s admin socket is missing at reload time, the service falls back to a full Stop + Start instead of returning exit status 1. If you see reload failures on older installs, upgrade to 0.6.34 or later.

Troubleshooting: if both quazzar.service and caddy.service are enabled, caddy.service grabs port 80 first at boot. Quazzar then fails its Caddy start. Disable the distro service:

sudo systemctl disable --now caddy.service sudo systemctl mask caddy.service

Semantic search (Ollama)

The Memory MCP server uses a local Ollama instance to compute embeddings for hybrid search. Configure with:

# Ollama host URL (default: the managed Ollama container, else http://127.0.0.1:11434) OLLAMA_HOST=http://127.0.0.1:11434 # Embedding model (default: nomic-embed-text, 768 dims) MCP_EMBED_MODEL=nomic-embed-text

Pull the default model once before first use:

ollama pull nomic-embed-text

If Ollama is unreachable at boot the service logs semantic search disabled (no embedding backend) and falls back to lexical-only ranking. Every Memory MCP tool keeps working; only the cosine term of the hybrid score is dropped.

Keep OLLAMA_HOST on loopback (127.0.0.1 or localhost) to prevent embedding queries leaving your node. Pointing it at a remote host sends your note content to that host on every memory_create / memory_update.

See Memory MCP for the full surface.


Memory search mode

The Memory MCP search engine supports three operating modes, controlled by:

# Values: legacy | shadow | hybrid_v2 (default: shadow) MEMORY_SEARCH_MODE=shadow
ModeBehaviour
legacyOriginal linear weighted-sum ranking (cosine*0.55 + lexical*0.35 + importance*0.10) over a LIKE-substring candidate pull.
shadowDefault. Returns the legacy ranking to the caller. Simultaneously computes the new FTS5/BM25 + RRF + link-boost + synonym ranking and logs both results plus their overlap count to the search_comparisons SQLite table. Use this to evaluate the new ranker before activating it.
hybrid_v2Activates the new ranker: FTS5/BM25 with Porter stemmer, RRF fusion with intent-adaptive alpha, wiki-graph link-boost, and synonym query expansion. The legacy path is no longer computed.

Recommended rollout:

  1. Run in shadow mode (the default) for a period that covers your typical query variety.
  2. Query search_comparisons to review divergence between the two rankers:
    SELECT query, overlap_count, legacy_top_ids, v2_top_ids, created_at FROM search_comparisons ORDER BY overlap_count ASC -- lowest overlap = biggest change LIMIT 20;
  3. If divergence looks good (higher-quality results), flip to hybrid_v2:
    MEMORY_SEARCH_MODE=hybrid_v2 sudo systemctl restart quazzar.service

The search_comparisons table is truncated automatically when it exceeds 10 000 rows (oldest first) to prevent unbounded growth.


Predictive Insights alerts

The Predictive Insights subsystem scores four predictors (resource anomaly, capacity forecast, backup health, app health) on an hourly cycle. Detection and on-demand serving (MCP tool, REST endpoint, dashboard card) are on by default.

Proactive push notifications — Molly alerting you without being asked, when a predictor scores high risk — are off by default and must be opted in:

# Enable proactive Molly alerts for high-risk predictions (default: false) QUAZZAR_INSIGHTS_ALERTS=true

When enabled, the alert system respects a per-predictor dedup window: a high-risk disk-capacity alert fires at most once per hour. If the risk level is unchanged in the next scoring cycle, no duplicate notification is sent.

All four predictors can raise an alert; there is no per-predictor setting.

See Predictive Insights for a full description of the predictors and their honest-refusal behaviour.


Control Center agent listener TLS

CC_AGENT_TLS_CERT, CC_AGENT_TLS_KEY and CC_AGENT_EXTERNAL_DOMAINS are Control Center settings (in /etc/quazzar/control-center.env), not node settings. They choose the server certificate of the agent mTLS listener (CC_AGENT_ADDR, default :8443) that nodes connect to:

# Externally issued certificate + key (PEM), e.g. a wildcard for your CC domain CC_AGENT_TLS_CERT=/var/lib/quazzar-cc/certs/server.crt CC_AGENT_TLS_KEY=/var/lib/quazzar-cc/certs/server.key # Extra DNS names for the certificate generated when no cert exists CC_AGENT_EXTERNAL_DOMAINS=cc.example.com,agents.example.com

When the certificate file does not exist, the Control Center issues one from its own CA, covering localhost, the host’s IP addresses and the names in CC_AGENT_EXTERNAL_DOMAINS. If that path is read-only, it falls back to a temporary location and logs a warning instead of failing. See CP CA Rotation for rotating the CA itself.


Service Management

Cloud OS runs as a systemd service. Common management commands:

# Check status sudo systemctl status quazzar.service # Start / stop / restart sudo systemctl start quazzar.service sudo systemctl stop quazzar.service sudo systemctl restart quazzar.service # View logs sudo journalctl -u quazzar.service -f

Database Read Replica

For high-traffic deployments, the Control Panel supports routing read-only queries to a PostgreSQL read replica.

Configuration

Set the CC_DATABASE_READ_URL environment variable to your read replica connection string:

CC_DATABASE_READ_URL="postgres://user:pass@replica-host:5432/quazzar_cc?sslmode=require"

When configured:

  • Read operations (listing instances, viewing dashboards, fetching analytics) use the read replica
  • Write operations (creating resources, updating settings, issuing commands) use the primary database

If CC_DATABASE_READ_URL is not set, all queries go to the primary database configured via CC_DATABASE_URL.

Ensure your read replica is kept in sync with the primary database. The Control Panel does not manage replication — configure streaming replication or logical replication at the PostgreSQL level.

Control Center workflow HTTP steps

An http step of a Control Center AI workflow (AI → Workflows) is a URL written by a workspace member and fetched from inside the Control Center’s network. To stop it from reaching internal services, the Control Center refuses — after DNS resolution, and again for every redirect — any address that isn’t public: loopback (127.0.0.0/8, ::1), private (10/8, 172.16/12, 192.168/16, fc00::/7 including fd00::/8), link-local (169.254.0.0/16 — the cloud metadata address 169.254.169.254 — and fe80::/10), carrier-grade NAT (100.64.0.0/10), multicast, reserved and NAT64 / 6to4 ranges. Only http and https URLs are allowed, the step never goes through an HTTP proxy, and a name that resolves to both a public and a private address is refused. A refused step fails with destination not allowed for workflow http steps.

To let workflows call an internal receiver (a webhook relay, a self-hosted chat server…), list it in CC_WORKFLOW_HTTP_ALLOWLIST — comma-separated CIDRs, IP addresses or host names:

CC_WORKFLOW_HTTP_ALLOWLIST="10.20.0.0/16, 192.168.1.10, hooks.internal.example"

An allow-listed host name may resolve to any address; a redirect from it to another target is checked again. The allow-list is a Control Center setting on purpose, not a workspace one: on a shared Control Center a workspace must not be able to open the Control Center’s own network to itself. Restart the Control Center after changing it.


Environment variables

Every variable the node reads, grouped the same way as the packaged /etc/quazzar/quazzar.env. Set them in that file and run sudo systemctl restart quazzar. “Unset” means the feature is off or the value is derived as described. Variables marked yaml override the same setting in /etc/quazzar/quazzar.yaml.

AI and Memory kill-switches are on unless set to off, 0, false, no, disable or disabled.

Server & paths

VariableDefaultDescription
QUAZZAR_CONFIG/etc/quazzar/quazzar.yamlPath to the YAML config file.
QUAZZAR_HOST0.0.0.0Listen address of the web UI / API (yaml server.host).
QUAZZAR_PORT8080Listen port of the web UI / API (yaml server.port).
QUAZZAR_TRUSTED_PROXIESloopback onlyComma-separated IPs / CIDRs whose X-Forwarded-For is trusted; none trusts no proxy (yaml server.trusted_proxies). See Trusted proxies.
QUAZZAR_DATA_DIR/var/lib/quazzarData directory: database, app data, backups, jwt-secret (yaml data.dir).
QUAZZAR_DB_PATH/var/lib/quazzar/quazzar.dbSQLite database file (yaml database.path).
QUAZZAR_ADMIN_SOCKET<data dir>/run/admin.sockLocal admin socket used by sudo quazzar-cli admin ….
QUAZZAR_ADDR—Legacy, not read. Use QUAZZAR_PORT.

Logging & tracing

VariableDefaultDescription
QUAZZAR_LOG_LEVELinfodebug, info, warn or error (yaml logging.level).
QUAZZAR_LOG_FORMATprettypretty or json (yaml logging.format).
QUAZZAR_OTEL_ENDPOINTunsetOpenTelemetry OTLP endpoint; tracing is off while unset.
QUAZZAR_OTEL_SERVICE_NAMEquazzar-osService name reported in traces.

Authentication & secrets

VariableDefaultDescription
QUAZZAR_JWT_SECRET/var/lib/quazzar/jwt-secretSession signing secret. Unset or weak (placeholder, under 32 characters): a random secret is generated once and kept in the data directory. See JWT signing secret.
QUAZZAR_WEBAUTHN_RP_IDproxy base domain or request hostPasskey relying-party id. See Passkey domain.
QUAZZAR_SECRETS_KEYunsetPassphrase for the key that encrypts stored secrets. Unset: a random key kept in QUAZZAR_SECRETS_KEYFILE. Changing it makes already stored secrets unreadable.
QUAZZAR_SECRETS_KEYFILE/etc/quazzar/secrets.keyWhere the random secrets key is kept.
QUAZZAR_GEOIP_DBunsetOffline MaxMind GeoLite2 / GeoIP2 City .mmdb; adds the city to sign-in events (yaml auth.geoip_db).
QUAZZAR_MCP_SERVICE_TOKENunsetShared token for internal service calls (X-Service-Auth header) made by the MCP outbound tools. Unset: service auth is off.
HCAPTCHA_SECRETunsethCaptcha secret for public forms; captcha is off while unset.

Reverse proxy (Caddy)

VariableDefaultDescription
QUAZZAR_PROXY_ENABLEDfalsetrue or 1 enables the built-in Caddy reverse proxy (yaml proxy.enabled; the variable can only switch it on).
QUAZZAR_PROXY_BASE_DOMAINunsetBase domain; apps get <app>.<base domain> (yaml proxy.base_domain).
QUAZZAR_PROXY_HTTPSfalsetrue or 1 enables automatic HTTPS via Let’s Encrypt; needs a public domain (yaml proxy.https; the variable can only switch it on).
QUAZZAR_PROXY_ADMIN_EMAILunsetLet’s Encrypt account email (yaml proxy.admin_email).
QUAZZAR_PROXY_CADDY_PATHcaddyCaddy binary (yaml proxy.caddy_path).

Docker & app import

VariableDefaultDescription
DOCKER_HOSTunix:///var/run/docker.sockDocker daemon socket. The standard Docker client variables (DOCKER_API_VERSION, DOCKER_CERT_PATH, DOCKER_TLS_VERIFY) work too.
CASAOS_ROOTauto-detectedCasaOS root scanned by the app importer (/var/lib/casaos or /DATA).
UMBREL_ROOTauto-detectedUmbrel root scanned by the app importer (/home/umbrel/umbrel or /opt/umbrel).

Control Center & telemetry

VariableDefaultDescription
CC_BASE_URLhttps://cp.quazzar.cloudControl Center URL the node fetches release notes from.
CC_TELEMETRY_URLhttps://cp.quazzar.cloud/api/v1/telemetryAnonymous telemetry endpoint.
CC_NODE_IDControl Center instance id, else localNode id used for Memory MCP sync.
QUAZZAR_REGIONcloud metadataRegion reported to the Control Center.
QUAZZAR_ZONEcloud metadataZone reported to the Control Center.

Cluster & HA

VariableDefaultDescription
QUAZZAR_NODE_IDrandom n-xxxxxxxxCluster node id, used only on the first start (then stored).
QUAZZAR_CLUSTER_ADVERTISELAN IPAddress other members use to reach this node.
QUAZZAR_CLUSTER_NO_WGunset1 / true skips host WireGuard setup when the network already links the members.
QUAZZAR_RAFT_ADDRchosen on joinRaft bind address (host:port). When set, Raft starts at boot.

AI (Molly)

VariableDefaultDescription
QUAZZAR_AI_ROUTERonComplexity router and model tiering.
QUAZZAR_AI_LOOP_CONTROLonAgent-loop nudges, closing gate and directive scrubber.
QUAZZAR_AI_SPEND_CAPonDaily / per-user spend caps.
QUAZZAR_AI_INTEGRITYonResponse integrity checks. See AI Response Integrity.
QUAZZAR_AI_CHANNEL_RECOVERYonResume in-flight channel requests after a restart. See AI Resilience.
QUAZZAR_AI_CHANNEL_DEDUPonDrop duplicate inbound channel messages.
QUAZZAR_AI_CANARYonPeriodic AI health check.
QUAZZAR_AI_CANARY_INTERVAL4hCanary period (Go duration, minimum 5m).
QUAZZAR_AI_CANARY_PROVIDERautoProvider check: auto, prompt, list or off.
QUAZZAR_AI_TOOL_SEARCHonDeferred tool loading (hot set + tool_search). off always sends the full catalogue.
QUAZZAR_AI_TOOL_SCHEMA_VALIDATEonNormalise tool schemas before serving them.
QUAZZAR_AI_TOOL_SEARCH_THRESHOLD20Deferred loading starts above this many tools.
QUAZZAR_AI_TOOL_SEARCH_HOT10Tools always visible (pinned + most used).
QUAZZAR_AI_TOOL_SEARCH_TOPK5Schemas returned per tool_search call (max 10).
QUAZZAR_AI_TOOL_SEARCH_SEED5Tools pre-loaded from the user’s message; 0 disables.
QUAZZAR_INSIGHTS_ALERTSfalseProactive Molly alerts for high-risk predictions (true or 1). See Predictive Insights alerts.
QUAZZAR_VOICE_HOME~/.quazzar/models of the service userWhere voice models are stored.
QUAZZAR_VOICE_MIRRORunsetDownload mirror that replaces https://github.com in voice model URLs (air-gapped installs).

Memory MCP

VariableDefaultDescription
OLLAMA_HOSTmanaged Ollama, else http://127.0.0.1:11434Ollama URL for embeddings. See Semantic search.
MCP_EMBED_MODELnomic-embed-textEmbedding model.
MEMORY_SEARCH_MODEshadowlegacy, shadow or hybrid_v2. See Memory search mode.
QUAZZAR_AI_MEMORY_PII_GUARDonStore-time PII guard (block / quarantine).
QUAZZAR_AI_MEMORY_TIERSonVisibility-tier classification and filtering.
QUAZZAR_AI_MEMORY_CONFIDENCEonFeedback-based confidence and ranking nudges.
QUAZZAR_AI_MEMORY_USAGEonRecord which memories fed a reply.
QUAZZAR_AI_MEMORY_HEALERonDaily knowledge healer.
QUAZZAR_AI_MEMORY_GAPSonKnowledge-gap logging.
QUAZZAR_AI_MEMORY_PII_LLMoffA node-local model confirms health / HR detail about a named person. Only on, 1, true, yes, enable(d) turn it on.
QUAZZAR_AI_MEMORY_PII_LLM_MODELlocal provider’s first modelModel used by QUAZZAR_AI_MEMORY_PII_LLM.

Install-time variables

These are read by the package installer (quazzar-setup) during apt install / dnf install, not by the service, so they have no effect in quazzar.env:

VariableDefaultDescription
QUAZZAR_COMPONENTSdefaultsComponent choice, e.g. "-mail,docker=keep". Same as install.sh --components. See Components.
QUAZZAR_DEFER_SETUPunset1 skips the component step in the package scripts (install.sh runs it itself afterwards).

Control Center

The Control Center reads /etc/quazzar/control-center.env, installed by the quazzar-control-center package the same way: a commented template listing every variable below, kept on upgrade. Apply changes with sudo systemctl restart quazzar-control-center.

The template ships with these active lines: CC_ADDR=:9090, CC_DATABASE_URL=postgres://quazzar:changeme@localhost:5432/quazzar_cc?sslmode=disable, and CC_LOG_LEVEL=info. Change the Postgres password (changeme is a published placeholder) in the database and in this line. CC_JWT_SECRET is commented out: like the node, the Control Center generates a random session secret and keeps it in $CC_DATA_DIR/jwt-secret. An unset or placeholder CC_JWT_SECRET uses that file (a placeholder is logged as an error), and the package upgrade comments out an exact CC_JWT_SECRET=CHANGE_ME line. The Control Center fails closed: a value you set that is shorter than 32 characters, or a data directory it cannot read or write, stops it at start with a message naming CC_DATA_DIR and the volume to mount. Pin a value of 32+ random characters only when several Control Center replicas must share it. Changing the secret signs every Control Center user out once. The audit log’s HMAC key is CC_AUDIT_HMAC_KEY if set (32+ characters, shorter stops the Control Center), else CC_JWT_SECRET if it is strong, else a random key in $CC_DATA_DIR/audit-hmac-key. A workspace whose log was written with a placeholder key gets one audit.rekeyed entry. Which workspaces get it is fixed once, outside the database: when the Control Center creates $CC_DATA_DIR/audit-hmac-key (the first start after leaving the placeholder), or on the start with CC_AUDIT_MIGRATE_PLACEHOLDER=1, it lists the eligible workspaces with their newest entry in audit-placeholder-pending (or audit-placeholder-migrated) before writing any entry, and later starts only retry listed workspaces whose newest entry is unchanged. Verification starts at the audit.rekeyed entry and lists older entries as unverifiable. Any other mismatch, including a log re-signed with a placeholder later, is reported as tampering.

Unless CC_AUDIT_HMAC_KEY is set, rotating CC_JWT_SECRET also changes the audit key, and every existing audit entry then fails verification. Before rotating, set CC_AUDIT_HMAC_KEY to the current CC_JWT_SECRET value and restart, then change CC_JWT_SECRET.

CC_ADDR, CC_LOG_LEVEL, CC_HETZNER_TOKEN and CC_DO_TOKEN are legacy and not read: the API listens on CC_API_ADDR, default :8080.

VariableDefaultDescription
Listeners
CC_API_ADDR:8080HTTP API / web UI listen address.
CC_AGENT_ADDR:8443Agent mTLS listener that nodes connect to.
CC_CORS_ORIGINSunsetComma-separated origins allowed by CORS (* for any). Unset: no CORS headers.
Database
CC_DATABASE_URLpostgres://quazzar:quazzar@localhost:5432/quazzar_cc?sslmode=requirePostgreSQL connection.
CC_DB_SSL_MODEunsetReplaces the sslmode= of CC_DATABASE_URL.
CC_DATABASE_READ_URLunsetRead replica for read-only queries. See Database Read Replica.
Authentication & secrets
CC_JWT_SECRET$CC_DATA_DIR/jwt-secretSession signing secret. Unset or a placeholder: a random secret is generated once and kept in the data dir. A set value under 32 characters stops the Control Center. Pin 32+ random characters (openssl rand -hex 32) when replicas must share it.
CC_AUDIT_HMAC_KEYCC_JWT_SECRET, else $CC_DATA_DIR/audit-hmac-keyKey of the audit log’s HMAC chain, 32+ characters (shorter stops the Control Center). Unset: a strong CC_JWT_SECRET, else a random key kept in the data dir. Set it to the current CC_JWT_SECRET before rotating that secret.
CC_AUDIT_MIGRATE_PLACEHOLDERunsetOne-shot. Set to 1 for the upgrade start if you replaced CHANGE_ME with a strong CC_JWT_SECRET (or set CC_AUDIT_HMAC_KEY) yourself, and remove it after a start logs placeholder migration complete. That start lists the workspaces whose log was signed with a placeholder in $CC_DATA_DIR/audit-placeholder-migrated, then writes their audit.rekeyed entries; a workspace that fails (logged at error level) is retried on the next start from that list, with or without the variable. With a persistent CC_DATA_DIR the file also makes later starts ignore the variable; without one (for example Helm without cpState.persistent) a later start would take a new list, so remove the variable after the upgrade start. To run it again, delete audit-placeholder-migrated and set the variable for one more start. Not needed when the Control Center creates audit-hmac-key itself: it writes audit-placeholder-pending before creating the key and finishes the same migration from it, even if that first start fails. Workspaces that cannot be listed are logged at error level and left for manual review.
CC_DATA_DIR$STATE_DIRECTORY, else /var/lib/quazzar-cpLocal state directory (jwt-secret, audit-hmac-key), used when CC_JWT_SECRET is unset or a placeholder. It must then be persistent and writable, or the Control Center does not start: systemd StateDirectory=quazzar-cp in the package, the cc-state volume in Docker Compose. With a strong CC_JWT_SECRET (required by the Helm chart) it is not needed.
CC_SETTINGS_ENCRYPTION_KEYunsetExactly 32 bytes; encrypts sensitive settings at rest.
CC_TOKEN_REFRESH_GRACE1hHow long after expiry a token may still be refreshed (Go duration).
CC_TOTP_REQUIRE_MFA_TOKENtrueThe TOTP sign-in step requires the token from the password step (always for staff); false relaxes it for customer accounts.
Public URLs
CC_PUBLIC_BASE_URLrequest / CC_API_ADDRBrowser-facing URL: SSO / OIDC issuer, enroll command, passkey origin.
CC_BASE_URLhttp://localhost:5173URL used in e-mailed links (invites, verification) and admin impersonation.
CC_PORTAL_CNAME_TARGEThost of CC_PUBLIC_BASE_URL / CC_BASE_URLCNAME target shown for custom portal domains.
Admin console security keys
CC_ADMIN_URLunsetAdmin console URL; its host becomes the relying-party id and an allowed origin.
CC_WEBAUTHN_ORIGINSdev originsExtra allowed origins (comma-separated).
CC_WEBAUTHN_RPIDhost of CC_ADMIN_URL, else localhostRelying-party id override.
CC_WEBAUTHN_CC_RPIDunsetRelying-party id for security keys used in the Control Center itself.
Certificates & agent mTLS
CC_CA_KEY_PATH/var/lib/quazzar-cc/certs/ca.keyCA key that signs node client certificates.
CC_CA_CERT_PATH/var/lib/quazzar-cc/certs/ca.crtCA certificate.
CC_ED25519_KEY_PATH/var/lib/quazzar-cc/certs/license.keyLicense signing key (generated when missing).
CC_ALLOW_AUTO_CA_GENfalsetrue generates a new CA when none is found. Dev / first bootstrap only: a new CA invalidates every registered node’s certificate.
CC_TRUST_ADDITIONAL_CA_CERTSunsetPrevious CA certificates still trusted during a rotation (comma-separated paths). See CP CA Rotation.
CC_AGENT_TLS_CERT / CC_AGENT_TLS_KEY<CA dir>/server.crt / server.keyAgent listener certificate; issued from the CA when missing. See Control Center agent listener TLS.
CC_SERVER_CERT_PATH / CC_SERVER_KEY_PATH—Older names of CC_AGENT_TLS_CERT / CC_AGENT_TLS_KEY.
CC_AGENT_EXTERNAL_DOMAINSunsetExtra DNS names in the generated agent certificate.
CC_AGENT_REQUIRE_CLIENT_CERTfalseRequire a client certificate on the agent listener.
Processes & HA
CC_DISABLE_WORKERfalsetrue on API pods when a dedicated worker runs the billing jobs.
CC_DISABLE_AGENT_SERVERfalsetrue on worker pods so they do not open the agent listener.
CC_WORKER_ID<hostname>-<pid>Worker id recorded on jobs.
CP_METRICS_JANITORonMetrics rollup janitor; 0 disables it.
CC_HA_MODEstandalonestandalone or cluster. cluster requires the three variables below.
CC_NODE_ID / CC_RAFT_ADDR / CC_RAFT_DATA_DIRunsetRaft node id, bind address and data directory for CC_HA_MODE=cluster.
Billing & e-mail
CC_STRIPE_SECRET_KEYunsetStripe secret key; Stripe is off while unset.
CC_STRIPE_WEBHOOK_SECRETunsetStripe webhook signing secret.
CC_STRIPE_PUBLIC_KEYunsetStripe publishable key.
CC_GMAIL_CLIENT_ID / CC_GMAIL_CLIENT_SECRET / CC_GMAIL_REFRESH_TOKEN / CC_GMAIL_FROMunsetOutgoing mail through the Gmail API (OAuth2).
Sign-in with Google / GitHub
CC_SSO_GOOGLE_CLIENT_ID / CC_SSO_GOOGLE_CLIENT_SECRETunsetCP-wide Google sign-in, on when both are set.
CC_SSO_GITHUB_CLIENT_ID / CC_SSO_GITHUB_CLIENT_SECRETunsetCP-wide GitHub sign-in, on when both are set.
Storage
MARKETPLACE_STORAGElocalMarketplace package storage: local, s3 or r2.
MARKETPLACE_LOCAL_ROOT / MARKETPLACE_LOCAL_URL_PREFIX/var/lib/quazzar-cp/marketplace/…Local disk root and public URL prefix.
MARKETPLACE_S3_BUCKET / _ENDPOINT / _ACCESS_KEY / _SECRET_KEY / _URL_PREFIXunsetS3 / R2 bucket, endpoint (R2), credentials and public URL prefix.
MARKETPLACE_S3_REGIONautoS3 region.
MARKETPLACE_S3_KEY_PREFIXskillsObject key prefix.
MARKETPLACE_S3_PATH_STYLEtruePath-style bucket addressing.
COMPLIANCE_LOCAL_ROOT / COMPLIANCE_LOCAL_URL_PREFIX/var/lib/quazzar-cp/compliance/…Where compliance reports are written, and their URL prefix.
Mobile push
CP_FCM_SERVICE_ACCOUNT_PATHunsetFirebase service-account JSON (Android). See Mobile Push Setup.
CP_APNS_KEY_PATH / CP_APNS_KEY_ID / CP_APNS_TEAM_ID / CP_APNS_BUNDLE_IDunsetApple Push .p8 key and ids (iOS).
Fleet, workflows & observability
CC_TERMINAL_IDLE_TIMEOUT15mNode web terminal idle timeout.
CC_TERMINAL_MAX_SESSION2hNode web terminal maximum session length.
CC_WORKFLOW_HTTP_ALLOWLISTunsetPrivate addresses workflow http steps may reach. See workflow HTTP steps.
CC_AUTOSCALE_REGISTER_URLhttps://app.quazzar.cloud/api/cluster/registerRegistration URL handed to autoscaled nodes.
CC_OTEL_ENDPOINTunsetOpenTelemetry OTLP endpoint; tracing is off while unset.
CC_OTEL_SERVICE_NAMEquazzar-ccService name reported in traces.

The separate billing worker binary (cmd/worker, not part of the package) also reads CC_DATABASE_URL, the three CC_STRIPE_* keys, CC_RABBITMQ_URL (default amqp://guest:guest@localhost:5672/) and CC_RABBITMQ_QUEUE_PREFIX (default quazzar_cc).

Tips

  • Keep backups of /etc/quazzar/quazzar.env before making changes.
  • Use journalctl -u quazzar to troubleshoot startup issues after configuration changes.
  • Restart the service (sudo systemctl restart quazzar) after editing the environment file for changes to take effect.
  • After an upgrade, diff /etc/quazzar/quazzar.env /etc/quazzar/quazzar.env.dpkg-dist (or .rpmnew) shows variables added since your copy was written.