The identity becomes the Matrix localpart at SSO, so a new account must not mint a name that
a Matrix account already holds (the 13 Synapse localparts) or a system name. Native register
refuses a reserved name; a derived identity takes the next free suffix. Lookups of existing
accounts and existing rows are untouched; there is no exemption path.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fails at this commit with DbUpdateConcurrencyException from CloseMotionAsync:
Motion.Status became a concurrency token in BifrostDbContext.cs:288.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A __Host- cookie is only removed by a Set-Cookie that is itself Secure. The
hardening test now checks Secure on every header, deletion included, and the
completion tests pin that success and refusal both clear the attempt cookie
with Secure, Path=/ and no Domain.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A signed-in retract on a full account table must say busy with no sign-in offer (the
retract door passes its voter to Throttled), and a spent cast budget must say only
"too fast", for anonymous and signed-in voters alike. Both mutants survived Soul s4.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Session, OAuth correlation, antiforgery, voter and Heimdall attempt cookies all take the
__Host- prefix. The prefix forbids a narrower Path, so the voter (was /mill) and attempt
(was /auth/heimdall) cookies move to Path=/.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A pass that cannot read its subjects (a scope factory failing like a database outage) is logged
by exception type only and retried after the interval, never in a tight loop. The earlier loop
test reached this catch through a per-subject exception, which the isolation now absorbs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The named logout HttpClient's primary handler disables auto-redirect, so a 3xx from MAS is a
non-delivery retried like any non-2xx instead of being followed to a final 2xx that revokes.
Pinned through the real DI registration against a real loopback listener answering 302, and
the registered client's Timeout is pinned to exactly 10 s. The unexpected-exception test is
replaced by the isolation test (its fix is the next commit) and the cancellation test stands alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OidcLogoutReconciler derives pending logouts from valid OpenIddict authorizations x
membership, POSTs one signed logout token per non-Active subject to MAS, and revokes
the authorizations only after a 2xx. Registered only when
Bifrost:Oidc:Clients:Mas:BackchannelLogoutUri is set. The active-member reading is
the endpoints' existing one, now shared.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One configured client (stale clients removed with their tokens and authorizations), Active membership re-checked at token and userinfo through IsStillActiveMemberAsync, PKCE required by the server option, OpenIddict.Server.AspNetCore + EntityFrameworkCore 7.7.1 with no vulnerable transitives. Soul s2, s3 and s4 hold; Low conformance gaps in gamecult-chat:follow_up:oidc-issuer-spec-conformance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Start takes a free slot or overwrites the one expiring first; parallel starts carry the same request
cookies, choose the same slot and overwrite each other. Complete finds its attempt by scanning the
slots for the posted nonce; an overwritten attempt finds none and is refused like any other. The
per-request counting sweep, its byte budget and the nonce-named cookie are deleted.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>