# Runtime secrets The canonical deployment secret is the single local file `deploy/secrets/thothii.secrets`. Copy the tracked template and protect the copy: ```sh 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 installation keys are `THT_MODEL_API_KEY`, `THT_DWH_API_KEY`, `THT_CA`, `THT_SSL_CA`, `THT_OIDC_CLIENT_SECRET`, and `THT_AUTHENTIK_API_TOKEN`. Metadata-generation models may reference exactly one of `THT_METADATA_API_KEY`, `ANTHROPIC_API_KEY`, `AZURE_API_KEY`, `GEMINI_API_KEY`, `DEEPSEEK_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`, or `ZAI_API_KEY` through their descriptor `apiKeyEnv`. An entry for an explicitly configured endpoint that accepts unauthenticated requests may omit `apiKeyEnv`; hosted/default endpoints must always reference a key. OpenAI-compatible Qwen endpoints that emit reasoning in `content` can additionally set `litellm.disableThinking: true`; the adapter sends the server's bounded chat-template flag so the strict JSON result remains parseable. The two authentication keys must be omitted until they have non-empty values in a protected OIDC installation. Other configured values must be non-empty and contain no whitespace. Do not put secrets in the root `.env`, installation YAML, workspace YAML, URLs, logs, or rendered Compose output. `THT_MODEL_API_KEY` remains the generic Pi child credential. Metadata generation is a separate backend-owned runtime and reads only the key named by its own `metadataGeneration.models[].apiKeyEnv` (when present); it does not read Pi settings, `PI_AUTH_FILE`, or workspace `llm_policy`. Do not add vector or embedding endpoint credentials to the bundle. Active operator manuals use internal Qdrant and Ollama services, so vector/embedding runtime endpoint secrets are not part of the supported installation contract. 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: ```sh 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 retained 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. Hosted Pi providers must use a single model key through `THT_MODEL_API_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.