DD-009: Verified-domain self-service join — parked until a consumer admits members by email domain¶
id: DD-009
status: PARKED
issues: [1424]
adrs: [0057, 0003, 0036, 0037]
decided: 2026-10-12
decided_at_sha: 2de583aa741ecc4dfad1f369f6c773fa12f99966
parent: flense-programme
One-line intent¶
No consumer turns on verified-domain join; its example (domain_join_co) was
retired in flense ship E. Flense ship F (ADR-0057) removes the join policy,
the join-request queue and the membership admission gate. Enterprise SSO's
DNS-TXT domain verification (auth/domain_verification.py,
verified_domains on connections, home-realm routing) stayed until flense
ship AD parked it with enterprise SSO in DD-013 (2026-10-15).
Plan (what we already concluded)¶
Restore from the commit this DD was parked at
(2de583aa741ecc4dfad1f369f6c773fa12f99966):
auth/domain_join.py— pure decision logic:assert_domain_admissible(uniform fail-closed gate on every membership-creating path: invitation accept, SSO JIT, SCIM) anddecide_domain_join(policy, email_verified, has_membership)→ Off / AutoJoin / NeedsApproval / Noop.auth/org_settings.py— typed view oforganizations.settings:domain_join_policy(off|auto_join|admin_approval) andrestrict_membership_to_verified_domains; leftover form tokens never invent a policy.auth/join_requests.py+join_request_routes.py, thejoin_requeststable (dropped by revision 0022 after operator sign-off on 2026-10-13; re-add with a new Alembic revision), the/auth/join-requestsadmin queue (approve / deny,FOR UPDATEserialisation, CSRF-gated) and the/auth/join-requestedpage.- Hooks: password login and email verification call
apply_domain_joinfor a verified email with no membership; a join hiccup never breaks auth. - Counter-priors: never admit on an unverified email or an unverified domain; never let the domain match override an explicit invitation.
Reopen when (consumer force)¶
- Named consumer — AegisMark wants staff with a school's email domain to join that school's tenant without an invitation.
- Evidence of host workaround — bulk invitation scripts per school, or
an
app/route that creates memberships from email domains. - Acceptance that unblocks — in AegisMark's CI a verified
@school.exampleuser lands in the school tenant (auto-join) or in the admin queue (approval), and an off-domain user is refused when the tenant restricts membership.
When a force lands:
- Set
status: FORCEDand date it. - Comment on every linked issue with the consumer + this DD path.
- Implement against the plan above; open child issues if the plan splits.
- When shipped, set
status: DONEand close issues.
Already shipped (do not re-litigate)¶
- Enterprise SSO connections, DNS-TXT domain verification and verified-domain home-realm discovery for OIDC/SAML were parked in DD-013 (flense ship AD). Verified domains are a prerequisite of this plan, so a force here restores DD-013's connection and domain-verification slice first.
- The
organizations.settingsJSON column (still present, now unread).
Explicitly out of scope until force¶
- Multi-domain policies per tenant, domain allow/deny lists beyond the verified set, cross-tenant join suggestions.
Trail¶
| Date | Event |
|---|---|
| 2026-10-12 | Parked (this DD); verified-domain join removed in flense ship F |
| 2026-10-15 | Domain verification parked with enterprise SSO (DD-013, flense ship AD) |