Fix Homebox OIDC invalid_scope error by allowing per-client extra scopes

_authelia_provision_oidc_client() hardcoded openid/profile/email as the
only scopes a registered client could ever request, but Homebox's own
Authelia integration needs 'groups' too — requesting it without it being
in the client's own scopes allowlist made Authelia reject every login
with invalid_scope, even though the server supports 'groups' generally.

Add an EXTRA_SCOPES positional arg (space-separated, right after
REQUIRE_PKCE) that only Homebox's caller populates ("groups"); every
other existing caller passes "" and gets a byte-for-byte unchanged
client registration.
This commit is contained in:
Claude
2026-08-27 12:39:22 +00:00
parent fc9733f937
commit 6f8a703004
9 changed files with 31 additions and 12 deletions
+1 -1
View File
@@ -257,7 +257,7 @@ _actualbudget_offer_authelia_oidc() {
prompt_yn " Require two-factor for Actual Budget logins via Authelia too? (y/n):" "y" _2fa
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
if ! _authelia_provision_oidc_client "ActualBudget" "actualbudget" "$AUTH_POLICY" "y" "n" \
if ! _authelia_provision_oidc_client "ActualBudget" "actualbudget" "$AUTH_POLICY" "y" "n" "" \
"https://${AB_OIDC_DOMAIN}/openid/callback"; then
log_warning "Couldn't register Actual Budget as an OIDC client in Authelia — skipping SSO setup."
return 0
+1 -1
View File
@@ -231,7 +231,7 @@ _audiobookshelf_offer_authelia_oidc() {
prompt_yn " Require two-factor for Audiobookshelf logins via Authelia too? (y/n):" "y" _2fa
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
if ! _authelia_provision_oidc_client "Audiobookshelf" "audiobookshelf" "$AUTH_POLICY" "y" "y" \
if ! _authelia_provision_oidc_client "Audiobookshelf" "audiobookshelf" "$AUTH_POLICY" "y" "y" "" \
"https://${APP_DOMAIN}/auth/openid/callback" "https://${APP_DOMAIN}/auth/openid/mobile-redirect" "audiobookshelf://oauth"; then
log_warning "Couldn't register Audiobookshelf as an OIDC client in Authelia — skipping SSO setup."
return 0
+23 -4
View File
@@ -2985,7 +2985,13 @@ _authelia_remove_oidc_client() {
# Guard every cross-file call with `declare -F` per this repo's chaining
# convention (services/gitea.sh does).
#
# Args: APP_NAME CLIENT_ID AUTH_POLICY RESTART_AUTH(y/n) <redirect_uri> [<redirect_uri> ...]
# Args: APP_NAME CLIENT_ID AUTH_POLICY RESTART_AUTH(y/n) REQUIRE_PKCE(y/n) EXTRA_SCOPES <redirect_uri> [<redirect_uri> ...]
# EXTRA_SCOPES — space-separated scope names to add on top of the
# always-included openid/profile/email (e.g. "groups" for an app whose own
# OIDC settings request group membership, like Homebox). Pass "" when the
# app only needs the three defaults — every existing caller before this
# parameter was added does exactly that, so their registered client is
# byte-for-byte unchanged.
# Out-params (not `local` — read them after the call returns):
# OIDC_CLIENT_SECRET_PLAIN the plaintext secret. Shown once — Authelia's
# config only ever stores the hash — so the
@@ -3010,7 +3016,7 @@ _authelia_remove_oidc_client() {
# that's already registered is NOT a failure — it gets replaced (see the
# comment at that check below).
_authelia_provision_oidc_client() {
local APP_NAME="$1" CLIENT_ID="$2" AUTH_POLICY="$3" RESTART_AUTH="$4" REQUIRE_PKCE="$5"; shift 5
local APP_NAME="$1" CLIENT_ID="$2" AUTH_POLICY="$3" RESTART_AUTH="$4" REQUIRE_PKCE="$5" EXTRA_SCOPES="$6"; shift 6
local -a REDIRECT_URIS=("$@")
OIDC_CLIENT_SECRET_PLAIN=""
@@ -3121,6 +3127,19 @@ _authelia_provision_oidc_client() {
pkce_challenge_method: 'S256'"
fi
# EXTRA_SCOPES is space-separated (e.g. "groups") and additive to the
# three always-included scopes below — Authelia rejects a callback
# requesting any scope not in this exact per-client allowlist, even one
# the server otherwise supports (confirmed live: Homebox's own
# HBOX_OIDC_SCOPE=openid profile email groups was rejected with
# invalid_scope until 'groups' was added here too).
local EXTRA_SCOPES_YAML=""
local _scope
for _scope in $EXTRA_SCOPES; do
EXTRA_SCOPES_YAML="${EXTRA_SCOPES_YAML}
- '${_scope}'"
done
local CLIENT_BLOCK=" - client_id: '${CLIENT_ID}'
client_name: '${APP_NAME}'
client_secret: '${CLIENT_SECRET_HASH}'
@@ -3131,7 +3150,7 @@ ${REDIRECT_URIS_YAML}
scopes:
- 'openid'
- 'profile'
- 'email'
- 'email'${EXTRA_SCOPES_YAML}
grant_types:
- 'authorization_code'
response_types:
@@ -3287,7 +3306,7 @@ _authelia_add_oidc_client() {
local RESTART_AUTH=""
prompt_yn " Restart Authelia to apply? (y/n):" "y" RESTART_AUTH
_authelia_provision_oidc_client "$APP_NAME" "$CLIENT_ID" "$AUTH_POLICY" "$RESTART_AUTH" "$REQUIRE_PKCE" "${REDIRECT_URIS[@]}" \
_authelia_provision_oidc_client "$APP_NAME" "$CLIENT_ID" "$AUTH_POLICY" "$RESTART_AUTH" "$REQUIRE_PKCE" "" "${REDIRECT_URIS[@]}" \
|| return 1
local CLIENT_SECRET_PLAIN="$OIDC_CLIENT_SECRET_PLAIN"
+1 -1
View File
@@ -286,7 +286,7 @@ _beszel_offer_authelia_oidc() {
prompt_yn " Require two-factor for Beszel logins via Authelia too? (y/n):" "y" _2fa
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
if ! _authelia_provision_oidc_client "Beszel" "beszel" "$AUTH_POLICY" "y" "y" \
if ! _authelia_provision_oidc_client "Beszel" "beszel" "$AUTH_POLICY" "y" "y" "" \
"https://${APP_DOMAIN}/api/oauth2-redirect"; then
log_warning "Couldn't register Beszel as an OIDC client in Authelia — skipping SSO setup."
return 0
+1 -1
View File
@@ -219,7 +219,7 @@ _gitea_offer_authelia_sso() {
prompt_yn " Require two-factor for Gitea logins via Authelia too? (y/n):" "y" _2fa
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
if ! _authelia_provision_oidc_client "Gitea" "gitea" "$AUTH_POLICY" "y" "n" \
if ! _authelia_provision_oidc_client "Gitea" "gitea" "$AUTH_POLICY" "y" "n" "" \
"https://${GITEA_OIDC_DOMAIN}/user/oauth2/authelia/callback"; then
log_warning "Couldn't register Gitea as an OIDC client in Authelia — skipping SSO setup."
return 0
+1 -1
View File
@@ -249,7 +249,7 @@ _homebox_offer_authelia_oidc() {
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" \
if ! _authelia_provision_oidc_client "Homebox" "homebox" "$AUTH_POLICY" "y" "y" "groups" \
"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
+1 -1
View File
@@ -274,7 +274,7 @@ _immich_offer_authelia_oidc() {
# Same three redirect URIs as the "Immich" preset in authelia.sh's own
# generic OIDC menu (web login, account-linking, mobile app callback) —
# kept identical on purpose so either path produces the same client.
if ! _authelia_provision_oidc_client "Immich" "immich" "$AUTH_POLICY" "y" "n" \
if ! _authelia_provision_oidc_client "Immich" "immich" "$AUTH_POLICY" "y" "n" "" \
"https://${APP_DOMAIN}/auth/login" "https://${APP_DOMAIN}/user-settings" "app.immich:///oauth-callback"; then
log_warning "Couldn't register Immich as an OIDC client in Authelia — skipping SSO setup."
return 0
+1 -1
View File
@@ -259,7 +259,7 @@ _mealie_offer_authelia_oidc() {
prompt_yn " Require two-factor for Mealie logins via Authelia too? (y/n):" "y" _2fa
[[ "$_2fa" =~ ^[Yy]$ ]] || AUTH_POLICY="one_factor"
if ! _authelia_provision_oidc_client "Mealie" "mealie" "$AUTH_POLICY" "y" "n" "${BASE_URL}/login"; then
if ! _authelia_provision_oidc_client "Mealie" "mealie" "$AUTH_POLICY" "y" "n" "" "${BASE_URL}/login"; then
log_warning "Couldn't register Mealie as an OIDC client in Authelia — skipping SSO setup."
return 0
fi