Best-effort serve for bad stored config + admin self-lockout guards

Serving never refuses to start because of stored realm config: the
registry build sanitizes best-effort and warns — misfiled origin entries
are reclassified (a cross-domain origins entry is served as a related
origin) or dropped, collisions resolve first-come-wins, over-cap related
lists truncate, unsalvageable realms are skipped. Fixing the stored
config stays the admin interface's job, and it stays reachable on any
working realm. Only a config with no servable realm at all is fatal.

Admin realm writes stay strict and gain self-lockout guards: an update
that would leave the admin's current host unable to run ceremonies for
the realm they are on is refused (unless an auth host takes over
ceremonies), and deleting the realm currently in use is refused.
This commit is contained in:
2026-09-06 22:52:00 +00:00
parent b9e6f4bc27
commit f5bd0a469c
6 changed files with 438 additions and 24 deletions
+119
View File
@@ -251,6 +251,125 @@ class TestValidateConfig:
)
# -------------------------------------------------------------------------
# Best-effort serving: stored config sanitization
# -------------------------------------------------------------------------
class TestSanitizeConfig:
"""Serving never fails on stored config problems; it degrades + warns."""
def test_cross_domain_origin_moved_to_related(self):
config, warnings = realms.sanitize_config(
Config(
realms=[RealmConfig(rp_id="localhost", origins=["https://example.com"])]
)
)
realm = config.realms[0]
assert realm.origins is None
assert realm.related_origins == ["https://example.com"]
assert any("related origin" in w for w in warnings)
realms.validate_config(config) # sanitized config is strict-clean
def test_malformed_origin_dropped(self):
config, warnings = realms.sanitize_config(
Config(realms=[RealmConfig(rp_id="a.com", origins=["not a url"])])
)
assert config.realms[0].origins is None
assert warnings
def test_invalid_rp_id_realm_dropped(self):
config, warnings = realms.sanitize_config(
Config(
realms=[RealmConfig(rp_id="not a domain!"), RealmConfig(rp_id="ok.com")]
)
)
assert [r.rp_id for r in config.realms] == ["ok.com"]
assert any("dropped" in w for w in warnings)
def test_duplicate_rp_id_first_wins(self):
config, _warnings = realms.sanitize_config(
Config(
realms=[
RealmConfig(rp_id="a.com", rp_name="First"),
RealmConfig(rp_id="a.com"),
]
)
)
assert len(config.realms) == 1
assert config.realms[0].rp_name == "First"
def test_related_inside_own_domain_dropped(self):
config, _ = realms.sanitize_config(
Config(
realms=[
RealmConfig(rp_id="a.com", related_origins=["https://app.a.com"])
]
)
)
assert config.realms[0].related_origins is None
def test_cap_exceeded_truncated(self):
config, warnings = realms.sanitize_config(
Config(
realms=[
RealmConfig(
rp_id="a.com",
related_origins=[f"https://app{i}.com" for i in range(6)],
)
]
)
)
assert len(config.realms[0].related_origins) == 5
assert any("maximum" in w for w in warnings)
def test_auth_host_outside_domain_ignored(self):
config, warnings = realms.sanitize_config(
Config(realms=[RealmConfig(rp_id="a.com", auth_host="https://auth.b.com")])
)
assert config.realms[0].auth_host is None
assert any("auth host ignored" in w for w in warnings)
def test_auth_host_colliding_with_rp_id_ignored(self):
config, warnings = realms.sanitize_config(
Config(
realms=[
RealmConfig(rp_id="a.com", auth_host="https://auth.a.com"),
RealmConfig(rp_id="auth.a.com"),
]
)
)
assert config.realms[0].auth_host is None
assert any("collides with an rp-id" in w for w in warnings)
def test_related_colliding_with_other_realm_dropped(self):
config, _ = realms.sanitize_config(
Config(
realms=[
RealmConfig(rp_id="a.com", related_origins=["https://app.b.com"]),
RealmConfig(rp_id="b.com"),
]
)
)
assert config.realms[0].related_origins is None
def test_no_realms_is_fatal(self):
with pytest.raises(ValueError, match="realm"):
realms.sanitize_config(Config(realms=[]))
with pytest.raises(ValueError, match="No servable realm"):
realms.sanitize_config(Config(realms=[RealmConfig(rp_id="not a domain!")]))
def test_build_tolerates_and_serves(self):
# Cross-domain entry stored in origins: served as a related origin
reg = build_registry(
RealmConfig(rp_id="localhost", origins=["https://example.com"])
)
assert reg.warnings
realm = reg.get("localhost")
assert realm.related_origins == ["https://example.com"]
realm.passkey.validate_origin("https://example.com")
# -------------------------------------------------------------------------
# Origin validation semantics (Passkey)
# -------------------------------------------------------------------------