arizuko › reference › Environment variables
environment variables
Every env var read by an arizuko Go or TypeScript daemon, with the file:line that reads it, type, default, and one-line effect. Generated from a grep of os.Getenv, chanlib.EnvOr/EnvInt/EnvBool/EnvBytes/EnvDur/MustEnv, and process.env[] across the repo. Test-only env vars omitted.
chanlib.EnvOr(k, d) returns d when the env var is empty or unset. chanlib.MustEnv(k) calls os.Exit(1) if unset. chanlib.EnvDur(k, d) reads integer milliseconds (legacy encoding) — not Go duration strings. Adapter LISTEN_ADDR code-defaults vary per daemon, but every service TOML in template/services/ pins :8080; the multi-daemon local-dev numbers (9001–9010) appear here only because that's what the source defaults to.core — consumed by every Go daemon via core.LoadConfig
These are read in core/config.go through chanlib.EnvOr / EnvInt / EnvDur and the resolveTimezone() helper. Every daemon that calls core.LoadConfig() (routd, onbod, webd, …) inherits this surface.
API_PORT
Listening port for routd's HTTP API.
| Read by | core / core/config.go:135 → routd |
|---|---|
| Type | int |
| Default | 8080 |
| Example | 8080 |
ARIZUKO_DEV
Dev mode — allows empty CHANNEL_SECRET and bind-mounts ant/src into spawned agent containers for live-reload of the in-container runner.
| Read by | core / core/config.go:168, container / container/runner.go:498 |
|---|---|
| Type | bool ("true" or "1") |
| Default | unset = production mode |
| Example | 1 |
ASSISTANT_NAME
Bot display name and mention trigger; also baked into the data-dir basename and compose container_name. Must contain no whitespace or shell metachars.
| Read by | core / core/config.go:102, webd / webd/main.go:42, teled / teled/main.go:63, discd / discd/main.go:70, whapd / whapd/src/main.ts:41 |
|---|---|
| Type | string |
| Default | Andy (core); assistant in webd; empty in teled/discd |
| Example | Andy |
AUTH_BASE_URL
Public base URL used to build OAuth redirect callbacks and onboarding invite links. HTTPS prefix toggles secure-cookie flag.
| Read by | core / core/config.go:115 |
|---|---|
| Type | URL |
| Default | "" |
| Example | https://krons.arizuko.com |
AUTH_SECRET
At-rest sealing key. Comma-separated to rotate: the first key seals new writes, the rest decrypt-only (retired keys kept so values sealed under an old key still read during rotation). This is not the JWT signing key — JWTs are signed with ES256 via authd’s keypair, not HMAC.
| Read by | core / core/config.go:173 |
|---|---|
| Type | string (hex/random) |
| Default | "" |
| Example | a3f1...c0de |
CHANNEL_SECRET
Bearer secret authenticating adapter ↔ routd traffic. Required in production; empty allowed only with ARIZUKO_DEV. Individual adapters can override per platform with <DAEMON>_CHANNEL_SECRET (e.g. SLAKD_CHANNEL_SECRET). routd binds whatever bearer the adapter registers with to that channel record, so a leaked per-platform secret does not compromise the others. See specs/7/H.
| Read by | core / core/config.go:136, webd / webd/main.go:39, teled / teled/main.go:60, discd / discd/main.go:67, mastd / mastd/main.go:56, bskyd / bskyd/main.go:57, reditd / reditd/main.go:72, emaid / emaid/main.go:63, linkd / linkd/main.go:65, slakd / slakd/main.go:60, whapd / whapd/src/main.ts:155, twitd / twitd/src/main.ts:42 |
|---|---|
| Type | string |
| Default | "" (refuses to start unless ARIZUKO_DEV set) |
| Example | e8c2...4b9a |
CONTAINER_IMAGE
Docker image used to spawn per-group agent containers.
| Read by | core / core/config.go:107 |
|---|---|
| Type | string |
| Default | arizuko-ant:latest |
| Example | arizuko-ant:v0.35.0 |
CONTAINER_TIMEOUT
Hard kill timeout per agent run, in milliseconds.
| Read by | core / core/config.go:108 |
|---|---|
| Type | int (milliseconds, via EnvDur) |
| Default | 3600000 (60 min) |
| Example | 1800000 |
CRACKBOX_ADMIN_API
Crackbox admin HTTP base URL. Non-empty enables egress isolation; runed requires EGRESS_NETWORK_PREFIX + EGRESS_CRACKBOX when set.
| Read by | core / core/config.go:158, compose / compose/compose.go:258 |
|---|---|
| Type | URL |
| Default | "" (egress isolation off) |
| Example | http://crackbox:3129 |
CRACKBOX_ADMIN_SECRET
Bearer token for crackbox admin API mutations. Sent by runed as the egress controller; consumed by crackbox.
| Read by | core / core/config.go:161, crackbox host / crackbox/pkg/host/host.go:105 |
|---|---|
| Type | string |
| Default | "" |
| Example | 7f...22 |
CRACKBOX_PROXY_URL
Value injected as HTTPS_PROXY / HTTP_PROXY into every agent container.
| Read by | core / core/config.go:159 |
|---|---|
| Type | URL |
| Default | http://crackbox:3128 |
| Example | http://crackbox:3128 |
DATA_DIR
Root of this instance's data directory (store/, groups/, ipc/, web/). When set in compose, also passes through to dashd, timed, and several adapters as their working/storage root.
| Read by | core / core/config.go:99, dashd / dashd/main.go:67, timed / timed/main.go:26, teled / teled/main.go:54, bskyd / bskyd/main.go:60, reditd / reditd/main.go:75, emaid / emaid/main.go:66, linkd / linkd/main.go:68, whapd / whapd/src/main.ts:42, twitd / twitd/src/main.ts:28 |
|---|---|
| Type | path |
| Default | cwd (core); /srv/data/<daemon> per adapter |
| Example | /srv/data/arizuko_krons |
DISCORD_CLIENT_ID
OAuth client id for the Discord login provider in proxyd's auth flow (distinct from the bot token used by discd).
| Read by | core / core/config.go:118 |
|---|---|
| Type | string |
| Default | "" |
| Example | 1234567890 |
DISCORD_CLIENT_SECRET
OAuth client secret for the Discord login provider.
| Read by | core / core/config.go:119 |
|---|---|
| Type | string |
| Default | "" |
| Example | abc...def |
EGRESS_CRACKBOX
Container name of the crackbox proxy; runed attaches it to every per-folder docker network.
| Read by | core / core/config.go:157, compose generation / compose/compose.go:266 |
|---|---|
| Type | string |
| Default | "" (compose generation derives <app>_crackbox_<flavor>) |
| Example | arizuko_crackbox_krons |
EGRESS_NETWORK_PREFIX
Docker network name prefix; per-folder networks created as <prefix>_<folder>.
| Read by | core / core/config.go:156, compose generation / compose/compose.go:259 |
|---|---|
| Type | string |
| Default | "" (compose generation derives arizuko_<flavor>) |
| Example | arizuko_krons |
EGRESS_SUBNET
Parent CIDR carved into per-folder /24s for egress networks.
| Read by | core / core/config.go:160 |
|---|---|
| Type | CIDR string |
| Default | 10.99.0.0/16 |
| Example | 10.42.0.0/16 |
GITHUB_ALLOWED_ORG
If set, restricts GitHub OAuth sign-in to members of this org.
| Read by | core / core/config.go:123 |
|---|---|
| Type | string |
| Default | "" |
| Example | kronael |
GITHUB_CLIENT_ID
OAuth client id for the GitHub login provider.
| Read by | core / core/config.go:116 |
|---|---|
| Type | string |
| Default | "" |
| Example | Iv1.abc123 |
GITHUB_CLIENT_SECRET
OAuth client secret for the GitHub login provider.
| Read by | core / core/config.go:117 |
|---|---|
| Type | string |
| Default | "" |
| Example | ghs_xxxxx |
GOOGLE_ALLOWED_EMAILS
CSV allowlist of email addresses permitted to complete Google OAuth.
| Read by | core / core/config.go:122 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | alice@example.com,bob@example.com |
GOOGLE_CLIENT_ID
OAuth client id for the Google login provider.
| Read by | core / core/config.go:120 |
|---|---|
| Type | string |
| Default | "" |
| Example | abc.apps.googleusercontent.com |
GOOGLE_CLIENT_SECRET
OAuth client secret for the Google login provider.
| Read by | core / core/config.go:121 |
|---|---|
| Type | string |
| Default | "" |
| Example | GOCSPX-xxx |
HOST_APP_DIR
Path on the host that contains the arizuko binaries and ant/src; used when bind-mounting the dev runner.
| Read by | core / core/config.go:101, compose / compose/compose.go:461 |
|---|---|
| Type | path |
| Default | directory of the running executable |
| Example | /home/onvos/app/arizuko |
HOST_CODEX_DIR
Host path bind-mounted into agent containers at /home/node/.codex so the oracle skill can reuse the operator's codex login state.
| Read by | core / core/config.go:133 |
|---|---|
| Type | path |
| Default | "" (mount disabled; falls back to CODEX_API_KEY/OPENAI_API_KEY folder secrets) |
| Example | /home/onvos/.codex |
HOST_DATA_DIR
Host-side path used when constructing volume mounts for spawned containers. Differs from DATA_DIR only when arizuko runs inside a container itself.
| Read by | core / core/config.go:100 |
|---|---|
| Type | path |
| Default | DATA_DIR |
| Example | /srv/data/arizuko_krons |
IDLE_TIMEOUT
How long an idle agent container is kept around before recycling, in milliseconds.
| Read by | core / core/config.go:109 |
|---|---|
| Type | int (milliseconds) |
| Default | 3600000 (60 min) |
| Example | 600000 |
MAX_CONCURRENT_CONTAINERS
Max agent containers running at once before runed queues spawns.
| Read by | core / core/config.go:110 |
|---|---|
| Type | int |
| Default | 5 |
| Example | 10 |
MEDIA_ENABLED
Enables inbound media download and forwarding to the agent. Adapters fall back to URL-only references when off.
| Read by | core / core/config.go:143 |
|---|---|
| Type | bool ("true") |
| Default | false |
| Example | true |
MEDIA_MAX_FILE_BYTES
Per-attachment byte cap on inbound media; adapter ProxyFile streams up to this size before truncation.
| Read by | core / core/config.go:144, teled / teled/main.go:65, discd / discd/main.go:71, mastd / mastd/main.go:59, bskyd / bskyd/main.go:61, reditd / reditd/main.go:76, emaid / emaid/main.go:67, slakd / slakd/main.go:63 |
|---|---|
| Type | int (bytes) |
| Default | 20971520 (20 MiB) |
| Example | 52428800 |
ONBOARDING_ENABLED
Master switch for the onboarding flow. Affects both routd behaviour and whether compose generates the onbod service.
| Read by | core / core/config.go:137, onbod / onbod/main.go:55 ("0" → exit 0), compose / compose/compose.go:326 |
|---|---|
| Type | bool (core: "true"; onbod: "0" disables) |
| Default | false |
| Example | true |
ONBOARDING_PLATFORMS
CSV of platforms (e.g. telegram,discord) for which onboarding admissions are enabled.
| Read by | core / core/config.go:138 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | telegram,whatsapp |
OBSERVE_WINDOW_MESSAGES
How many trailing #observe-mode messages routd folds into context when a trigger turn fires. Per-route override via routes.observe_window_messages.
| Read by | core / core/config.go:151, routd |
|---|---|
| Type | int |
| Default | 10 |
| Example | 25 |
OBSERVE_WINDOW_CHARS
Character cap on the #observe context window for a single trigger turn. Per-route override via routes.observe_window_chars.
| Read by | core / core/config.go:152, routd |
|---|---|
| Type | int (chars) |
| Default | 4000 |
| Example | 8000 |
ENGAGEMENT_TTL
How long a (chat, topic) stays “engaged” after the bot’s last reply. Engaged pairs fire a turn on every inbound message without needing a fresh @mention, and override #observe routing. TTL is sliding — reset on each user or bot message while engaged. See engagement.
| Read by | core / core/config.go:217 → routd |
|---|---|
| Type | duration (e.g. 10m, 30m) |
| Default | 20m |
| Example | 30m |
SECRETS_KEY
AES-256-GCM key for the secrets table — secrets are encrypted at rest. Required: routd refuses to start without it, and there is no plaintext mode and no AUTH_SECRET fallback. The value is a comma-separated keyring: the first key seals new writes, the rest are decrypt-only (retired keys kept around so values sealed under an old key still read during rotation). On boot routd migrates any legacy-plaintext rows in place under the active key. arizuko create generates a random key into the new instance’s .env; the arizuko secret CLI uses the same keyring. Stored values carry a v2: prefix.
| Read by | core / core/config.go:123 → routd, arizuko secret CLI |
|---|---|
| Type | string (comma-separated keyring; first = active seal key) |
| Default | none — routd exits if unset; arizuko create generates one |
| Example | 9d4f...new,2a17...retired |
SEND_DISABLED_CHANNELS
CSV of channel names where outbound sends are dropped (read-only mode).
| Read by | core / core/config.go:140 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | mastodon,bluesky |
SEND_DISABLED_GROUPS
CSV of group folders where outbound sends are dropped (read-only mode).
| Read by | core / core/config.go:141 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | solo/inbox,corp/eng |
TELEGRAM_BOT_TOKEN
Bot token for the Telegram channel adapter.
| Read by | core / core/config.go:106, teled / teled/main.go:58 (MustEnv) |
|---|---|
| Type | string |
| Default | "" (teled refuses to start) |
| Example | 12345:ABC-DEF1234ghIkl-zyx57W2v1u123ew11 |
TTS_BASE_URL
OpenAI-compatible /v1/audio/speech base URL the agent's send_voice path hits.
| Read by | core / core/config.go:151 |
|---|---|
| Type | URL |
| Default | http://ttsd:8880 |
| Example | http://ttsd:8880 |
TTS_ENABLED
Enables TTS rendering of agent replies as voice messages.
| Read by | core / core/config.go:150 |
|---|---|
| Type | bool ("true") |
| Default | false |
| Example | true |
TTS_MODEL
Default model name passed in the TTS request body.
| Read by | core / core/config.go:153 |
|---|---|
| Type | string |
| Default | kokoro |
| Example | kokoro |
TTS_TIMEOUT
Per-request timeout when calling the TTS backend, in milliseconds.
| Read by | core / core/config.go:154 |
|---|---|
| Type | int (milliseconds) |
| Default | 15000 (15 s) |
| Example | 30000 |
TTS_VOICE
Instance-default voice id; agent may override per-call via send_voice args or per-group via PERSONA.md frontmatter.
| Read by | core / core/config.go:152 |
|---|---|
| Type | string |
| Default | af_bella |
| Example | af_sky |
TZ
IANA timezone for log timestamps, cron evaluation in timed, and Config.Timezone consumers.
| Read by | core / core/config.go:192, timed / timed/main.go:36, compose / compose/compose.go:490 |
|---|---|
| Type | string (IANA name) |
| Default | UTC |
| Example | Europe/Bratislava |
VIDEO_TRANSCRIPTION_ENABLED
Enables Whisper transcription of inbound video.
| Read by | core / core/config.go:147 |
|---|---|
| Type | bool ("true") |
| Default | false |
| Example | true |
VOICE_TRANSCRIPTION_ENABLED
Enables Whisper transcription of inbound voice messages.
| Read by | core / core/config.go:146 |
|---|---|
| Type | bool ("true") |
| Default | false |
| Example | true |
WEB_HOST
Public hostname the instance serves; used to build chat-link, webhook, and onboarding URLs in agent prompts.
| Read by | core / core/config.go:114 |
|---|---|
| Type | string |
| Default | "" |
| Example | krons.arizuko.com |
WHISPER_BASE_URL
Base URL of the Whisper-compatible transcription endpoint.
| Read by | core / core/config.go:145 |
|---|---|
| Type | URL |
| Default | http://localhost:8080 |
| Example | http://whisper:9000 |
WHISPER_MODEL
Model name passed to Whisper.
| Read by | core / core/config.go:148 |
|---|---|
| Type | string |
| Default | turbo |
| Example | large-v3 |
container — agent spawn (read by runed when building runs)
ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, OPENAI_API_KEY, and CODEX_API_KEY pick which model a spawn talks to, so they are user-scoped credentials, not folder secrets — the store rejects them at folder scope. A user sets their own in a dedicated dashboard section at /dash/me/env, and that value overrides the operator default for their spawns. The host .env value below is the instance-wide default forwarded when a user has set nothing. See secrets.ANTHROPIC_API_KEY
Instance default forwarded into every spawned agent container so Claude Code can authenticate, unless the triggering user has set their own at /dash/me/env.
| Read by | container / container/runner.go:617 |
|---|---|
| Type | string |
| Scope | user (env-profile key; rejected at folder scope) |
| Default | not forwarded if unset |
| Example | sk-ant-... |
CLAUDE_CODE_OAUTH_TOKEN
Alternative auth for Claude Code; forwarded into the container alongside ANTHROPIC_API_KEY, same user-override rule.
| Read by | container / container/runner.go:617 |
|---|---|
| Type | string |
| Scope | user (env-profile key; rejected at folder scope) |
| Default | not forwarded if unset |
| Example | cc-oauth-... |
LOG_LEVEL
Sets the stderr slog level (debug < info < warn < error) for every daemon, applied by obs.Setup at startup. Additionally, in runed debug/trace dumps full container stderr + mounts after every spawn.
| Read by | every daemon via obs.Setup; container-run verbose dump / container/runner.go:891 |
|---|---|
| Type | string (debug/info/warn/error/trace) |
| Default | info |
| Example | debug |
chanreg
CHANNEL_REGISTER_ALLOW_PUBLIC
Dev override that lets channel adapters register with public IPs. By default chanreg rejects non-private adapter URLs as SSRF risk.
| Read by | chanreg / chanreg/chanreg.go:222 |
|---|---|
| Type | bool ("1") |
| Default | unset = enforce private-only |
| Example | 1 |
arizuko CLI (cmd/arizuko)
ARIZUKO_DATA_DIR
Override the base directory used to construct instance data paths. When set, instance dir is $ARIZUKO_DATA_DIR/arizuko_<name>.
| Read by | cli / cmd/arizuko/main.go:151 |
|---|---|
| Type | path |
| Default | "" (falls back to PREFIX) |
| Example | /var/lib/arizuko |
PREFIX
Filesystem prefix for instance data dirs; final path is $PREFIX/data/arizuko_<name>.
| Read by | cli / cmd/arizuko/main.go:154 |
|---|---|
| Type | path |
| Default | /srv |
| Example | /srv |
arizuko run (compose generation)
Read by compose/compose.go at arizuko run time when it generates the docker-compose YAML. These are not consumed by any running daemon — only by the generator that decides which services to emit, which ports to expose, and which proxyd routes to gate.
DAV_PORT
Host port to expose for davd. Empty ⇒ davd not exposed at the docker level.
| Read by | compose / compose/compose.go:564 |
|---|---|
| Type | string (port) |
| Default | "" |
| Example | 8096 |
PROFILE
Compose profile selector. minimal drops the dashd routes and other non-essential services; full includes everything.
| Read by | compose / compose/compose.go:306 |
|---|---|
| Type | string (minimal / full) |
| Default | full |
| Example | minimal |
WEB_PORT
Host port the proxyd service is published on; the public entry point for the instance.
| Read by | compose / compose/compose.go:530 |
|---|---|
| Type | string (port) |
| Default | 8095 |
| Example | 443 |
WEB_PORT_ALIASES
CSV of additional host ports also published for proxyd (e.g. expose 80 alongside 443).
| Read by | compose / compose/compose.go:536 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | 80,8080 |
WEBDAV_ENABLED
Whether to emit the davd service and gate its /dav/ proxyd route.
| Read by | compose / compose/compose.go:323 (and as a route gate at :186) |
|---|---|
| Type | bool ("true") |
| Default | true |
| Example | false |
routd
routd has no direct env reads — every value comes from core.LoadConfig above. The crackbox/egress validation lives in the runed startup check: if CRACKBOX_ADMIN_API is set, both EGRESS_NETWORK_PREFIX and EGRESS_CRACKBOX must also be set or the daemon exits (runed owns the docker spawn + crackbox attach).
proxyd
PROXYD_HMAC_SECRET retired
Retired. The HMAC identity-header model is gone. proxyd no longer signs an X-User-Sig header; it proves the channel to each backend with an authd-minted ES256 bearer pinned to service:proxyd, verified by auth.ProxydTransit in auth/middleware.go. No shared secret to set. See auth concept.
PROXYD_LISTEN
Port proxyd binds to. Plain numbers get a : prefix.
| Read by | proxyd / proxyd/main.go:42 |
|---|---|
| Type | string (port or :port) |
| Default | 8080 |
| Example | 8080 |
PROXYD_ROUTES_JSON
Aggregated route table generated at compose time from every adapter's TOML [[proxyd_route]] entries.
| Read by | proxyd / proxyd/main.go:59 |
|---|---|
| Type | JSON string |
| Default | "" (falls back to legacy built-in routes) |
| Example | [{"prefix":"/dash/","backend":"http://dashd:8080","auth":"user"},…] |
PUB_REDIRECT_URL
If set, proxyd redirects /pub/* requests to this base URL instead of serving them locally — lets a CDN front the static docs.
| Read by | proxyd / proxyd/main.go:57 |
|---|---|
| Type | URL |
| Default | "" (proxyd serves /pub/ itself) |
| Example | https://docs.arizuko.com |
TRUSTED_PROXIES
CSV of CIDRs (or bare IPs) trusted to set X-Forwarded-For. Empty ⇒ no client trusted, XFF always replaced with the connection peer.
| Read by | proxyd / proxyd/main.go:60 |
|---|---|
| Type | CSV string (CIDRs / IPs) |
| Default | "" |
| Example | 10.0.0.0/8,172.16.0.0/12 |
VITE_ADDR
Backend address proxyd forwards /pub/* (and chat widget) traffic to.
| Read by | proxyd / proxyd/main.go:56 |
|---|---|
| Type | URL |
| Default | http://vited:8080 |
| Example | http://vited:8080 |
webd
ROUTER_URL
Base URL of routd; webd posts inbound web chat and webhook messages to $ROUTER_URL/v1/messages.
| Read by | webd / webd/main.go:38 — see also ROUTER_URL in adapters |
|---|---|
| Type | URL |
| Default | http://routd:8080 |
| Example | http://routd:8080 |
WEBD_LISTEN
Address webd binds to.
| Read by | webd / webd/main.go:36 |
|---|---|
| Type | listen addr (:port or host:port) |
| Default | :8080 |
| Example | :8080 |
WEBD_URL
Public URL webd advertises to routd when registering as a channel.
| Read by | webd / webd/main.go:37 |
|---|---|
| Type | URL |
| Default | http://webd:8080 |
| Example | http://webd:8080 |
onbod
ONBOARD_POLL_INTERVAL
Cadence at which onbod scans for unprompted users / admission queue entries.
| Read by | onbod / onbod/main.go:147 |
|---|---|
| Type | Go duration string (time.ParseDuration) |
| Default | 10s |
| Example | 30s |
ONBOARDING_GREETING
Custom greeting string injected into onboarding prompts in place of the default copy.
| Read by | onbod / onbod/main.go:142 |
|---|---|
| Type | string |
| Default | "" |
| Example | Welcome to krons. |
ONBOD_LISTEN_ADDR
Address onbod binds to.
| Read by | onbod / onbod/main.go:144 |
|---|---|
| Type | listen addr |
| Default | :8080 |
| Example | :8080 |
onbod additionally reads ONBOARDING_ENABLED ("0" → clean exit) and ROUTER_URL via core. It trusts X-User-* headers only behind the proxyd transit bearer (auth.ProxydTransit); on its mixed public/authed invite routes an unproven request is treated as anonymous rather than rejected.
dashd
DASH_PORT
Port dashd binds to. Plain numbers get a : prefix.
| Read by | dashd / dashd/main.go:79, compose / compose/compose.go:523 |
|---|---|
| Type | string |
| Default | :8080 |
| Example | :8080 |
DB_PATH
SQLite DSN dashd opens read-only (with a separate RW handle for /dash/me/secrets writes). Falls back to $DATA_DIR/store/messages.db.
| Read by | dashd / dashd/main.go:70 |
|---|---|
| Type | path |
| Default | $DATA_DIR/store/messages.db (refuses to start if both unset) |
| Example | /srv/data/arizuko_krons/store/messages.db |
SURROGATE_GITHUB_CLIENT_ID
OAuth app client id for the surrogate “Connect GitHub” flow at /dash/me/connections — arizuko authenticating as the user against GitHub's API, not a user signing in to arizuko. Distinct from GITHUB_CLIENT_ID, the login provider. Unset hides the GitHub connection option; the user falls back to pasting a GITHUB_TOKEN at /dash/me/secrets.
| Read by | dashd / dashd/main.go:284 |
|---|---|
| Type | string |
| Default | "" |
| Example | Iv1.def456 |
SURROGATE_GITHUB_CLIENT_SECRET
OAuth app client secret paired with SURROGATE_GITHUB_CLIENT_ID.
| Read by | dashd / dashd/main.go:284 |
|---|---|
| Type | string |
| Default | "" |
| Example | ghs_yyyyy |
timed
DATABASE
SQLite DSN timed opens to poll scheduled_tasks. Falls back to $DATA_DIR/store/messages.db.
| Read by | timed / timed/main.go:28 |
|---|---|
| Type | path |
| Default | $DATA_DIR/store/messages.db (refuses to start if both unset) |
| Example | /srv/data/arizuko_krons/store/messages.db |
timed also reads DATA_DIR and TZ (for cron evaluation).
ttsd
TTSD_ADDR
Address ttsd binds to.
| Read by | ttsd / ttsd/main.go:31 |
|---|---|
| Type | listen addr |
| Default | :8880 |
| Example | :8880 |
TTS_BACKEND_URL
Upstream Kokoro/OpenAI-compatible TTS server ttsd proxies to.
| Read by | ttsd / ttsd/main.go:32 |
|---|---|
| Type | URL |
| Default | http://kokoro:8880 |
| Example | http://kokoro:8880 |
ttsd also reads LOG_LEVEL.
Adapter common surface
Every channel adapter shares the same set of plumbing env vars:
CHANNEL_NAME
Name the adapter registers with routd; routing uses this verbatim. Has a per-daemon default.
| Read by | teled :55, discd :64, mastd :52, bskyd :52, reditd :64, emaid :55, linkd :59, slakd :56 |
|---|---|
| Type | string |
| Default | matches the platform (telegram, discord, mastodon, …) |
| Example | telegram-prod |
LISTEN_ADDR
Address the adapter binds for its outbound-send HTTP server (routd → adapter).
| Read by | teled :61 (:9001), discd :68 (:9002), whapd :156 (:9002), mastd :57 (:9004), emaid :64 (:9003), bskyd :58 (:9005), reditd :73 (:9006), linkd :66 (:9010), slakd :61 (:8080), twitd :43 (:8080) |
|---|---|
| Type | listen addr |
| Default | varies (see column above; :8080 when pinned by service TOML) |
| Example | :8080 |
LISTEN_URL
URL the adapter advertises to routd on registration so routd can reach it.
| Read by | teled :62, discd :69, whapd :157, mastd :58, emaid :65, bskyd :59, reditd :74, linkd :67, slakd :62, twitd :44 |
|---|---|
| Type | URL |
| Default | http://<daemon>:<port> |
| Example | http://teled:9001 |
ROUTER_URL
Base URL of routd where the adapter posts inbound messages.
| Read by | teled :59 (MustEnv), discd :66 (MustEnv), whapd :154, mastd :55 (MustEnv), emaid :62 (MustEnv), bskyd :56 (MustEnv), reditd :71 (MustEnv), linkd :64 (MustEnv), slakd :59 (MustEnv), twitd :41, webd :38, onbod :143 |
|---|---|
| Type | URL |
| Default | required in most adapters (MustEnv); webd/onbod default to http://routd:8080 |
| Example | http://routd:8080 |
All adapters additionally read CHANNEL_SECRET and most read MEDIA_MAX_FILE_BYTES.
teled (Telegram)
Reads TELEGRAM_BOT_TOKEN (MustEnv), ASSISTANT_NAME, DATA_DIR, plus the adapter common surface. No teled-specific env vars beyond these.
discd (Discord)
DISCORD_BOT_TOKEN
Bot token. Required unless DISCORD_USER_TOKEN is set instead.
| Read by | discd / discd/main.go:52 |
|---|---|
| Type | string |
| Default | "" (refuses to start if both bot/user tokens empty) |
| Example | MTAxNTM4... |
DISCORD_USER_TOKEN
User-account token; selects user-mode operation, bypassing bot intents. Mutually exclusive with the bot token.
| Read by | discd / discd/main.go:53 |
|---|---|
| Type | string |
| Default | "" |
| Example | mfa.xxxxx |
whapd (WhatsApp)
WHATSAPP_AUTH_DIR
Directory where Baileys multi-file auth state (creds, keys) is persisted.
| Read by | whapd / whapd/src/main.ts:44 |
|---|---|
| Type | path |
| Default | $DATA_DIR/store/whatsapp-auth or /srv/data/store/whatsapp-auth |
| Example | /srv/data/arizuko_krons/store/whatsapp-auth |
whapd also reads ASSISTANT_NAME, DATA_DIR, ROUTER_URL, CHANNEL_SECRET, LISTEN_ADDR, LISTEN_URL.
mastd (Mastodon)
MASTODON_ACCESS_TOKEN
App access token for the configured Mastodon instance.
| Read by | mastd / mastd/main.go:54 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | abcDEF... |
MASTODON_FILE_CACHE_SIZE
LRU size of cached attachment IDs (prevents reprocessing).
| Read by | mastd / mastd/main.go:65 |
|---|---|
| Type | int |
| Default | 1000 |
| Example | 5000 |
MASTODON_INSTANCE_URL
Base URL of the Mastodon instance the adapter streams from.
| Read by | mastd / mastd/main.go:53 (MustEnv) |
|---|---|
| Type | URL |
| Default | required |
| Example | https://mastodon.social |
bskyd (Bluesky)
BLUESKY_IDENTIFIER
AT Protocol handle or DID the adapter logs in as.
| Read by | bskyd / bskyd/main.go:53 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | arizuko.bsky.social |
BLUESKY_PASSWORD
App password for the Bluesky account.
| Read by | bskyd / bskyd/main.go:54 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | xxxx-xxxx-xxxx-xxxx |
BLUESKY_SERVICE
PDS endpoint to authenticate against.
| Read by | bskyd / bskyd/main.go:55 |
|---|---|
| Type | URL |
| Default | https://bsky.social |
| Example | https://bsky.social |
reditd (Reddit)
REDDIT_CLIENT_ID
OAuth client id of the registered Reddit app.
| Read by | reditd / reditd/main.go:65 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | abc123 |
REDDIT_CLIENT_SECRET
OAuth client secret of the registered Reddit app.
| Read by | reditd / reditd/main.go:66 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | xyz789 |
REDDIT_PASSWORD
Password for the bot account (script OAuth flow).
| Read by | reditd / reditd/main.go:68 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | hunter2 |
REDDIT_POLL_INTERVAL
How often reditd polls subreddits for new posts/comments.
| Read by | reditd / reditd/main.go:77 |
|---|---|
| Type | Go duration string |
| Default | 5m |
| Example | 2m |
REDDIT_SUBREDDITS
CSV of subreddit names to monitor.
| Read by | reditd / reditd/main.go:58 |
|---|---|
| Type | CSV string |
| Default | "" |
| Example | selfhosted,homelab |
REDDIT_USER_AGENT
User-Agent string used in Reddit API calls (Reddit policy requires a descriptive UA).
| Read by | reditd / reditd/main.go:70 |
|---|---|
| Type | string |
| Default | arizuko/1.0 |
| Example | arizuko-krons/1.0 by u/op |
REDDIT_USERNAME
Username of the bot account.
| Read by | reditd / reditd/main.go:67 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | arizuko_bot |
emaid (Email)
EMAIL_ACCOUNT
Email address / IMAP+SMTP login username.
| Read by | emaid / emaid/main.go:58 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | bot@example.com |
EMAIL_IMAP_HOST
IMAP server hostname.
| Read by | emaid / emaid/main.go:56 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | imap.gmail.com |
EMAIL_IMAP_PORT
IMAP server port.
| Read by | emaid / emaid/main.go:60 |
|---|---|
| Type | string (port) |
| Default | 993 |
| Example | 993 |
EMAIL_PASSWORD
Login password / app password for IMAP+SMTP.
| Read by | emaid / emaid/main.go:59 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | xxxx xxxx xxxx xxxx |
EMAIL_SMTP_HOST
SMTP server hostname.
| Read by | emaid / emaid/main.go:57 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | smtp.gmail.com |
EMAIL_SMTP_PORT
SMTP server port.
| Read by | emaid / emaid/main.go:61 |
|---|---|
| Type | string (port) |
| Default | 587 |
| Example | 587 |
EMAIL_STRICT_AUTH
Reject inbound mail outright when SPF/DKIM/DMARC fails (fail-closed). When unset (default), failed-auth messages still reach the agent but flagged untrusted in the envelope. Spec 10/17.
| Read by | emaid / emaid/auth.go:64 |
|---|---|
| Type | bool (truthy strings: 1, true, yes, on) |
| Default | false |
| Example | true |
EMAIL_TRUSTED_AUTHSERV
Hostname of the upstream MTA whose Authentication-Results header emaid will trust (e.g. mx.google.com for Gmail). When unset, every inbound is classified untrusted (fail-closed default per spec 10/17). Added v0.40.5.
| Read by | emaid / emaid/auth.go:63 |
|---|---|
| Type | string (hostname, lowercased) |
| Default | unset |
| Example | mx.google.com |
EMAIL_TRUSTED_DOMAINS
Comma-separated allowlist of sender domains that count as trusted (matched against the From-address domain after DMARC alignment). Empty entries ignored. Both this and EMAIL_TRUSTED_AUTHSERV must agree for a message to be trusted. Added v0.40.5.
| Read by | emaid / emaid/auth.go:68 |
|---|---|
| Type | comma-separated list |
| Default | unset (no domain allowlist) |
| Example | example.com, partner.org |
twitd (X / Twitter)
TWITTER_2FA_SECRET
TOTP shared secret used to mint 2FA codes during automated login.
| Read by | twitd / twitd/src/main.ts:38 |
|---|---|
| Type | string (base32 TOTP secret) |
| Default | unset (login may fail when 2FA prompted) |
| Example | JBSWY3DPEHPK3PXP |
TWITTER_AUTH_DIR
Persistent dir for cookies + cursor state across restarts.
| Read by | twitd / twitd/src/main.ts:30 |
|---|---|
| Type | path |
| Default | $DATA_DIR/store/twitter-auth or /srv/data/store/twitter-auth |
| Example | /srv/data/arizuko_krons/store/twitter-auth |
TWITTER_EMAIL
Email associated with the X account; sometimes required as a fallback identifier during login.
| Read by | twitd / twitd/src/main.ts:37 |
|---|---|
| Type | string |
| Default | unset |
| Example | bot@example.com |
TWITTER_PASSWORD
Password for the X account.
| Read by | twitd / twitd/src/main.ts:36 |
|---|---|
| Type | string |
| Default | unset |
| Example | hunter2 |
TWITTER_POLL_INTERVAL
Mentions/DM poll cadence. Accepts plain seconds (90), Ns, or Nm.
| Read by | twitd / twitd/src/main.ts:45 |
|---|---|
| Type | seconds (int or Ns/Nm) |
| Default | 90 |
| Example | 5m |
TWITTER_USERNAME
Username/handle for the X account.
| Read by | twitd / twitd/src/main.ts:35 |
|---|---|
| Type | string |
| Default | unset |
| Example | arizuko_bot |
linkd (LinkedIn)
LINKEDIN_ACCESS_TOKEN
Pre-acquired OAuth access token; if unset, linkd runs an interactive auth flow.
| Read by | linkd / linkd/main.go:62 |
|---|---|
| Type | string |
| Default | "" |
| Example | AQX... |
LINKEDIN_API_BASE
Base URL of the LinkedIn REST API.
| Read by | linkd / linkd/main.go:69 |
|---|---|
| Type | URL |
| Default | https://api.linkedin.com |
| Example | https://api.linkedin.com |
LINKEDIN_AUTO_PUBLISH
Allow the agent to publish posts without explicit operator confirmation.
| Read by | linkd / linkd/main.go:72 |
|---|---|
| Type | bool ("true") |
| Default | false |
| Example | true |
LINKEDIN_CLIENT_ID
OAuth client id of the registered LinkedIn app.
| Read by | linkd / linkd/main.go:60 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | 77abcde |
LINKEDIN_CLIENT_SECRET
OAuth client secret of the registered LinkedIn app.
| Read by | linkd / linkd/main.go:61 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | xyz123 |
LINKEDIN_OAUTH_BASE
Base URL for the LinkedIn OAuth endpoints.
| Read by | linkd / linkd/main.go:70 |
|---|---|
| Type | URL |
| Default | https://www.linkedin.com |
| Example | https://www.linkedin.com |
LINKEDIN_POLL_INTERVAL
Cadence at which linkd polls for new messages.
| Read by | linkd / linkd/main.go:71 |
|---|---|
| Type | Go duration string |
| Default | 300s |
| Example | 60s |
LINKEDIN_REFRESH_TOKEN
Refresh token used to mint new access tokens.
| Read by | linkd / linkd/main.go:63 |
|---|---|
| Type | string |
| Default | "" |
| Example | AQR... |
slakd (Slack)
SLACK_BOT_TOKEN
Slack xoxb- bot token used by the Web API and Events API client.
| Read by | slakd / slakd/main.go:57 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | xoxb-... |
SLACK_SIGNING_SECRET
Shared secret Slack uses to sign incoming event webhooks; slakd verifies X-Slack-Signature against it.
| Read by | slakd / slakd/main.go:58 (MustEnv) |
|---|---|
| Type | string |
| Default | required |
| Example | 8f742231... |
SLAKD_CHANNEL_SECRET
Adapter-side override for CHANNEL_SECRET: slakd sends this value instead of CHANNEL_SECRET when registering with routd. Note: routd currently verifies all registration requests against the single shared CHANNEL_SECRET, so this must equal CHANNEL_SECRET in production. Per-adapter verification is not yet implemented.
| Read by | slakd / slakd/main.go:60 |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | slk-... |
SLAKD_USERS_CACHE_TTL
TTL (seconds) of the Slack user-info cache; lower values cost more API quota.
| Read by | slakd / slakd/main.go:64 |
|---|---|
| Type | int (seconds) |
| Default | 900 (15 min) |
| Example | 3600 |
TELED_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by teled when registering with routd. See specs/7/H.
| Read by | teled / teled/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | tg-... |
DISCD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by discd. See specs/7/H.
| Read by | discd / discd/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | dc-... |
EMAID_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by emaid. See specs/7/H.
| Read by | emaid / emaid/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | em-... |
MASTD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by mastd. See specs/7/H.
| Read by | mastd / mastd/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | ma-... |
BSKYD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by bskyd. See specs/7/H.
| Read by | bskyd / bskyd/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | bs-... |
REDITD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by reditd. See specs/7/H.
| Read by | reditd / reditd/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | rd-... |
LINKD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by linkd. See specs/7/H.
| Read by | linkd / linkd/main.go |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | li-... |
WHAPD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by whapd. See specs/7/H.
| Read by | whapd / whapd/src/main.ts |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | wa-... |
TWITD_CHANNEL_SECRET
Per-adapter override for CHANNEL_SECRET used by twitd. See specs/7/H.
| Read by | twitd / twitd/src/main.ts |
|---|---|
| Type | string |
| Default | falls back to CHANNEL_SECRET |
| Example | tw-... |
split daemons (routd / runed / authd)
Three daemons split the work: routd (routing + message loop), runed (container spawn), and authd (auth + identity) — specs 5/E + 5/P. These vars wire them together.
CUTOVER_SPLIT
Removed in v0.50.0 — the split is now the only topology, so there is no monolith to select against. This row is kept only so older links don't break.
AUTHD_URL
In-network base URL of authd. routd, runed, webd, and proxyd reach it for service-token exchange and JWKS.
| Read by | compose / compose/compose.go:434 → routd, runed, webd, proxyd |
|---|---|
| Type | URL |
| Default | http://authd:8080 |
| Example | http://authd:8080 |
AUTHD_SERVICE_KEY
Per-daemon shared secret a service daemon presents to authd to authenticate. Provisioned once per daemon and persisted to env/<daemon>.env; authd recognises them via AUTHD_SERVICE_KEYS.
| Read by | compose / compose/compose.go:428 → routd, runed |
|---|---|
| Type | string (secret) |
| Default | auto-provisioned at compose time |
| Example | <random hex> |
AUTHD_SERVICE_KEYS
The principal=secret pairs authd accepts, one per service daemon. Rotating a key here invalidates that daemon's in-flight service tokens.
| Read by | compose / compose/compose.go:432 → authd |
|---|---|
| Type | string (comma-separated principal=secret) |
| Default | auto-built from the provisioned service keys |
| Example | service:routd=...,service:runed=... |
RUNED_URL
In-network base URL of runed (the container-runner plane). routd dispatches runs to it.
| Read by | routd / routd/cmd/routd/main.go:40 |
|---|---|
| Type | URL |
| Default | http://runed:8080 |
| Example | http://runed:8080 |
ROUTD_SERVICE_TOKEN
Service token routd presents to runed on each run dispatch.
| Read by | routd / routd/cmd/routd/main.go:78 |
|---|---|
| Type | string (token) |
| Default | minted against AUTHD_URL using AUTHD_SERVICE_KEY |
| Example | <jwt> |
RUNED_SERVICE_TOKEN
Service token runed presents to authd when its broker authenticates.
| Read by | runed / runed/cmd/runed/main.go:74 |
|---|---|
| Type | string (token) |
| Default | minted against AUTHD_URL using AUTHD_SERVICE_KEY |
| Example | <jwt> |
observability — OTLP export
slog to journald is always on. Setting the OTLP endpoint additionally fans every slog event out to an OpenTelemetry collector (spec 5/O, library obs/). Unset = zero overhead.
OTEL_EXPORTER_OTLP_ENDPOINT
OTLP/HTTP collector endpoint. When set, every daemon's obs.Setup sends slog events to stderr and the collector; records carrying turn_id get a deterministic TraceID so one turn's events group. When empty, only the stderr JSON handler runs.
| Read by | obs / obs/obs.go:36 (every daemon's main) |
|---|---|
| Type | URL |
| Default | "" = OTLP disabled |
| Example | http://collector:4318 |
Not documented here
- davd — the daemon binary is upstream
sigoden/dufswrapped in alpine for the healthcheck (davd/Dockerfile). Its config is CLI args and dufs's own env vars, not arizuko's. - vited — static-file server image with no arizuko Go/TS code. Generated at compose time.
- Test-only env vars — e.g.
TEST_*,SMOKE_INSTANCE(Makefile-only). Omitted by scope. - crackbox internals —
XDG_CONFIG_HOME,HOME,CRACKBOX_LIBEXECare read inside the crackbox component when it runs standalone. The arizuko-side touchpoints areCRACKBOX_ADMIN_API,CRACKBOX_ADMIN_SECRET,CRACKBOX_PROXY_URL.