Skip to content

Release v0.2.1

Choose a tag to compare

@github-actions github-actions released this 06 Sep 20:40
2c87716

Fixed

  • AcceptInvitation and SetupOrganization now reject a caller who has not verifiably exchanged the exact invitation they are acting on. Previously, any signed-in caller supplying a known invitation id could complete onboarding for that invitation under their own identity, even without ever exchanging its invite token - the invitation id alone (visible in a URL, a token, or a shared link) was treated as sufficient. (#13)
  • SignedInIdentity's session lookup no longer falls back to the most recently accepted session when the current request's subject does not match the one recorded for an invitation. That fallback treated contradictory evidence (a different login than the one that exchanged the invitation) the same as missing evidence, which could resolve the wrong identity provider and compliance subject for the events an onboarding command appends.
  • SignedInIdentity's session lookup now also excludes expired sessions, closing a window where a session past its nominal expiry - but not yet swept by MongoDB's periodic TTL cleanup - could still be picked.

Summary

This is the second work package of the onboarding-security epic (#10), building on the expiring/retry-safe invitation exchange from #12. It adds the authorization gate itself: ISignedInIdentity.IsVerifiedOwnerOf(InvitationId) verifies that the caller either presents the invite token's own jti claim for the invitation, or has a live, unexpired AcceptedInvitation session recorded under their own subject for that exact invitation. Both invitation-bound commands (AcceptInvitation, SetupOrganization) gate on it through their CommandValidator, so a mismatched or missing owner is rejected before Handle() ever runs and no event is appended.

RegisterOrganization (self-service registration, with no invitation to own) is unchanged - it has no invitation target to verify ownership against. The issue's broader acceptance criteria around read-side exposure (status/pending-list/identity queries keyed only by invitation id) and a redesigned owner-bound registration operation are follow-on work, not addressed here.

Test plan

  • dotnet build -c Debug - 0 warnings, 0 errors (regenerates proxies; command shapes unchanged)
  • dotnet build -c Release -p:CratisProxiesOutputPath= - 0 warnings, 0 errors
  • dotnet test - 78/78 passing, including new specs covering: a verified owner succeeds, a caller with no session/expired session/wrong-invitation session is rejected, contradictory subject evidence is rejected, and the jti-claim fast path verifies directly