Skip to content

Feature: Organization domain gating for magic link authentication #159

@WayneKennedy

Description

@WayneKennedy

Summary

We've implemented organization-based domain gating for magic link authentication and would like to contribute it back. This builds on the discussion in #127 but takes a different approach - leveraging Keycloak's native Organizations feature rather than a static domain list.

Use Case

B2B/multi-tenant SaaS where:

  • Users authenticate via magic link
  • Only users from recognized organization domains should be allowed
  • New users should be automatically assigned to their organization based on email domain

Implementation

Rather than a static list of allowed domains (as proposed in #127), this uses Keycloak's OrganizationProvider to dynamically look up organizations by their configured domains. This means:

  1. Domain management happens in Keycloak admin (Organizations → Domains), not in authenticator config
  2. Adding/removing allowed domains doesn't require flow reconfiguration
  3. New users can be auto-assigned to the matching organization

New Configuration Options

Option Description Default
Require organization domain Only allow users whose email domain matches a Keycloak Organization false
Auto-assign to organization Automatically add new users as members of the matching organization true
Unknown domain error code OAuth error parameter sent when domain doesn't match unknown_domain

Behavior

  • When enabled, extracts domain from email and calls OrganizationProvider.getByDomainName()
  • If no match: redirects to client with OAuth error response (error=unknown_domain)
  • If match + new user + auto-assign enabled: adds user to organization via OrganizationProvider.addMember()

Production Status

We've been running this in production for ~2 weeks without issues.

Regarding #127

The maintainer suggested a separate ConditionalAuthenticator approach. I understand that reasoning for a static domain list, but the Organizations integration feels more naturally coupled to the authenticator since it also handles the auto-assignment of new users. Happy to discuss alternative approaches if preferred.

PR

I have a working implementation ready to submit as a PR if there's interest. Happy to adjust the approach based on feedback.

Fork with implementation: https://github.com/Originate-Group/keycloak-magic-link

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions