# Admin and settings Guides for instance administrators: global settings, user management, SSO, and troubleshooting. ## Global settings Admins have access to a **Settings** page that controls instance-wide behavior. The page uses a **tabbed layout**: each section (Access & General, Default Limits, Final Output, Integrations, etc.) is a tab. The first tab is **System** (version, command status, memory/CPU/disk from the system-stats API). A **global search** box filters tabs and scrolls to matching controls (e.g. typing "Account Registration" jumps to Enable Account Registration). There is a single form and one **Save** button across all tabs. On desktop you see a vertical sidebar for tabs; on mobile, a drawer. You can use keyboard navigation (arrow keys, Home/End to jump to first/last tab, Escape to close the drawer). Key areas (in their respective tabs): ### System The **System** tab shows instance version, command status, and system stats (memory, CPU, disk). Use it for a quick health check. ### Account and access - **Account registration** - Enable or disable whether new users can create accounts. - **Public feeds** - Enable or disable public podcast and episode pages and RSS feeds for listeners. - **White Label** - Optional name that replaces "HarborFM" on public feed headers, episode pages, share titles, embed players, and related public surfaces when configured. - **Welcome banner** - Optional message shown to users (e.g. on login or dashboard). - **Hostname** - Set the public hostname so SSO callbacks, WebRTC public WebSocket URL, and related links stay correct. Changing Hostname updates the WebRTC public WebSocket URL when it still pointed at the previous host. Once set in WebRTC Settings, those values take precedence over `WEBRTC_*` env vars. ### Defaults and limits - **Default limits for new users** - Max podcasts, max episodes, max storage per user when they sign up. Can be overridden per user in [User management](#user-management). - **`defaultCanStripe`** - Whether newly registered users get Stripe Payments access. Default is on. See [Stripe payments](Stripe-payments.md). - **`defaultCanImportTheme`** - Whether newly registered users can import and edit [page themes](Page-themes.md). Default is on. ### Episode output - **Final Episode Output** - Default format for rendered episodes (e.g. mono vs stereo, bitrate). Affects **Build Final Episode** output. ### Integrations - **GeoLite2** - MaxMind GeoIP for analytics (country/city). Configure GeoIP credentials and update path if used. See [Analytics](Analytics.md). - **Whisper ASR** - URL and options for the Whisper service used to generate transcripts. When set, users can generate transcripts in the episode editor. - **LLMs** - Ollama or OpenAI (or compatible) endpoint and API key for segment transcript helpers. When set, users can "ask" the LLM about a segment. Also used for optional review spam checks when enabled. - **Captcha** - reCAPTCHA or hCaptcha for registration, login, or public polls/reviews if enabled. - **Email** - SMTP (or SendGrid etc.) for password reset, verification, invite emails, review verification, guest episode review previews, and Stripe token recovery / receipts when configured. **Email Event Tracking** (on by default) lets meeting invite and reminder emails report opens in Schedule Meeting. Changes are saved from the Settings page. Some options require environment variables; see the main [README](../blob/main/README.md) ("Docker environment variables") and [Deployment: Environment variables](Deployment.md#environment-variables). ### See also - [User management](#user-management) - [Troubleshooting](#troubleshooting) - [Deployment: Environment variables](Deployment.md#environment-variables) - Main [README](../blob/main/README.md) - env vars table ## User management Admins can view and manage users from the **Users** page. ### User list - View all users on the instance. - For each user you can typically see: email, username, role (admin or not), account status (enabled/disabled), and optionally storage or usage. ### Per-user actions - **Podcasts** - View the list of podcasts owned by or shared with that user. - **Library** - View the user's library (and optionally storage used). - **Edit** - Change email, username, or other profile fields; **change password** (set a new password for the user); **disable or enable** the account. - **Limits** - Set or override **max podcasts**, **max episodes**, and **max storage** for that user. If they hit a limit (e.g. storage), actions like Record new section may be disabled until the limit is raised or they free space. - **`canStripe`** - Per-user flag for Stripe Payments. When off, that user cannot open Stripe Payments or call Stripe API routes (403). Independent of show role. See [Stripe payments](Stripe-payments.md). - **`canImportTheme`** - Per-user flag for page themes. When off, that user cannot import, download, or edit theme packages (403). Selecting a server-wide theme on a show they manage still works. See [Page themes](Page-themes.md). - **Video generation** - Per-user permission (`canGenerateVideo`) when the instance allows video generation. ### Invite to platform When inviting a **collaborator** to a show, if the person doesn't have an account yet, the UI can send an "invite to the platform" email (rate-limited per inviter per day). Admins can also invite users directly if the instance supports it. ### See also - [Global settings](#global-settings) - Default limits for new users - [Stripe payments](Stripe-payments.md) - `defaultCanStripe` / `canStripe` - [Podcasts: Collaborators and permissions](Podcasts.md#collaborators-and-permissions) - Main [README](../blob/main/README.md) - Permissions, storage limits ## SSO (OIDC / SAML) HarborFM supports **Single Sign-On** via **OIDC** (OpenID Connect) and **SAML**. Configured providers appear as sign-in options on the login page. Add and edit providers under **Settings > SSO (OIDC / SAML)**. ### General - Set the **Hostname** (e.g. `app.harborfm.com` or `https://app.harborfm.com`) so callback URLs are correct. - Use **"(set)"** in password or certificate fields when editing a provider to keep existing secrets without re-entering them. ### OIDC (e.g. Keycloak, Google, Auth0) 1. In your identity provider (IdP), create a client and note the **Client ID**, **Client secret**, and **redirect/callback URL**. The callback URL in HarborFM is typically `https://your-host/api/auth/sso/oidc/callback/{provider-id}`. 2. In HarborFM, under **OIDC providers**, click **Add Provider**. 3. Set **Provider ID** (slug used in the callback path), **Display name**, **Discovery URL** (e.g. `https://keycloak.example.com/realms/harborfm` for Keycloak - no path suffix; HarborFM fetches `/.well-known/openid-configuration`), **Client ID**, **Client secret**, and **Scopes** (e.g. `openid profile email`). 4. Enable **Trust email from provider** if you want account linking by email. 5. If you see "issuer does not match," set **Issuer Override** to the exact `issuer` from your IdP's `/.well-known/openid-configuration`. Save the provider, then **Save** at the bottom of Settings. ### SAML (e.g. Keycloak) 1. In the IdP, create a **SAML** client. Set **Client ID** (entity ID) to HarborFM's SAML entity ID: `https://your-host/api/auth/sso/saml`. Set **Valid redirect URIs** (ACS URL) to `https://your-host/api/auth/sso/saml/callback/{provider-id}`. 2. From the IdP, get the **IdP certificate (PEM)** and **IdP Entry Point URL** (SAML login URL). 3. In HarborFM, under **SAML providers**, click **Add Provider**. Enter **Provider ID**, **Display name**, **IdP Entry Point URL**, **IdP certificate (PEM)**. Optionally configure **SP certificate/private key** if the IdP requires signed requests. 4. Use the **Callback URL** shown in the form when configuring the IdP. Full step-by-step for Keycloak (OIDC and SAML) is in the main [README](../blob/main/README.md) ("Single Sign-On (SSO)"). ### See also - [Login and registration](Account.md#login-and-registration) - [Global settings](#global-settings) - Main [README](../blob/main/README.md) - Single Sign-On (SSO) ## Troubleshooting Common issues and where to look. For full detail, see the main [README](../blob/main/README.md) ("Troubleshooting" and related sections). ### Setup URL / "Server not set up yet" On first run, the **one-time setup URL** is printed in the server (or container) logs. Open that URL in your browser (e.g. `https://your-host/setup?id=...`) to create the admin account. - **Lost the URL?** Restart the server to see it again. The token is regenerated only if the secrets file is missing. - **Where to look:** `docker logs `, or the terminal where you ran `pnpm run dev` or the server process. See [Getting started](Getting-started.md). ### ffmpeg or audiowaveform not found The server needs **ffmpeg** and **audiowaveform** for segment processing (trim, concat, silence removal, waveforms). - **Docker:** The official image includes ffmpeg. If you use a custom image or run locally, ensure both are installed and on the `PATH`. - **Local dev:** Install via your package manager. For [audiowaveform](https://github.com/bbc/audiowaveform), build from source or use a package if available (e.g. on macOS: `brew install audiowaveform`). You can override binary paths with environment variables; see main [README](../blob/main/README.md) (`FFMPEG_PATH`, `FFPROBE_PATH`, `AUDIOWAVEFORM_PATH`). ### Group calls not working - **No "Record" or group-call UI** - Ensure **WebRTC** is enabled: `WEBRTC_ENABLED=1`, and that `WEBRTC_SERVICE_URL` and `WEBRTC_PUBLIC_WS_URL` are set (or configured under WebRTC Settings after Hostname is set). See main [README](../blob/main/README.md) "WebRTC (group calls)." - **Can't connect / no audio** - Verify firewall allows UDP ports (default 40000–40200, or 41000–41100 in Docker). Behind NAT, set `MEDIASOUP_ANNOUNCED_IP` to the server's public IP. - **Stale WebSocket URL after domain change** - Confirm Hostname and WebRTC Settings still match the public host. - **Logs:** `docker compose logs webrtc` or `pm2 logs webrtc`. See [Group calls](Group-calls.md). ### Login failures and IP bans Repeated failed login attempts can trigger a temporary **IP ban**. The main README documents `LOGIN_FAILURE_THRESHOLD`, `LOGIN_BAN_MINUTES`, and `LOGIN_WINDOW_MINUTES`. Admins can clear IP bans (e.g. via server script `pnpm run db:clear-ip-bans` or equivalent; see README "Scripts"). ### Backup and upgrading Before upgrading, back up **DATA_DIR** (database, uploads, processed audio, RSS, artwork, library). Optionally back up **SECRETS_DIR**. Migrations run automatically on server start. See main [README](../blob/main/README.md) "Backup and upgrading." ### See also - [Getting started](Getting-started.md) - [Group calls](Group-calls.md) - [Deployment](Deployment.md) - Main [README](../blob/main/README.md) - Troubleshooting, Backup and upgrading, Scripts