Wire Authelia SSO into Homebox
_homebox_offer_authelia_oidc() automates Homebox's own native OIDC support (real env vars, not paste-in instructions) — confirmed the exact variable names and redirect path against homebox.software's own OIDC docs and authelia.com's Homebox integration page, not guessed. Needs PKCE, unlike Mealie/ActualBudget. The stock compose template listed env vars individually in `environment:` rather than using `env_file: .env` — added to the template, and patched onto any pre-existing install's compose file the first time this offer runs, or the OIDC vars written to .env would never actually reach the container. _homebox_offer_disable_local_login() is the separate, gated "replace local login entirely" step (HBOX_OPTIONS_ALLOW_LOCAL_LOGIN=false + HBOX_OIDC_AUTO_REDIRECT=true), same "have you tested it first" pattern as Mealie/Beszel.
This commit is contained in:
@@ -493,6 +493,7 @@ right (Portainer, ntfy), not general familiarity with the product:
|
|||||||
| Service | Native OIDC? | Notes |
|
| Service | Native OIDC? | Notes |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `mealie` | Yes — wired up | Pure env vars (`OIDC_AUTH_ENABLED`, `OIDC_CLIENT_ID/SECRET`, `OIDC_CONFIGURATION_URL`), see `_mealie_offer_authelia_oidc()`. Redirect URI is `<BASE_URL>/login`. Needs a `--forwarded-allow-ips` entrypoint override when Caddy-fronted, or the generated redirect URI comes out `http://` even when actually served over `https://` — see the function's own comment. |
|
| `mealie` | Yes — wired up | Pure env vars (`OIDC_AUTH_ENABLED`, `OIDC_CLIENT_ID/SECRET`, `OIDC_CONFIGURATION_URL`), see `_mealie_offer_authelia_oidc()`. Redirect URI is `<BASE_URL>/login`. Needs a `--forwarded-allow-ips` entrypoint override when Caddy-fronted, or the generated redirect URI comes out `http://` even when actually served over `https://` — see the function's own comment. |
|
||||||
|
| `homebox` | Yes — wired up | Pure env vars (`HBOX_OIDC_ENABLED`, `HBOX_OIDC_ISSUER_URL`, `HBOX_OIDC_CLIENT_ID/SECRET`, `HBOX_OIDC_SCOPE`), see `_homebox_offer_authelia_oidc()`. Confirmed against homebox.software's own OIDC docs and authelia.com's Homebox integration page — needs PKCE (unlike Mealie/ActualBudget). Redirect path is `/api/v1/users/login/oidc/callback`; issuer URL is reportedly sensitive to a trailing slash (a real upstream bug), so it's written from this repo's own portal-URL value as-is, never with one appended. The stock compose template didn't have `env_file: .env` (vars were listed individually in `environment:` instead) — added to the template, and patched onto any pre-existing install's compose file the first time this offer runs, or the written `.env` additions would silently never reach the container. `HBOX_OPTIONS_ALLOW_LOCAL_LOGIN=false`/`HBOX_OIDC_AUTO_REDIRECT=true` are real, documented env vars for fully replacing local login, offered as a separate step gated behind the same "have you tested the button first" confirmation as Mealie/Beszel. |
|
||||||
| `actualbudget` | Yes — wired up | Pure env vars (`ACTUAL_OPENID_DISCOVERY_URL`, `ACTUAL_OPENID_CLIENT_ID/SECRET`, `ACTUAL_OPENID_SERVER_HOSTNAME`), see `_actualbudget_offer_authelia_oidc()`. Redirect path `/openid/callback` (matches the existing preset in `_authelia_add_oidc_client()`'s menu). First OIDC login becomes the server owner if none is set yet — Actual's own behavior. |
|
| `actualbudget` | Yes — wired up | Pure env vars (`ACTUAL_OPENID_DISCOVERY_URL`, `ACTUAL_OPENID_CLIENT_ID/SECRET`, `ACTUAL_OPENID_SERVER_HOSTNAME`), see `_actualbudget_offer_authelia_oidc()`. Redirect path `/openid/callback` (matches the existing preset in `_authelia_add_oidc_client()`'s menu). First OIDC login becomes the server owner if none is set yet — Actual's own behavior. |
|
||||||
| `immich` | Yes — wired up | Real OAuth2/OIDC settings under Administration → Settings, backed by `GET`/`PUT /api/system-config` — confirmed the exact JSON field names against Immich's own `config-file.md` and source directly (the `oauth` sub-object: `enabled`/`issuerUrl`/`clientId`/`clientSecret`/`scope`/`buttonText`, etc.), not guessed. See `_immich_offer_authelia_oidc()`. GET/PUT exchange the *whole* config object (no partial-patch endpoint), so it round-trips everything else — storage template, library settings — completely unchanged; the same shape already proven by `import-photos.sh`'s own storage-template step in this file. Needs an admin API key, which doesn't exist until the user creates their account on first web visit — this offer runs from both the fresh-install path (usually a no-op that first time) and the "update" rerun path, which is the realistic way most people finish this. |
|
| `immich` | Yes — wired up | Real OAuth2/OIDC settings under Administration → Settings, backed by `GET`/`PUT /api/system-config` — confirmed the exact JSON field names against Immich's own `config-file.md` and source directly (the `oauth` sub-object: `enabled`/`issuerUrl`/`clientId`/`clientSecret`/`scope`/`buttonText`, etc.), not guessed. See `_immich_offer_authelia_oidc()`. GET/PUT exchange the *whole* config object (no partial-patch endpoint), so it round-trips everything else — storage template, library settings — completely unchanged; the same shape already proven by `import-photos.sh`'s own storage-template step in this file. Needs an admin API key, which doesn't exist until the user creates their account on first web visit — this offer runs from both the fresh-install path (usually a no-op that first time) and the "update" rerun path, which is the realistic way most people finish this. |
|
||||||
| `audiobookshelf` | Yes — wired up (Authelia side only) | Checked against audiobookshelf.org's own OIDC docs: config is UI-only (Settings → Authentication), no env var or config API — so `_audiobookshelf_offer_authelia_oidc()` registers the Authelia client (needs PKCE, confirmed via authelia.com's own integration page for it) and prints the exact individual-endpoint values to paste in, since Audiobookshelf wants those rather than a discovery URL. Three redirect URIs: web callback, mobile-redirect, and the `audiobookshelf://oauth` app-scheme callback. |
|
| `audiobookshelf` | Yes — wired up (Authelia side only) | Checked against audiobookshelf.org's own OIDC docs: config is UI-only (Settings → Authentication), no env var or config API — so `_audiobookshelf_offer_authelia_oidc()` registers the Authelia client (needs PKCE, confirmed via authelia.com's own integration page for it) and prints the exact individual-endpoint values to paste in, since Audiobookshelf wants those rather than a discovery URL. Three redirect URIs: web callback, mobile-redirect, and the `audiobookshelf://oauth` app-scheme callback. |
|
||||||
|
|||||||
@@ -201,6 +201,124 @@ fi
|
|||||||
|
|
||||||
register_service homebox utilities "Home inventory and asset management (Homebox)" 7745
|
register_service homebox utilities "Home inventory and asset management (Homebox)" 7745
|
||||||
|
|
||||||
|
# Offers to wire Homebox's own native OIDC support to Authelia — real
|
||||||
|
# server-side automation via env vars, not paste-in instructions, same
|
||||||
|
# shape as Mealie/ActualBudget. Confirmed against homebox.software's own
|
||||||
|
# OIDC docs and authelia.com's Homebox integration page directly: PKCE is
|
||||||
|
# required, redirect path is /api/v1/users/login/oidc/callback, and the
|
||||||
|
# issuer URL is sensitive to a trailing slash (a real reported bug) — the
|
||||||
|
# portal URL this repo already stores never has one, so left as-is here.
|
||||||
|
#
|
||||||
|
# Args: DIR CONTAINER
|
||||||
|
_homebox_offer_authelia_oidc() {
|
||||||
|
local DIR="$1" CONTAINER="$2"
|
||||||
|
|
||||||
|
declare -F _authelia_provision_oidc_client >/dev/null 2>&1 || return 0
|
||||||
|
[ -d "$DOCKER_DIR/authelia" ] || return 0
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
local USE_SSO=""
|
||||||
|
prompt_yn " Add \"Sign in with Authelia\" (OpenID Connect) to Homebox? (y/n):" "n" USE_SSO
|
||||||
|
[[ "$USE_SSO" =~ ^[Yy]$ ]] || return 0
|
||||||
|
|
||||||
|
if grep -q '^HBOX_OIDC_ENABLED=' "$DIR/.env" 2>/dev/null; then
|
||||||
|
echo ""
|
||||||
|
log_info "Authelia SSO is already configured for Homebox (HBOX_OIDC_* already set in $DIR/.env)."
|
||||||
|
local RECONFIGURE=""
|
||||||
|
prompt_yn " Reconfigure it (registers a fresh Authelia client + secret)? (y/n):" "n" RECONFIGURE
|
||||||
|
[[ "$RECONFIGURE" =~ ^[Yy]$ ]] || return 0
|
||||||
|
sed -i '/^HBOX_OIDC_/d; /^HBOX_OPTIONS_TRUST_PROXY=/d' "$DIR/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Existing installs from before this offer existed won't have env_file
|
||||||
|
# picked up their .env's OIDC additions otherwise — this repo's own
|
||||||
|
# compose template gained it above; a pre-existing compose file needs
|
||||||
|
# the same one-line patch to actually load what's about to be written.
|
||||||
|
if ! grep -q '^\s*env_file: \.env\s*$' "$DIR/docker-compose.yml" 2>/dev/null; then
|
||||||
|
sed -i "/^ hostname: /a\\ env_file: .env" "$DIR/docker-compose.yml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local APP_DOMAIN
|
||||||
|
APP_DOMAIN="$(_authelia_pick_domain "Domain Homebox is reachable at (number or domain)")"
|
||||||
|
if [ -z "$APP_DOMAIN" ]; then
|
||||||
|
log_warning "No domain entered — skipping SSO setup."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local _2fa="" AUTH_POLICY="two_factor"
|
||||||
|
prompt_yn " Require two-factor for Homebox logins via Authelia too? (y/n):" "y" _2fa
|
||||||
|
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
|
||||||
|
|
||||||
|
if ! _authelia_provision_oidc_client "Homebox" "homebox" "$AUTH_POLICY" "y" "y" \
|
||||||
|
"https://${APP_DOMAIN}/api/v1/users/login/oidc/callback"; then
|
||||||
|
log_warning "Couldn't register Homebox as an OIDC client in Authelia — skipping SSO setup."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >> "$DIR/.env" << ENV
|
||||||
|
|
||||||
|
# Written by services/homebox.sh's Authelia SSO step — adds "Sign in with
|
||||||
|
# Authelia" alongside local login; local accounts keep working unchanged.
|
||||||
|
HBOX_OIDC_ENABLED=true
|
||||||
|
HBOX_OIDC_ISSUER_URL=${OIDC_AUTHELIA_PORTAL_URL}
|
||||||
|
HBOX_OIDC_CLIENT_ID=homebox
|
||||||
|
HBOX_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET_PLAIN}
|
||||||
|
HBOX_OIDC_SCOPE=openid profile email groups
|
||||||
|
HBOX_OPTIONS_TRUST_PROXY=true
|
||||||
|
ENV
|
||||||
|
chown "$ACTUAL_USER:$ACTUAL_USER" "$DIR/.env" 2>/dev/null || true
|
||||||
|
|
||||||
|
(cd "$DIR" && docker compose up -d) \
|
||||||
|
&& log_success "\"Sign in with Authelia\" added to Homebox — local login still works too." \
|
||||||
|
|| log_warning "Restart failed — check: docker compose -f $DIR/docker-compose.yml logs"
|
||||||
|
|
||||||
|
declare -F _authelia_scope_access >/dev/null 2>&1 && _authelia_scope_access "homebox" "$APP_DOMAIN"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_info "Test the \"Login with Authelia\" button on Homebox's own login page before"
|
||||||
|
log_info "disabling local login — re-run 'sudo ./setup.sh homebox' (choose update) once"
|
||||||
|
log_info "you've confirmed it works, and you'll be offered that as a separate step."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Split out from _homebox_offer_authelia_oidc so disabling local login is
|
||||||
|
# never offered in the same breath as first setting SSO up — same
|
||||||
|
# reasoning as Mealie/Beszel's equivalent split (confirmed live on Beszel:
|
||||||
|
# saying yes before actually testing the button leaves both login paths
|
||||||
|
# broken at once). Only reached from a later "update" rerun once OIDC is
|
||||||
|
# already configured and the admin declines to reconfigure.
|
||||||
|
_homebox_offer_disable_local_login() {
|
||||||
|
local DIR="$1"
|
||||||
|
grep -q '^HBOX_OPTIONS_ALLOW_LOCAL_LOGIN=false' "$DIR/.env" 2>/dev/null && return 0
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
local _tested=""
|
||||||
|
prompt_yn " Have you ALREADY logged into Homebox successfully using the Authelia button (not just enabled it)? (y/n):" "n" _tested
|
||||||
|
if [[ ! "$_tested" =~ ^[Yy]$ ]]; then
|
||||||
|
log_info "Skipped. Test the Authelia login button first, then re-run 'sudo ./setup.sh homebox' (choose update) to come back to this."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local _disable_local=""
|
||||||
|
prompt_yn " Also disable Homebox's own local login, so Authelia is the only way in? (y/n):" "n" _disable_local
|
||||||
|
[[ "$_disable_local" =~ ^[Yy]$ ]] || return 0
|
||||||
|
|
||||||
|
log_warning "Anyone without an Authelia account (only a local Homebox one) will no longer be able to log in."
|
||||||
|
log_info "Reversible any time: set HBOX_OPTIONS_ALLOW_LOCAL_LOGIN back to true in $DIR/.env and 'docker compose up -d'."
|
||||||
|
local _auto_redirect=""
|
||||||
|
prompt_yn " Skip Homebox's login page entirely and jump straight to Authelia? (y/n):" "y" _auto_redirect
|
||||||
|
|
||||||
|
sed -i '/^HBOX_OPTIONS_ALLOW_LOCAL_LOGIN=/d; /^HBOX_OIDC_AUTO_REDIRECT=/d' "$DIR/.env"
|
||||||
|
{
|
||||||
|
echo "HBOX_OPTIONS_ALLOW_LOCAL_LOGIN=false"
|
||||||
|
[[ "$_auto_redirect" =~ ^[Yy]$ ]] && echo "HBOX_OIDC_AUTO_REDIRECT=true"
|
||||||
|
} >> "$DIR/.env"
|
||||||
|
chown "$ACTUAL_USER:$ACTUAL_USER" "$DIR/.env" 2>/dev/null || true
|
||||||
|
|
||||||
|
(cd "$DIR" && docker compose up -d) \
|
||||||
|
&& log_success "Local login is now disabled — Authelia is the only way into Homebox." \
|
||||||
|
|| log_warning "Restart failed — check: docker compose -f $DIR/docker-compose.yml logs"
|
||||||
|
}
|
||||||
|
|
||||||
install_homebox() {
|
install_homebox() {
|
||||||
require_docker || return 1
|
require_docker || return 1
|
||||||
log_info "Installing Homebox..."
|
log_info "Installing Homebox..."
|
||||||
@@ -261,6 +379,8 @@ install_homebox() {
|
|||||||
( cd "$HB_DIR" && docker compose pull && docker compose up -d ) \
|
( cd "$HB_DIR" && docker compose pull && docker compose up -d ) \
|
||||||
&& log_success "Homebox image refreshed" \
|
&& log_success "Homebox image refreshed" \
|
||||||
|| log_warning "Refresh failed — check: docker compose -f $HB_DIR/docker-compose.yml logs"
|
|| log_warning "Refresh failed — check: docker compose -f $HB_DIR/docker-compose.yml logs"
|
||||||
|
_homebox_offer_authelia_oidc "$HB_DIR" "$CONTAINER"
|
||||||
|
_homebox_offer_disable_local_login "$HB_DIR"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
cancel)
|
cancel)
|
||||||
@@ -326,6 +446,7 @@ services:
|
|||||||
container_name: $CONTAINER
|
container_name: $CONTAINER
|
||||||
hostname: $CONTAINER
|
hostname: $CONTAINER
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
- HBOX_LOG_LEVEL=info
|
- HBOX_LOG_LEVEL=info
|
||||||
- HBOX_WEB_MAX_UPLOAD_SIZE=10
|
- HBOX_WEB_MAX_UPLOAD_SIZE=10
|
||||||
@@ -353,6 +474,8 @@ HB_ENV
|
|||||||
|
|
||||||
configure_caddy_for_service "Homebox${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)}" "${CONTAINER}:7745" "homebox${INSTANCE_SUFFIX:+-$INSTANCE_SUFFIX}"
|
configure_caddy_for_service "Homebox${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)}" "${CONTAINER}:7745" "homebox${INSTANCE_SUFFIX:+-$INSTANCE_SUFFIX}"
|
||||||
|
|
||||||
|
_homebox_offer_authelia_oidc "$HB_DIR" "$CONTAINER"
|
||||||
|
|
||||||
write_readme "$HB_DIR" << MD
|
write_readme "$HB_DIR" << MD
|
||||||
# Homebox${INSTANCE_SUFFIX:+ — $INSTANCE_SUFFIX}
|
# Homebox${INSTANCE_SUFFIX:+ — $INSTANCE_SUFFIX}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user