YotoShelf
Self-Host

Configuration

Environment variable reference for YotoShelf. All knobs, their defaults, and when to set them.

Configuration is loaded from environment variables with the prefix YOTOSHELF_. Precedence: CLI flags > environment variables > built-in defaults. There is no config file; pass everything via the environment.

AI provider keys are the exception: they're added in-app from the Settings page (AI Providers, plus per-user AI Keys), not as environment variables, so they carry no rows below.

Core

VariableDefaultDescription
YOTOSHELF_DB_PATH yotoshelf.db Path to the SQLite database file. Put this on a persistent volume.
YOTOSHELF_LISTEN_ADDR :8080 HTTP listen address and port.
YOTOSHELF_LIBRARY_PATH library Directory for audio files, cover images, and generated assets. Put this on a persistent volume.
YOTOSHELF_PUBLIC_URL Externally visible base URL (e.g. https://yotoshelf.example.com). Unless overridden by YOTOSHELF_YOTO_REDIRECT_URL / YOTOSHELF_OIDC_REDIRECT_URL, it derives both OAuth redirect URLs and the base for share links. Leaving it unset also disables CSRF origin checking.

Security

VariableDefaultDescription
YOTOSHELF_SESSION_SECRET Signing key for session cookies. Minimum 32 bytes. Required. Rotate to invalidate all active sessions.
YOTOSHELF_ENCRYPTION_KEY Key for encrypting Yoto OAuth tokens at rest. Minimum 32 bytes. Required. Changing this invalidates stored tokens, so users must re-link their Yoto accounts.
YOTOSHELF_SECURE_COOKIES true Set the Secure flag on session cookies. Over plain HTTP (a LAN address included, not just local development) the browser never stores the cookie and login silently fails. Set to false for any deployment without TLS; leave the default behind HTTPS.
YOTOSHELF_TRUST_PROXY false Read real client IP from X-Forwarded-For. Enable when behind a reverse proxy.
YOTOSHELF_SESSION_MAX_AGE 604800 Session lifetime in seconds. Default is 7 days.

Authentication

VariableDefaultDescription
YOTOSHELF_LOCAL_AUTH_ENABLED true Enable local username/password login. Set to false to require OIDC.
YOTOSHELF_REQUIRE_EMAIL_VERIFICATION true Require users to verify their email address after registration.
YOTOSHELF_PASSWORD_MIN_LENGTH 10 Minimum password length for local accounts.
YOTOSHELF_LOCKOUT_THRESHOLD 5 Failed login attempts before account lockout.
YOTOSHELF_LOCKOUT_DURATION 900 Lockout duration in seconds (default: 15 minutes).

OIDC (single sign-on)

YotoShelf supports OpenID Connect for SSO. When configured, users authenticate via an external identity provider. The OIDC flow uses PKCE S256, nonce verification, and email_verified enforcement.

VariableDefaultDescription
YOTOSHELF_OIDC_ISSUER OIDC issuer URL, e.g. https://auth.example.com/application/o/yotoshelf/
YOTOSHELF_OIDC_CLIENT_ID OAuth 2.0 client ID from your identity provider.
YOTOSHELF_OIDC_CLIENT_SECRET OAuth 2.0 client secret.
YOTOSHELF_OIDC_REDIRECT_URL {PUBLIC_URL}/api/v1/auth/oidc/callback OAuth callback URL. Derived from YOTOSHELF_PUBLIC_URL unless set explicitly.

Configure your IdP's backchannel logout to send POST requests to /auth/oidc/backchannel-logout. When LOCAL_AUTH_ENABLED=false, the first OIDC user to log in is auto-promoted to admin.

Yoto API

VariableDefaultDescription
YOTOSHELF_YOTO_CLIENT_ID Yoto OAuth application client ID. Required for publishing cards to Yoto accounts.
YOTOSHELF_YOTO_CLIENT_SECRET Yoto OAuth application client secret.
YOTOSHELF_YOTO_REDIRECT_URL {PUBLIC_URL}/api/v1/yoto-accounts/callback Yoto OAuth callback URL. Derived from YOTOSHELF_PUBLIC_URL unless set explicitly. Enter the exact value as the Redirect URI on dashboard.yoto.dev.

Create the OAuth application at dashboard.yoto.dev and enable the permissions matching YotoShelf's requested scopes:

  • View basic information about your family
  • View/Manage players
  • Remotely control players
  • View and Manage Make Your Own content
  • View, upload and edit custom icons
  • Retain access (offline_access)

Yoto publishes no official mapping from these dashboard permissions to OAuth scopes; the pairing above is measured against the API's observed behavior, not documented by Yoto.

If a requested permission is missing, sign-in fails with a 403 on the first family lookup. If linking already succeeded but a later call returns a 403 with a scope error, the account was linked before this permission existed: ticking the box on dashboard.yoto.dev does not widen a token that was already issued. The app marks such accounts as needing a re-link and shows a re-link action on the Accounts page; use that instead.

Email (SMTP)

VariableDefaultDescription
YOTOSHELF_SMTP_HOST SMTP server hostname.
YOTOSHELF_SMTP_PORT 587 SMTP server port.
YOTOSHELF_SMTP_USER SMTP username.
YOTOSHELF_SMTP_PASSWORD SMTP password.
YOTOSHELF_SMTP_FROM Sender address for outbound email (verification, password reset).

Observability

VariableDefaultDescription
YOTOSHELF_LOG_LEVEL info Log verbosity: debug, info, warn, error.
YOTOSHELF_LOG_FORMAT json Log output format: json or text.
YOTOSHELF_SLOW_QUERY_MS 100 Queries slower than this threshold (milliseconds) are logged as warnings.
YOTOSHELF_METRICS_TOKEN Bearer token for the GET /metrics Prometheus endpoint. Unset = endpoint is open.
YOTOSHELF_OTEL_ENDPOINT OTLP gRPC endpoint for distributed tracing. Empty = tracing disabled.
YOTOSHELF_OTEL_INSECURE true Connect to YOTOSHELF_OTEL_ENDPOINT without TLS. Set to false for a TLS-secured collector.
YOTOSHELF_TRACE_SAMPLE_RATE 0.1 Fraction of traces to sample (0.0–1.0).

Recording

VariableDefaultDescription
YOTOSHELF_RECORDING_CHUNK_SIZE 5 Seconds between audio chunks the browser sends during an in-app recording.
YOTOSHELF_RECORDING_MAX_BYTES 209715200 (200 MiB) Maximum size of a single in-app recording session before it is rejected.
YOTOSHELF_QUICK_RECORD_COLLECTION auto Collection slug that quick recordings are filed into. auto finds or creates a per-user "Quick Recordings" collection; set a specific slug to route recordings there instead.

Housekeeping

VariableDefaultDescription
YOTOSHELF_AUDIT_RETENTION_DAYS 90 Days to keep audit log entries. Set to 0 to disable pruning.