- Add scripts/provision-hub-tokens.sh. It adds the five HUB_TOKEN_* keys to ~/.config/environment.d/10-secrets.conf. It is idempotent, keeps mode 600, leaves a mode-600 backup, and never prints a value. It uses openssl when present and /dev/urandom otherwise (this host has no openssl). - docker-compose.yml: run the container as the host user. The image's distroless nonroot user cannot read the 0600 secrets file. With nonroot the Hub read no tokens and every /ask returned 401. - Document the deploy steps, the finding, and the dry-run evidence in docs/outline/04-agent-runbook.md, docs/outline/02-config-and-env.md, README.md. Dry run on port 18788 with a scratch secrets file: /health ok with omniroute ok, control action refused, bad token 401. The host secrets file and the running hub container were not touched. Co-Authored-By: Paperclip <noreply@paperclip.ing>
3.9 KiB
Central AI Hub — Configuration & Environment
Writing Style: ASD-STE100 Simplified Technical English (
ste-writing).
Secrets
All secrets come from ~/.config/environment.d/10-secrets.conf on each machine.
Never hard-code a secret. Never commit a secret.
Relevant keys:
| Key | Use |
|---|---|
OMNIROUTE_API_KEY |
Model calls through OmniRoute. |
PAPERCLIP_API_KEY |
File jobs to Paperclip. The Hub agent holds this key (id 108c6220-c9e1-4b62-9e0a-6a763e0d28fd). Key name: hub-service. |
TAVILY_API_KEY |
Web search. |
OL_API_KEY |
Outline docs. |
VIKUNJA_TOKEN |
Vikunja tasks. |
GITEA_TOKEN |
Gitea repository. |
HUB_TOKEN_PHONE |
Hub token for the phone app. |
HUB_TOKEN_ESP32 |
Hub token for the house voice. |
HUB_TOKEN_DSH |
Hub token for dsh chat. |
HUB_TOKEN_CONSOLE |
Hub token for the console portal. |
HUB_TOKEN_ADMIN |
Hub token for the admin app. The only trusted door. |
Add the five Hub tokens with scripts/provision-hub-tokens.sh. It is
idempotent, keeps mode 600, and never prints a value. A new token needs Sam's OK
(AGENTS.md "ask first: credentials").
The container runs as the host user (HUB_UID/HUB_GID, default 1000:100),
not the image's nonroot user, because the secrets file has mode 0600 and the
nonroot user cannot read it. See docs/outline/04-agent-runbook.md.
Hub Environment Keys
The Hub reads these keys from the environment, then from the secrets file. The
secrets file path is HUB_SECRETS_FILE, or ~/.config/environment.d/10-secrets.conf.
| Key | Default | Use |
|---|---|---|
HUB_PORT |
8788 |
Listen port. |
HUB_ROUTING_FILE |
routing.md |
Human-edited routing rules. |
HUB_SECRETS_FILE |
~/.config/environment.d/10-secrets.conf |
Read secrets when the environment is empty. |
HUB_PROJECTS |
empty | Data projects: name=url,name2=url2. |
HUB_PROJECT_<NAME>_TOKEN |
empty | Per-project bearer token. |
OMNIROUTE_URL |
http://192.168.20.13:20129 |
Model gateway base. |
OMNIROUTE_MODEL |
gpt-4o-mini |
Routing model. The gateway is OpenAI-compatible. |
JERVIS_URL |
http://192.168.20.13:8501 |
House TTS. |
PAPERCLIP_BASE_URL |
http://192.168.20.13:3100 |
Paperclip board. |
PAPERCLIP_COMPANY_ID |
from the repo convention | Company for filed jobs. |
HUB_LOG_PATH |
hub.log |
Append-only request log. |
HUB_LOG_MAX_BYTES |
1048576 |
Rotate size. |
HUB_LOG_KEEP_DAYS |
7 |
Rotated files kept. |
HUB_LLM_TIMEOUT |
3s |
Routing LLM cap (docs/hub-api.md section 8). |
HUB_PROJECT_TIMEOUT |
3s |
One project /ask cap. |
HUB_DEST_TIMEOUT |
2s |
One destination command cap. |
HUB_TTS_TIMEOUT |
15s |
House TTS completes out of band. |
HUB_ASK_TIMEOUT |
8s |
POST /ask total. |
HUB_APPROVE_TIMEOUT |
5s |
POST /approve total. |
HUB_RATE_PER_MIN |
30 |
Requests per client token per minute. |
Observed on 2026-10-10: the routing LLM answer through OmniRoute took 0.8 s to 1.9 s with
gpt-4o-mini, inside the 3 s cap. Theauto/*combos were slower than 3 s and are not the default.
Services and Ports
| Service | Host | Port | Use |
|---|---|---|---|
| OmniRoute | 192.168.20.13 | 20129 | Model gateway. |
| Paperclip | 192.168.20.13 | 3100 | Job orchestration. |
| Jervis (voice) | 192.168.20.13 | 8501 | Speak and announce. |
| Home Assistant | 192.168.20.30 | 8123 | Devices and timers. |
| MQTT | 192.168.20.13 | 1883 | Voice topics. |
| Apprise | 192.168.20.35 | 8210 | Notifications. |
| Hub | 192.168.20.13 | 8788 | This service. Allocated 2026-10-10. HUB_PORT, default 8788. |
Port 8787 was only a proposal. It is used by the
headroomcontainer. Port 8788 was free on 2026-10-10 and is the allocated Hub port.
Config Paths
- Brief:
hub_brief.md - Rules:
AGENTS.md - Docs:
docs/ - Outline context:
docs/outline/
Rule
A new project gets its own service, its own port, and its own folder. Do not merge a destination into the Hub.