Files
ThothII/deploy/secrets

Runtime secrets

The canonical deployment secret is the single local file deploy/secrets/thothii.secrets. Copy the tracked template and protect the copy:

cp deploy/secrets/thothii.secrets.example deploy/secrets/thothii.secrets
chmod 600 deploy/secrets/thothii.secrets

The file uses strict KEY=VALUE lines (comments and blank lines are allowed). The supported keys are THT_MODEL_API_KEY, THT_DWH_API_KEY, THT_VEC_API_KEY, THT_VEC_WRITE_API_KEY, and the four THT_VECTOR_*_PASSWORD role passwords. Values must be non-empty and contain no whitespace. Do not put secrets in the root .env, workspace YAML, URLs, logs, or rendered Compose output.

Compose mounts the bundle read-only as /run/secrets/thothii.secrets. The host file must be a regular non-symlink file with mode 0600 or 0400; Docker's normal 0444 mode is accepted only for the runtime mount beneath /run/secrets. The core runs as UID 10001. Verify the mount without printing its contents:

docker compose --env-file deploy/env/local.env \
  -f compose.yaml -f deploy/compose.local.yaml \
  run --rm core sh -c 'id && test -r /run/secrets/thothii.secrets'

A private CA PEM chain is not a bundle value: PEM whitespace is rejected by the strict parser. Keep it in the host or secret manager and add a reviewed Compose override that mounts it at /run/secrets/ca-chain.pem and sets THT_SSL_CA (or the adapter-specific setting). The base Compose files intentionally do not create this mount.

Migration from separate secret files

Older installations used THT_*_SECRET_FILE variables and one file per value. Migrate by copying each value to its bundle key, validating with the complete base+profile command, and only then deleting the old files. The old variables remain a compatibility path for staged upgrades, but the documented and tested default is an absolute THT_SECRETS_FILE path to the protected bundle.

The local-vector bootstrap rotation helper still accepts an old/new password file as its maintenance interface. Run it only with files protected by 0600, then copy the resulting password into THT_VECTOR_BOOTSTRAP_PASSWORD in the bundle before restarting vector-reconcile/the application. The helper never prints password contents.

The helper has no implicit operator-env default. Pass the same protected env file used for the deployment explicitly; it must be a readable regular non-symlink file and must not be writable by group or other users:

chmod 600 deploy/env/local.env
./scripts/vector-rotate-bootstrap-password.sh \
  --env-file "$(pwd)/deploy/env/local.env" \
  /secure/thoth/bootstrap-password /secure/thoth/bootstrap-password.next

Automation may set the narrowly scoped THT_VECTOR_OPERATOR_ENV_FILE instead. An explicit --env-file takes precedence. Missing or unsafe env files are rejected before Compose runs.

Hosted Pi providers must use a single provider key. Compound providers (Bedrock, Azure OpenAI Responses, Cloudflare Workers AI/Gateway) fail closed until a provider-specific credential adapter is implemented.

User-owned session database secrets

The server-session overlay deliberately does not add session database credentials to the shared bundle. Materialize three distinct Docker secrets from protected host or secret-manager files: session_runtime_password, session_migrator_password, and session_ca.pem. Their host source paths are respectively THT_SESSION_RUNTIME_PASSWORD_SOURCE, THT_SESSION_MIGRATOR_PASSWORD_SOURCE, and THT_SESSION_CA_SOURCE; all must be absolute paths outside the repository. The runtime password is mounted only into core; the migrator password is mounted only into the one-shot session-migrate service. Do not reuse either login for the other role.

session_ca.pem is a PEM file rather than a bundle value because the bundle rejects whitespace. The server workspace receives only its mount path through THT_SESSION_DB_SSLROOTCERT; it uses THT_SESSION_DB_SSLMODE=verify-ca or, normally, verify-full. TLS disable/prefer/require modes are unsupported for session storage.