docs(admin-panel): clarify admin provider key handling and AUTH_SECRET rotation
Expand admin panel documentation to detail the transition from live env var reading to one-shot seeding for TTS providers in v3.0.0. Add warnings about the impact of rotating AUTH_SECRET on encrypted admin provider keys and the required manual steps after rotation. docs(migrations): add schema migration history table Document the sequence and purpose of each migration introduced in v3.0.0, clarifying upgrade behavior from v2.2.0 and summarizing schema changes. chore(env): remove commented default TTS model example from .env.example
This commit is contained in:
parent
ca4228970b
commit
80f9386a6c
3 changed files with 20 additions and 6 deletions
|
|
@ -94,6 +94,5 @@ FFMPEG_BIN=
|
|||
# NEXT_PUBLIC_RESTRICT_USER_API_KEYS=true
|
||||
# NEXT_PUBLIC_DEFAULT_TTS_PROVIDER=custom-openai
|
||||
# NEXT_PUBLIC_CHANGELOG_FEED_URL=https://docs.openreader.richardr.dev/changelog/manifest.json
|
||||
# NEXT_PUBLIC_DEFAULT_TTS_MODEL=kokoro
|
||||
# NEXT_PUBLIC_ENABLE_AUDIOBOOK_EXPORT=true
|
||||
# NEXT_PUBLIC_ENABLE_WORD_HIGHLIGHT=true
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ On first boot, if `admin_providers` is empty and the legacy `API_KEY` env var is
|
|||
|
||||
After this seed runs, the legacy `API_KEY` / `API_BASE` env vars are no longer read by the TTS routes — the DB row is authoritative. You can rename, edit, disable, or delete this row like any other from the admin UI, and remove the env vars from your `.env` when convenient.
|
||||
|
||||
:::warning Upgrading from v2.2.0
|
||||
In v2.2.0 and earlier, `API_KEY` / `API_BASE` were read live by the TTS routes on every request. As of v3.0.0 they are **one-shot seeds** consumed only on the first boot where `admin_providers` is empty. After upgrading, boot the app once and confirm a `default-openai` row exists in **Settings → Admin → Shared providers** with the correct base URL. If it is missing or wrong (e.g. the env vars were not set on first boot, or the table was already non-empty from a pre-release), create or edit the shared provider manually — TTS will not fall back to the env vars.
|
||||
:::
|
||||
|
||||
## Site features
|
||||
|
||||
Runtime-editable settings, one row per key:
|
||||
|
|
@ -100,11 +104,15 @@ You can keep the env vars indefinitely if you prefer; they're only read on the f
|
|||
|
||||
## How keys are protected
|
||||
|
||||
- API keys are encrypted in the `admin_providers` table with AES-256-GCM. The encryption key is derived from `AUTH_SECRET` via `scrypt`. This means rotating `AUTH_SECRET` will invalidate all stored admin keys — re-enter them via the admin UI after rotating.
|
||||
- API keys are encrypted in the `admin_providers` table with AES-256-GCM. The encryption key is derived from `AUTH_SECRET` via `scrypt`.
|
||||
- The masked-list view (`GET /api/admin/providers`, used by the admin UI itself) returns `••••` + last-4 only — never plaintext or ciphertext.
|
||||
- The public list endpoint (`GET /api/tts/shared-providers`, called by every user's browser) returns only `{ slug, displayName, providerType, defaultModel }`. Keys and base URLs are never exposed to the client.
|
||||
- Non-admin users cannot enumerate admin providers' credentials or base URLs through any API.
|
||||
|
||||
:::danger Rotating `AUTH_SECRET` invalidates all stored admin provider keys
|
||||
Because the encryption key for `admin_providers` is derived from `AUTH_SECRET`, changing `AUTH_SECRET` makes every stored API key undecryptable. After rotating it, shared providers will fail to authenticate upstream until you re-enter each provider's API key in **Settings → Admin → Shared providers** (edit the row and paste the key again). There is no automated re-encryption path. If you must rotate `AUTH_SECRET`, plan to re-enter admin provider keys immediately afterward.
|
||||
:::
|
||||
|
||||
## Related
|
||||
|
||||
- [Auth](./auth) — required to use the admin panel.
|
||||
|
|
|
|||
|
|
@ -20,14 +20,21 @@ Startup migration phases:
|
|||
- DB schema migrations (`pnpm migrate`)
|
||||
- Storage/data migration (`pnpm migrate-fs`) for legacy filesystem content into S3 + DB rows
|
||||
|
||||
Recent schema addition:
|
||||
|
||||
- `0001_tts_segments` (SQLite + Postgres) creates the `tts_segments` table used by server-side TTS segment caching and alignment metadata.
|
||||
|
||||
:::info
|
||||
In most setups, you do not need to run migration commands manually because startup handles this automatically.
|
||||
:::
|
||||
|
||||
### Schema history
|
||||
|
||||
Migrations are applied in order. All of the following ship in v3.0.0; an instance upgrading from v2.2.0 applies `0001`–`0004` in a single startup pass.
|
||||
|
||||
| Migration | Dialects | What it does |
|
||||
| --- | --- | --- |
|
||||
| `0001_tts_segments` | SQLite + Postgres | Creates the original single-table `tts_segments` used by server-side TTS segment caching. |
|
||||
| `0002_add_segment_key_to_tts_segments` | SQLite + Postgres | Adds the `segment_key` column to `tts_segments` for stable locator-independent segment identity. |
|
||||
| `0003_tts_segments_v2_split` | SQLite + Postgres | Replaces `tts_segments` with a normalized two-table model: `tts_segment_entries` (one row per document segment + locator identity) and `tts_segment_variants` (one row per settings combination, holding the cached audio key, status, and alignment). Drops the original `tts_segments` table — no released build (v2.2.0 or earlier) ever populated it, so there is no production data to migrate. |
|
||||
| `0004_admin_panel` | SQLite + Postgres | Creates `admin_providers` (encrypted shared TTS provider rows) and `admin_settings` (runtime site-feature config), and adds the `is_admin` column to the `user` table. Backs the [Admin Panel](./admin-panel). |
|
||||
|
||||
To skip automatic startup migrations:
|
||||
|
||||
- Set `RUN_DRIZZLE_MIGRATIONS=false`
|
||||
|
|
|
|||
Loading…
Reference in a new issue