Merge pull request #390 from outis1one/claude/frigate-authelia-openid-0l1htj

Claude/frigate authelia openid 0l1htj
This commit is contained in:
Outis
2026-08-24 08:36:08 -04:00
committed by GitHub
+352 -50
View File
@@ -244,10 +244,13 @@ install_authelia() {
echo " 11) Un-protect a site (undoes option 10 for one site)" echo " 11) Un-protect a site (undoes option 10 for one site)"
echo " 12) Export/import user data (backup accounts + 2FA before a reinstall," echo " 12) Export/import user data (backup accounts + 2FA before a reinstall,"
echo " or restore a previous export)" echo " or restore a previous export)"
echo " 13) Make sure admins always have access to every site (old and new —"
echo " safe to re-run any time)"
echo " 14) Rename an outside-access group (e.g. \"customer1\" -> \"acme-corp\")"
echo " 0) Leave as-is / exit" echo " 0) Leave as-is / exit"
echo "" echo ""
local EXISTING_CHOICE="" local EXISTING_CHOICE=""
prompt_text " Choice [1-12, 0 to exit]:" "0" EXISTING_CHOICE prompt_text " Choice [1-14, 0 to exit]:" "0" EXISTING_CHOICE
case "$EXISTING_CHOICE" in case "$EXISTING_CHOICE" in
1) 1)
add_authelia_domain add_authelia_domain
@@ -296,6 +299,14 @@ install_authelia() {
_authelia_export_import_users_menu _authelia_export_import_users_menu
return 0 return 0
;; ;;
13)
_authelia_ensure_admin_access_everywhere
return 0
;;
14)
_authelia_rename_group
return 0
;;
0|*) 0|*)
echo " Keeping existing Authelia. (Edit config/users.yml then: cd $AUTHELIA_DIR && docker compose restart authelia)" echo " Keeping existing Authelia. (Edit config/users.yml then: cd $AUTHELIA_DIR && docker compose restart authelia)"
return 0 return 0
@@ -451,6 +462,14 @@ authentication_backend:
access_control: access_control:
default_policy: deny default_policy: deny
rules: rules:
# Admins always match first, on every domain this instance protects — this
# rule must stay above any per-service scoping rule (old or new) below it,
# or a group's "deny elsewhere" rule could accidentally catch an admin.
# add_authelia_domain and _authelia_scope_access both preserve this
# ordering automatically — see _authelia_ensure_admin_bypass.
- domain: "*.${AUTHELIA_DOMAIN}"
subject: "group:admins"
policy: two_factor
- domain: "*.${AUTHELIA_DOMAIN}" - domain: "*.${AUTHELIA_DOMAIN}"
policy: two_factor policy: two_factor
@@ -733,9 +752,16 @@ add_authelia_domain() {
NEW_PORTAL_DOMAIN="${NEW_PORTAL_SUBDOMAIN}.${NEW_DOMAIN}" NEW_PORTAL_DOMAIN="${NEW_PORTAL_SUBDOMAIN}.${NEW_DOMAIN}"
# ── access_control.rules: insert right after "rules:" ──────────────────── # ── access_control.rules: insert right after "rules:" ────────────────────
# The admin-bypass rule goes first, this domain's own catch-all second —
# both inserted together in one shot so a fresh domain never has a window
# where the catch-all exists without the bypass above it. See
# _authelia_ensure_admin_bypass for why this ordering has to hold.
awk -v domain="$NEW_DOMAIN" ' awk -v domain="$NEW_DOMAIN" '
{ print } { print }
/^ rules:$/ && !done { /^ rules:$/ && !done {
print " - domain: \"*." domain "\""
print " subject: \"group:admins\""
print " policy: two_factor"
print " - domain: \"*." domain "\"" print " - domain: \"*." domain "\""
print " policy: two_factor" print " policy: two_factor"
done=1 done=1
@@ -861,7 +887,10 @@ remove_authelia_domain() {
fi fi
local -a apex_domains local -a apex_domains
mapfile -t apex_domains < <(grep -oE '^ - domain: "\*\.[^"]+"' "$CONFIG_FILE" | sed -E 's/^ - domain: "\*\.(.+)"$/\1/') # Each apex domain now has two rules sharing this exact domain string —
# its admin-bypass rule and its plain catch-all (see
# _authelia_ensure_admin_bypass) — so dedupe or it'd list every domain twice.
mapfile -t apex_domains < <(grep -oE '^ - domain: "\*\.[^"]+"' "$CONFIG_FILE" | sed -E 's/^ - domain: "\*\.(.+)"$/\1/' | awk '!seen[$0]++')
echo "" echo ""
if [ "${#apex_domains[@]}" -eq 0 ]; then if [ "${#apex_domains[@]}" -eq 0 ]; then
@@ -913,6 +942,23 @@ remove_authelia_domain() {
prompt_yn " Continue? (y/n):" "n" CONFIRM_RM prompt_yn " Continue? (y/n):" "n" CONFIRM_RM
[[ "$CONFIRM_RM" =~ ^[Yy]$ ]] || { log_info "Cancelled — nothing changed."; return 0; } [[ "$CONFIRM_RM" =~ ^[Yy]$ ]] || { log_info "Cancelled — nothing changed."; return 0; }
# ── access_control.rules: remove this domain's admin-bypass rule first ────
# (3 lines: domain/subject/policy — see _authelia_ensure_admin_bypass) —
# has to run before the plain catch-all removal below, which only knows
# how to strip a 2-line domain/policy pair and would otherwise leave this
# rule's own "policy:" line orphaned, the exact corruption class this
# instance was repaired from once already.
awk -v domain="$RM_DOMAIN" '
BEGIN { skip=0 }
skip > 0 { skip--; next }
$0 == " - domain: \"*." domain "\"" {
getline nxt
if (nxt == " subject: \"group:admins\"") { skip=1; next }
print; print nxt; next
}
{ print }
' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
# ── access_control.rules: remove the "- domain: "*.X"" + "policy: ..." pair ── # ── access_control.rules: remove the "- domain: "*.X"" + "policy: ..." pair ──
awk -v domain="$RM_DOMAIN" ' awk -v domain="$RM_DOMAIN" '
BEGIN { skip=0 } BEGIN { skip=0 }
@@ -1543,7 +1589,85 @@ _authelia_create_user_noninteractive() {
# domain that's already scoped just report the existing group instead of # domain that's already scoped just report the existing group instead of
# duplicating rules. # duplicating rules.
# #
# Idempotent: makes sure a "subject: group:admins" rule exists for $domain's
# access_control.rules, above every other rule for that domain, then returns
# the 1-indexed line number its "policy:" line ended up on (via ADMIN_BYPASS_LINE,
# not stdout — awk already uses stdout for the rewritten file). Callers that
# insert a NEW rule for this domain (_authelia_scope_access's deny-elsewhere
# rule in particular) must insert it AFTER that line, never at the literal
# top of "rules:" — Authelia takes the first matching rule, so a deny rule
# landing above the admin-bypass rule would catch an admin who's also (by
# mistake, or by some future feature) a member of the group being denied.
# install_authelia and add_authelia_domain both bake this rule in directly
# at creation time instead of calling this — it's for retrofitting an apex
# domain that predates this (see _authelia_ensure_admin_access_everywhere,
# the menu-driven bulk version of this for an existing install) and for
# _authelia_scope_access's own just-in-time safety net.
_authelia_ensure_admin_bypass() {
local config_file="$1" domain="$2"
ADMIN_BYPASS_LINE=""
ADMIN_BYPASS_ADDED="false"
local result
result="$(awk -v domain="$domain" '
{ lines[NR] = $0 }
END {
for (i = 1; i < NR; i++) {
if (lines[i] == " - domain: \"*." domain "\"" && lines[i+1] == " subject: \"group:admins\"") {
print i + 2
exit
}
}
}
' "$config_file")"
if [ -n "$result" ]; then
ADMIN_BYPASS_LINE="$result"
return 0
fi
ADMIN_BYPASS_ADDED="true"
awk -v domain="$domain" '
{ print }
/^ rules:$/ && !done {
print " - domain: \"*." domain "\""
print " subject: \"group:admins\""
print " policy: two_factor"
done=1
}
' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file"
chown 1000:1000 "$config_file" 2>/dev/null || true
# The block we just inserted is always lines 2-4 counting from " rules:"
# (which awk just placed the block right after) — but simplest and least
# fragile is to just re-run the same lookup now that it exists.
ADMIN_BYPASS_LINE="$(awk -v domain="$domain" '
{ lines[NR] = $0 }
END {
for (i = 1; i < NR; i++) {
if (lines[i] == " - domain: \"*." domain "\"" && lines[i+1] == " subject: \"group:admins\"") {
print i + 2
exit
}
}
}
' "$config_file")"
}
# Args: SERVICE_ID DOMAIN # Args: SERVICE_ID DOMAIN
#
# service_id is only ever used as the SUGGESTED group name when creating a
# brand-new group — the actual group is whatever the user picks or types
# below, so the same group (e.g. "customer1-only") can be attached to
# several different sites over time instead of getting a fresh
# "<service_id>-only" group every call. The "-only" suffix itself is kept
# internally (never shown to the user, who just sees "customer1") because
# it's load-bearing elsewhere: _authelia_list_scoped_groups,
# _authelia_report_access_scope, edit_authelia_user's per-user group
# toggle, and _authelia_unprotect_site's cleanup all already key off that
# exact suffix pattern to find "this is a site-scoping group, not some
# other group a user happens to be in" — dropping it would mean touching
# all four of those instead of just this one function.
_authelia_scope_access() { _authelia_scope_access() {
local service_id="$1" domain="$2" local service_id="$1" domain="$2"
local authelia_dir="$DOCKER_DIR/authelia" local authelia_dir="$DOCKER_DIR/authelia"
@@ -1552,54 +1676,100 @@ _authelia_scope_access() {
[ -f "$config_file" ] || return 0 [ -f "$config_file" ] || return 0
local group="${service_id}-only" echo ""
echo " Who should be able to reach $domain via Authelia?"
echo " 0) Native — your own users, no extra restriction (default — same"
echo " access as everything else)"
echo " 1) Outside access — a named group of specific users only"
local scope_choice=""
prompt_text " Choice [0 for native, 1 for outside access]:" "0" scope_choice
[ "$scope_choice" = "1" ] || return 0
if grep -qF "subject: \"group:${group}\"" "$config_file" 2>/dev/null; then local -a existing_groups
log_info "Access to $domain is already scoped to group '$group'." mapfile -t existing_groups < <(_authelia_list_scoped_groups "$users_file")
local group="" is_new_group="true" i
if [ "${#existing_groups[@]}" -gt 0 ]; then
echo " Existing outside-access groups:"
for i in "${!existing_groups[@]}"; do
echo " $((i + 1))) ${existing_groups[$i]%-only}"
done
echo " Pick a number to add $domain to one of these, or type a new group"
echo " name (e.g. \"customer1\") to create one."
else
echo " No outside-access groups exist yet — type a name to create one"
echo " (e.g. \"customer1\")."
fi
local group_choice=""
prompt_text " Group:" "${service_id}" group_choice
if [ -z "$group_choice" ]; then
log_warning "No group entered — leaving $domain open to all Authelia users."
return 0
fi
if [[ "$group_choice" =~ ^[0-9]+$ ]] && [ "$group_choice" -ge 1 ] && [ "$group_choice" -le "${#existing_groups[@]}" ]; then
group="${existing_groups[$((group_choice - 1))]}"
is_new_group="false"
else
local clean_name
clean_name="$(echo "$group_choice" | tr -cs 'a-zA-Z0-9_-' '-' | sed 's/^-*//;s/-*$//')"
if [ -z "$clean_name" ]; then
log_warning "Invalid group name — leaving $domain open to all Authelia users."
return 0
fi
group="${clean_name}-only"
for i in "${existing_groups[@]}"; do
[ "$i" = "$group" ] && is_new_group="false"
done
fi
if grep -A1 -F " - domain: \"${domain}\"" "$config_file" 2>/dev/null | grep -qF " subject: \"group:${group}\""; then
log_info "$domain is already scoped to group '${group%-only}'."
log_info "Manage its members via this menu's \"Edit an existing user\" (toggle their groups by hand in users.yml), or the universal-access report below." log_info "Manage its members via this menu's \"Edit an existing user\" (toggle their groups by hand in users.yml), or the universal-access report below."
return 0 return 0
fi fi
echo "" local -a usernames
echo " Who should be able to reach $domain via Authelia?" if [ "$is_new_group" = "false" ]; then
echo " 1) Specific users only" log_info "Reusing existing group '${group%-only}' — its current members already have access."
echo " 0) Any Authelia user (default — same access as everything else)" local add_more=""
local scope_choice="" prompt_yn " Add more users to '${group%-only}' now? (y/n):" "n" add_more
prompt_text " Choice [1, or 0 for any user]:" "0" scope_choice if [[ ! "$add_more" =~ ^[Yy]$ ]]; then
[ "$scope_choice" = "1" ] || return 0 usernames=()
local -a existing_users
mapfile -t existing_users < <(_authelia_list_usernames "$users_file")
local i
if [ "${#existing_users[@]}" -gt 0 ]; then
echo " Existing Authelia users:"
for i in "${!existing_users[@]}"; do
echo " $((i + 1))) ${existing_users[$i]}"
done
echo " Pick by number (space-separated), and/or type new usernames directly"
echo " to create them — mix freely, e.g. \"1 3 newperson\"."
else
echo " No existing Authelia users yet — type usernames below to create them fresh."
fi
echo " Anyone typed (not picked by number) who doesn't already have an"
echo " Authelia account gets one created — you'll get their temporary"
echo " password to hand over."
local raw_users=""
prompt_text " Usernames/numbers:" "" raw_users
local -a raw_tokens usernames
read -ra raw_tokens <<< "$raw_users"
if [ "${#raw_tokens[@]}" -eq 0 ]; then
log_warning "No usernames entered — leaving $domain open to all Authelia users."
return 0
fi
local t
for t in "${raw_tokens[@]}"; do
if [[ "$t" =~ ^[0-9]+$ ]] && [ "$t" -ge 1 ] && [ "$t" -le "${#existing_users[@]}" ]; then
usernames+=("${existing_users[$((t - 1))]}")
else
usernames+=("$t")
fi fi
done fi
if [ "$is_new_group" = "true" ] || [[ "${add_more:-}" =~ ^[Yy]$ ]]; then
local -a existing_users
mapfile -t existing_users < <(_authelia_list_usernames "$users_file")
if [ "${#existing_users[@]}" -gt 0 ]; then
echo " Existing Authelia users:"
for i in "${!existing_users[@]}"; do
echo " $((i + 1))) ${existing_users[$i]}"
done
echo " Pick by number (space-separated), and/or type new usernames directly"
echo " to create them — mix freely, e.g. \"1 3 newperson\"."
else
echo " No existing Authelia users yet — type usernames below to create them fresh."
fi
echo " Anyone typed (not picked by number) who doesn't already have an"
echo " Authelia account gets one created — you'll get their temporary"
echo " password to hand over."
local raw_users=""
prompt_text " Usernames/numbers:" "" raw_users
local -a raw_tokens
read -ra raw_tokens <<< "$raw_users"
if [ "${#raw_tokens[@]}" -eq 0 ] && [ "$is_new_group" = "true" ]; then
log_warning "No usernames entered — leaving $domain open to all Authelia users."
return 0
fi
local t
for t in "${raw_tokens[@]}"; do
if [[ "$t" =~ ^[0-9]+$ ]] && [ "$t" -ge 1 ] && [ "$t" -le "${#existing_users[@]}" ]; then
usernames+=("${existing_users[$((t - 1))]}")
else
usernames+=("$t")
fi
done
fi
local u start_end start end local u start_end start end
for u in "${usernames[@]}"; do for u in "${usernames[@]}"; do
@@ -1609,7 +1779,7 @@ _authelia_scope_access() {
start_end="$(_authelia_user_line_range "$users_file" "$u")" start_end="$(_authelia_user_line_range "$users_file" "$u")"
start="${start_end% *}"; end="${start_end#* }" start="${start_end% *}"; end="${start_end#* }"
_authelia_toggle_group "$users_file" "$start" "$end" "$group" "true" _authelia_toggle_group "$users_file" "$start" "$end" "$group" "true"
log_success "Added '$u' to group '$group'" log_success "Added '$u' to group '${group%-only}'"
else else
local email_default="${u}@${SITE_DOMAIN:-example.com}" local email_default="${u}@${SITE_DOMAIN:-example.com}"
if _authelia_create_user_noninteractive "$u" "$u" "$email_default" "$group"; then if _authelia_create_user_noninteractive "$u" "$u" "$email_default" "$group"; then
@@ -1624,6 +1794,16 @@ _authelia_scope_access() {
# before access_control's existing "*.${AUTHELIA_DOMAIN}" catch-all. # before access_control's existing "*.${AUTHELIA_DOMAIN}" catch-all.
local authelia_domain local authelia_domain
authelia_domain="$(awk '/^ cookies:$/{f=1; next} f && /domain:/{print $3; exit}' "$config_file")" authelia_domain="$(awk '/^ cookies:$/{f=1; next} f && /domain:/{print $3; exit}' "$config_file")"
# ...but BELOW the admin-bypass rule for this apex — otherwise the
# deny-elsewhere rule below would outrank it, and an admin who ever ends
# up in this group (by mistake, or a future feature) would be locked out
# of every other domain on the instance. Ensures the bypass rule exists
# first (retrofits it if this instance predates the feature), then
# inserts right after it rather than at the literal top of "rules:".
_authelia_ensure_admin_bypass "$config_file" "$authelia_domain"
local anchor_line="$ADMIN_BYPASS_LINE"
local scope_rules=" - domain: \"${domain}\" local scope_rules=" - domain: \"${domain}\"
subject: \"group:${group}\" subject: \"group:${group}\"
policy: two_factor policy: two_factor
@@ -1631,9 +1811,10 @@ _authelia_scope_access() {
subject: \"group:${group}\" subject: \"group:${group}\"
policy: deny" policy: deny"
awk -v block="$scope_rules" ' awk -v block="$scope_rules" -v anchor="$anchor_line" '
/^ rules:$/ && !done { print; print block; done=1; next }
{ print } { print }
anchor != "" && NR == anchor + 0 { print block }
anchor == "" && /^ rules:$/ && !done { print block; done=1 }
' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file" ' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file"
chown 1000:1000 "$config_file" 2>/dev/null || true chown 1000:1000 "$config_file" 2>/dev/null || true
@@ -1641,7 +1822,128 @@ _authelia_scope_access() {
prompt_yn " Restart Authelia to apply this scoping? (y/n):" "y" restart_auth prompt_yn " Restart Authelia to apply this scoping? (y/n):" "y" restart_auth
if [[ "$restart_auth" =~ ^[Yy]$ ]]; then if [[ "$restart_auth" =~ ^[Yy]$ ]]; then
(cd "$authelia_dir" && docker compose restart authelia 2>/dev/null) \ (cd "$authelia_dir" && docker compose restart authelia 2>/dev/null) \
&& log_success "Authelia restarted — $domain is now restricted to group '$group'." \ && log_success "Authelia restarted — $domain is now restricted to group '${group%-only}'." \
|| log_warning "Restart failed — check: docker compose logs authelia"
fi
}
# Renames an existing outside-access group everywhere it appears — every
# "subject: group:<old>" line in configuration.yml's access_control.rules,
# and every member's "- <old>" entry under their own groups: list in
# users.yml. A plain find/replace on the "-only"-suffixed internal name;
# the display name typed at the prompt (what _authelia_scope_access shows
# without the suffix) is what the user actually renames.
_authelia_rename_group() {
local users_file="$DOCKER_DIR/authelia/config/users.yml"
local config_file="$DOCKER_DIR/authelia/config/configuration.yml"
[ -f "$config_file" ] || { log_warning "No configuration.yml found — install Authelia first."; return 1; }
local -a existing_groups
mapfile -t existing_groups < <(_authelia_list_scoped_groups "$users_file")
if [ "${#existing_groups[@]}" -eq 0 ]; then
log_info "No outside-access groups exist yet."
return 0
fi
echo ""
echo " Outside-access groups:"
local i
for i in "${!existing_groups[@]}"; do
echo " $((i + 1))) ${existing_groups[$i]%-only}"
done
echo " 0) Cancel"
local choice=""
prompt_text " Which group to rename? [0]:" "0" choice
if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#existing_groups[@]}" ]; then
log_info "Cancelled — nothing changed."
return 0
fi
local old_group="${existing_groups[$((choice - 1))]}"
local new_name=""
prompt_text " New name for '${old_group%-only}':" "" new_name
local clean_name
clean_name="$(echo "$new_name" | tr -cs 'a-zA-Z0-9_-' '-' | sed 's/^-*//;s/-*$//')"
if [ -z "$clean_name" ]; then
log_warning "No name entered — nothing changed."
return 0
fi
local new_group="${clean_name}-only"
if [ "$new_group" = "$old_group" ]; then
log_info "Same name — nothing changed."
return 0
fi
for i in "${existing_groups[@]}"; do
if [ "$i" = "$new_group" ]; then
log_warning "A group named '${clean_name}' already exists — pick a different name, or use that group directly instead of renaming into it."
return 1
fi
done
sed -i "s/subject: \"group:${old_group}\"/subject: \"group:${new_group}\"/g" "$config_file"
sed -i "s/^ - ${old_group}\$/ - ${new_group}/g" "$users_file"
chown 1000:1000 "$config_file" "$users_file" 2>/dev/null || true
log_success "Renamed '${old_group%-only}' to '${clean_name}' — updated every access rule and member using it."
local restart_auth=""
prompt_yn " Restart Authelia to apply? (y/n):" "y" restart_auth
if [[ "$restart_auth" =~ ^[Yy]$ ]]; then
(cd "$DOCKER_DIR/authelia" && docker compose restart authelia 2>/dev/null) \
&& log_success "Authelia restarted" \
|| log_warning "Restart failed — check: docker compose logs authelia"
fi
}
# Menu-driven, idempotent bulk version of _authelia_ensure_admin_bypass —
# backfills the admin-bypass rule for every apex domain currently on this
# instance in one pass. install_authelia and add_authelia_domain bake the
# rule in automatically for anything created from here on, and
# _authelia_scope_access retrofits it just-in-time for whichever domain it's
# scoping — this is for catching every OTHER domain an install already had
# before this feature existed (or just double-checking one that's fine).
# Safe to re-run any time; only touches domains actually missing the rule.
_authelia_ensure_admin_access_everywhere() {
local config_file="$DOCKER_DIR/authelia/config/configuration.yml"
[ -f "$config_file" ] || { log_warning "No configuration.yml found — install Authelia first."; return 1; }
local -a apex_domains
mapfile -t apex_domains < <(grep -oE '^ - domain: "\*\.[^"]+"' "$config_file" | sed -E 's/^ - domain: "\*\.(.+)"$/\1/' | awk '!seen[$0]++')
if [ "${#apex_domains[@]}" -eq 0 ]; then
log_info "No apex domains found on this instance."
return 0
fi
echo ""
echo " Checking the admin-bypass rule for every domain on this instance:"
local d any_added="false"
for d in "${apex_domains[@]}"; do
_authelia_ensure_admin_bypass "$config_file" "$d"
if [ "$ADMIN_BYPASS_ADDED" = "true" ]; then
echo " ${d} — added"
any_added="true"
else
echo " ${d} — already present"
fi
done
if [ "$any_added" = "false" ]; then
log_success "Every domain already had it — nothing to change."
return 0
fi
log_success "Members of the 'admins' group now always have access to every domain"
log_success "listed above, regardless of any per-service scoping already in place —"
log_success "or added later, since _authelia_scope_access checks for this automatically"
log_success "from now on."
log_warning "Make sure your admin account(s) are actually in the 'admins' group in"
log_warning "config/users.yml — the default admin created at install time already is."
local restart_auth=""
prompt_yn " Restart Authelia to apply? (y/n):" "y" restart_auth
if [[ "$restart_auth" =~ ^[Yy]$ ]]; then
(cd "$DOCKER_DIR/authelia" && docker compose restart authelia 2>/dev/null) \
&& log_success "Authelia restarted" \
|| log_warning "Restart failed — check: docker compose logs authelia" || log_warning "Restart failed — check: docker compose logs authelia"
fi fi
} }
@@ -1664,7 +1966,7 @@ _authelia_report_access_scope() {
fi fi
echo "" echo ""
echo " Universal access (every protected domain):" echo " Native (universal every protected domain, no outside-access group):"
local -a universal=() restricted=() local -a universal=() restricted=()
local u start_end start end groups_in_range local u start_end start end groups_in_range
for u in "${all_users[@]}"; do for u in "${all_users[@]}"; do
@@ -1681,7 +1983,7 @@ _authelia_report_access_scope() {
[ "${#universal[@]}" -eq 0 ] && echo " (none)" [ "${#universal[@]}" -eq 0 ] && echo " (none)"
echo "" echo ""
echo " Scoped to specific services only:" echo " Outside access (limited to a named group):"
if [ "${#restricted[@]}" -eq 0 ]; then if [ "${#restricted[@]}" -eq 0 ]; then
echo " (none)" echo " (none)"
else else