Relabel "native" access as "internal" throughout Authelia's menus

Pure wording change, no behavior difference — internal already meant
exactly this (any registered Authelia user, no group) before the rename.
Also brings CLAUDE.md's description of the outside-access/admin-bypass
feature up to date; it still described the pre-generalization one-group-
per-service shape from earlier in this branch.
This commit is contained in:
Claude
2026-08-25 15:42:23 +00:00
parent e9286c8360
commit 1e625b9955
2 changed files with 47 additions and 20 deletions
+42 -15
View File
@@ -422,22 +422,49 @@ existing login page. Reuse `_authelia_provision_oidc_client()` (guarded by
instead of duplicating Authelia's client-secret-generation/config-patching
logic again.
**Scoping a domain to specific users instead of every Authelia user.**
By default, any domain with an `access_control` rule at all is reachable by
every Authelia user (the existing catch-all `*.${AUTHELIA_DOMAIN}` rule).
`services/authelia.sh`'s `_authelia_scope_access(SERVICE_ID, DOMAIN)` is a
generic, reusable opt-in on top of that — call it right after *any* service
finishes being protected by Authelia, forward_auth gate or native OIDC
alike (it only cares about the domain, not the gating mechanism; see
`_gitea_offer_authelia_sso()` for the reference caller). Asks whether
access should stay universal or be scoped to specific usernames; if scoped,
creates a dedicated `<service_id>-only` group, adds every listed username
to it (creating accounts on the fly via
**Internal vs. outside access — named, reusable groups, not one group per
service.** By default, any domain with an `access_control` rule at all is
"internal": reachable by every Authelia user (the existing catch-all
`*.${AUTHELIA_DOMAIN}` rule) — admins included automatically, since the
admin-bypass rule (below) always outranks it anyway. `services/authelia.sh`'s
`_authelia_scope_access(SERVICE_ID, DOMAIN)` is the generic, reusable opt-in
on top of that for "outside access" — call it right after *any* service
finishes being protected by Authelia, forward_auth gate or native OIDC alike
(it only cares about the domain, not the gating mechanism; see
`_gitea_offer_authelia_sso()` for the reference caller). Asks "Internal
(default) or Outside access", and if outside access, lets the admin pick an
*existing* named group (by number, so e.g. "customer1" can be attached to a
second, third, unrelated site later) or type a new one — `service_id` is
only the suggested default name, never forced. Creates the group if new
(adding every listed username to it, creating accounts on the fly via
`_authelia_create_user_noninteractive()` for names that don't exist yet,
printing their temp password), and inserts two rules *above* the general
catch-all — allow that group on this domain, deny that group on every
other protected domain. Idempotent: reruns against an already-scoped
domain just report the existing group instead of duplicating rules.
printing their temp password) and inserts two rules *above* the general
catch-all but *below* the admin-bypass rule — allow that group on this
domain, deny that group on every other protected domain. The already-scoped
check is keyed to the (domain, group) pair, not the group name alone, so
reusing a group on a second site correctly adds that site's own rule instead
of a false "already scoped" no-op (a real bug in an earlier version of this
function, since fixed).
Three more menu options round this out: **13** backfills the admin-bypass
rule (below) onto any apex domain missing it; **14** renames a group
everywhere it's referenced (rules + every member); **15** lists every
group's sites and members in one place; **16** is the reverse of the
scoping prompt's own member-picker — pick a group first, then toggle which
users are in it, for adding members without re-touching a site.
**Admins always match first, on every domain — old sites and new.**
`_authelia_ensure_admin_bypass(config_file, domain)` inserts
`- domain: "*.${domain}" / subject: "group:admins" / policy: two_factor` as
literally the first rule under `rules:`, and every insertion point that
adds new rules (`add_authelia_domain`, `_authelia_scope_access`) inserts
*after* this block rather than at the literal top of `rules:`, so a later
scoping action can never accidentally outrank it. Without this, a group's
deny-elsewhere rule (above) would deny an admin who's ever added to that
group on every OTHER domain — this rule exists specifically so that can't
happen. `install_authelia()`/`add_authelia_domain()` bake it in for
anything created from here on; menu option 13 backfills it onto an
instance that predates the feature.
Guard every cross-file call with `declare -F`, same convention as the OIDC
helper above — a service can run standalone with authelia.sh never sourced.
+5 -5
View File
@@ -1689,11 +1689,11 @@ _authelia_scope_access() {
echo ""
echo " Who should be able to reach $domain via Authelia?"
echo " 0) Native — your own users, no extra restriction (default — same"
echo " 0) Internal — 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
prompt_text " Choice [0 for internal, 1 for outside access]:" "0" scope_choice
[ "$scope_choice" = "1" ] || return 0
local -a existing_groups
@@ -1936,7 +1936,7 @@ _authelia_report_groups() {
local -a groups
mapfile -t groups < <(_authelia_list_scoped_groups "$users_file")
if [ "${#groups[@]}" -eq 0 ]; then
log_info "No outside-access groups exist yet — every site is native (open to any Authelia user, admins always included)."
log_info "No outside-access groups exist yet — every site is internal (open to any Authelia user, admins always included)."
return 0
fi
@@ -1995,7 +1995,7 @@ _authelia_manage_group_membership() {
if [ "${#groups[@]}" -eq 0 ]; then
log_info "No outside-access groups exist yet. A group is created the first time you"
log_info "protect a site (option 10, or a service's own \"Add Sign in with Authelia\""
log_info "offer) and choose \"Outside access\" instead of \"Native\" — name it there"
log_info "offer) and choose \"Outside access\" instead of \"Internal\" — name it there"
log_info "(e.g. \"customer1\"), and it'll show up here afterward to manage its members."
return 0
fi
@@ -2147,7 +2147,7 @@ _authelia_report_access_scope() {
fi
echo ""
echo " Native (universal — every protected domain, no outside-access group):"
echo " Internal (universal — every protected domain, no outside-access group):"
local -a universal=() restricted=()
local u start_end start end groups_in_range
for u in "${all_users[@]}"; do