Services/AudioBookshelf
As of: 2026-07-05 — migrated from `services/AUDIOBOOKSHELF.md`
AudioBookshelf
Service Info
- Type: Native systemd (not Docker)
- Version: 2.33.2
- Port: 13378
- Public URL: https://listen.wilsoz.com (proxied via VPS nginx → Tailscale → stronghold)
- Config:
/etc/default/audiobookshelf - Data:
/usr/share/audiobookshelf/(config/, metadata/) - DB:
/usr/share/audiobookshelf/config/absdatabase.sqlite(owned: audiobookshelf:audiobookshelf) - Service user:
audiobookshelf - Backups:
/raid1/Consolidated/AudioBookshelfBackup, nightly 1:30 AM, 7 kept
<syntaxhighlight lang="bash"> systemctl status audiobookshelf systemctl restart audiobookshelf </syntaxhighlight>
Authentik OIDC
- Provider: pk 18, name: "AudioBookshelf OAuth", slug: audiobookshelf
- Application slug: audiobookshelf, URL: https://listen.wilsoz.com
- Client ID: in OpenBao at
secret/audiobookshelffieldoidc-client-id - Client Secret: in OpenBao at
secret/audiobookshelffieldoidc-client-secret - Match existing accounts by: username
- Auto-register new users: yes
- Auto-launch SSO: no (local login still shown as fallback)
Redirect URIs registered in Authentik
<syntaxhighlight lang="text"> https://listen.wilsoz.com/auth/openid/callback https://listen.wilsoz.com/audiobookshelf/auth/openid/callback audiobookshelf://oauth </syntaxhighlight>
OIDC Endpoints (from Authentik discovery)
<syntaxhighlight lang="text"> Issuer: https://key.wilsoz.com/application/o/audiobookshelf/ Authorize: https://key.wilsoz.com/application/o/authorize/ Token: https://key.wilsoz.com/application/o/token/ UserInfo: https://key.wilsoz.com/application/o/userinfo/ JWKS: https://key.wilsoz.com/application/o/audiobookshelf/jwks/ Logout: https://key.wilsoz.com/application/o/audiobookshelf/end-session/ </syntaxhighlight>
Gotchas
OIDC config lives in SQLite, not a config file. Settings are in the settings table under key server-settings as a JSON blob. ABS must be stopped before writing (owned by audiobookshelf user):
<syntaxhighlight lang="bash"> systemctl stop audiobookshelf sudo -u audiobookshelf sqlite3 /usr/share/audiobookshelf/config/absdatabase.sqlite \
"SELECT value FROM settings WHERE key='server-settings';" | python3 -m json.tool
systemctl start audiobookshelf </syntaxhighlight>
authOpenIDSubfolderForRedirectURLs must be set to "" (empty string, not absent). If this field is missing from the settings JSON, ABS sends https://listen.wilsoz.com/undefined/auth/openid/callback as the redirect URI — a JS undefined coerced to string. This field is normally set by the v2.17.4 migration, but only if OIDC was already enabled at migration time. If you configure OIDC by writing directly to the DB, add this field manually.
Authentik authorize/token/userinfo URLs are shared, not per-provider. Even with issuer_mode: per_provider, the actual endpoints are:
/application/o/authorize/(not/application/o/audiobookshelf/authorize/)/application/o/token/(not/application/o/audiobookshelf/token/)/application/o/userinfo/(not/application/o/audiobookshelf/userinfo/)
Only the issuer, JWKS, and end-session URLs are per-provider. Use the discovery document to get the correct URLs: <syntaxhighlight lang="bash"> curl -s https://key.wilsoz.com/application/o/audiobookshelf/.well-known/openid-configuration | python3 -m json.tool </syntaxhighlight>
Authentik API PATCH returns 403 for providers — use PUT with the full provider object instead.
Python urllib drops Authorization header on HTTPS redirect — use subprocess + curl for Authentik API calls from Python scripts.
Users
| Username | Type | |
|---|---|---|
| admin | (none) | root |
| marcus | (none) | user |
| travis | (none) | user |
| mehone | [email protected] | user |
| stefany | (none) | user |
Note: marcus and admin have no email stored — OIDC match is by username, not email.