harden(security): freeze RoleCarryingUserIdentity.Roles to a defensive copy

Code-review follow-up to T17: copy the roles into a fresh array at construction so a
caller mutating the source list cannot retroactively alter a session's granted roles,
and so the T18 ack gate's per-invocation .Contains(...) runs over a known-small frozen
array.
This commit is contained in:
Joseph Doherty
2026-06-11 05:53:11 -04:00
parent 1f172e55f7
commit 4b38a9d8c8
@@ -23,7 +23,11 @@ public sealed class RoleCarryingUserIdentity : UserIdentity
public RoleCarryingUserIdentity(UserIdentityToken token, IReadOnlyList<string> roles)
: base(token)
{
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
ArgumentNullException.ThrowIfNull(roles);
// Freeze to a defensive copy so a caller mutating the source list can never retroactively
// alter this session's granted roles, and so the gate's per-ack `.Contains(...)` runs over a
// known-small frozen array.
Roles = [.. roles];
}
/// <summary>The roles the authenticator granted this session, used by downstream permission gates.</summary>