fix: accept pipe-separated trusted-groups header values

Authentik's proxy provider on this deployment joins multiple group
names with "|" instead of "," (e.g. "admins|developpeur"). The
comma-only split in _trusted_groups_header_value() treated that whole
string as a single unmatched group name, silently dropping the
session to the unbound "default" profile even for identities that
are legitimate members of a mapped group. Single-group identities were
never affected since there was no separator to parse.

Accept comma, pipe, and newline as equivalent separators so the parser
works regardless of which the outpost happens to send.
This commit is contained in:
SuperAgent BEAM3 committed 2026-08-26 08:35:10 +00:00
1 parent e168b67e42
commit bb5347e1cd
2 files changed
+38 -1

No files matched your search

+10 -1
View File
@@ -722,7 +722,16 @@ def _trusted_groups_header_value(handler) -> list[str]:
if not raw:
return []
values = []
for part in str(raw).replace('\n', ',').split(','):
# Authentik's outpost typically joins multiple group names with a comma,
# but this deployment's proxy provider/property mapping emits a
# pipe-separated list instead (e.g. "admins|developpeur"). A bare comma
# split silently treats a multi-group pipe-joined value as one unmatched
# group name, dropping the session to the unbound "default" profile even
# though the identity is a legitimate member of a mapped group. Accept
# comma, pipe, and newline as equivalent separators so either format
# works regardless of which the outpost happens to send.
normalized = str(raw).replace('\n', ',').replace('|', ',')
for part in normalized.split(','):
part = part.strip()
if part:
values.append(part)
+28
View File
@@ -212,6 +212,34 @@ def test_group_map_prefers_mapping_order_over_header_order(monkeypatch):
assert auth.ensure_trusted_auth_session(second)["bound_profile"] == "ops"
def test_group_map_accepts_pipe_separated_header_value(monkeypatch):
# Some Authentik proxy provider / property mapping configs join multiple
# group names with "|" instead of ",". Regression case for the identity
# falling back to the unbound "default" profile despite being a member
# of a mapped group: a lone-membership identity works fine (no
# separator to parse), but a second group membership starts producing a
# pipe-joined header value that a comma-only split can't see through.
#
# NOTE: this only covers the concrete-mapped-group case. The
# wildcard-mapped-group case (a "*" mapping value dominating a concrete
# one) is intentionally not exercised here — that precedence rule isn't
# implemented on this branch yet; it ships separately in #6798. See the
# PR description for the full scope note.
_trusted_env(
monkeypatch,
groups_header="Remote-Groups",
group_map={"hermes_devops": "devops"},
)
handler = _Handler(
headers={"Remote-User": "alice", "Remote-Groups": "hermes_devops|other_group"}
)
info = auth.ensure_trusted_auth_session(handler)
assert info["bound_profile"] == "devops"
assert auth.trusted_session_allows_active_profile(info) is True
@pytest.mark.parametrize(
"group_map",
[