Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0066
ADR-0066: /opt/orchestrata secrets live in ~/.config/orchestrata/.env and the installer never defaults to the workspace template
| field | value |
|---|---|
| Status | Accepted — Accepted (ruling R16, Mohamed, 2026-09-24: "1, proceed with that") |
| Date | 2026-09-24 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0066-opt-orchestrata-secrets-live-in-the-user-config-env.md — permalink at 0fe7f2e36 (unchanged on master since that commit) |
| Wiki register entry | ADR-0066 (wiki status: Accepted) |
The record
Status: Accepted (ruling R16, Mohamed, 2026-09-24: "1, proceed with that") · Date: 2026-09-24
Context
deploy/install-orchestrata.sh installs one secrets file as
$PREFIX/.env (mode 0600). Until 2026-09-24 the default for --secrets-env
was $SOURCE_REPO/.env, the workspace's 56-key CHANGEME template, so the
first bootstrap of /opt/orchestrata shipped a .env with 56 placeholders
and the prod promote failed at services (gateway on GATEWAY_HOST,
conversation consumer on CONVERSATION_KG_URI/CONVERSATION_KG_DATABASE).
U-BOOT3 (ec0c61100) made the installer refuse any secrets file that still
carries a CHANGEME value. The consumer's contract
(knowledge_graph/conversation_consumer.py::resolve_conversation_endpoint)
states the conversation graph's endpoint keys "must be set in the secrets-only
.env (they are deliberately absent from every env/*.env profile overlay)".
The host carries real secrets in ~/.env (a mixed file also holding Neo4j
and port keys for other tools) and nowhere else; ~/.config/orchestrata/
did not exist.
Decision (Mohamed, ruling R16)
The production secrets file is ${XDG_CONFIG_HOME:-$HOME/.config}/orchestrata/.env,
mode 0600, owned by the deploying user, containing secrets only — never a
config key that belongs in the committed env/prod.env, never a placeholder.
deploy/install-orchestrata.sh defaults --secrets-env to that path and
never to the workspace template again; an absent file is a refusal, as is a
placeholder. The two conversation-graph keys live in this file, per the
consumer's contract. The file is created on the host from the real values
already present in ~/.env (a script copies named keys; values are never
printed), and grows only by keys the promote's services stage proves
missing — each addition recorded in the plan by key name.
Alternatives rejected
- Keep defaulting to
$SOURCE_REPO/.env: that is the template, and the installer now refuses it anyway; a default that always refuses is a trap. - Point the installer at
~/.env: it mixes other tools' keys (PORT,NEO4J_*) into every orchestrata unit's environment; a genericPORTsilently reconfigures services. - Commit an
env/prod.secrets.env: secrets in git, rejected on sight. - Put the conversation-graph endpoint into
env/prod.env: the consumer refuses to resolve it through profile keys by design (REQ-021-069); the profile overlay is what dev/test redirect.
Consequences
Bootstrap and re-bootstrap commands read
--secrets-env ~/.config/orchestrata/.env implicitly. The file's key set is
the plan's record: at acceptance it holds DEEPSEEK_API_KEY, GITLAB_TOKEN,
OPENROUTER_API_KEY, GEMINI_API_KEY. The conversation-graph endpoint value
(which server and database host the conversation graph) is an operational
parameter still to be named by Mohamed (plan item R16b); until it is set the
consumer unit is refused by design, not by accident. tests/deploy/ test_install_orchestrata_secrets.py gains the default-path and absent-file
cases (U-PROD2).
Provenance
Orchestrator findings 2026-09-24 (plan
plans/PLAN-2026-09-23-production-deployable-tools.md, records "ship attempt
5", "U-BOOT3", R16). Mohamed's ruling, 2026-09-24: "1, proceed with that" and
"record tbe adr decisions". Evidence: deploy/install-orchestrata.sh:26,48, 183-196; conversation_consumer.py:66-112; scratchpad/ship-wave7e.log;
host file created 2026-09-24 16:22 (ls -l → -rw-------, 0 CHANGEME).
Related ADRs
No other ADR is named in this record.
Rulings cited
None.
Specs cited
None (or no spec page exists for the ones named).