Cookbook — Identity ↔ Directory
Illustrative bounded contexts only. Rename to your domains; do not import product module trees.
| Module | Owns |
|---|---|
| Identity | Credentials, sessions/tokens, authentication challenges, “who is signed in” |
| Directory | Member/organisation profile, roles as Directory sees them, eligibility tiers |
Design test: If Identity is replaced by an external IdP, Directory Application/Domain still compile (Directory talks to a local port / events — not Identity Entities).
Bridges used
| Need | Bridge |
|---|---|
| Directory must know “subject X is authenticated” for an admin action | Sync ACL to Identity or host middleware that already resolved a subject code into the Use Case DTO |
| After signup, Directory creates a member shell | Domain Event IdentityUserRegistered → Directory translation listener → inbound Use Case |
| Ordering checks member tier | Sync ACL Ordering → Directory (Identity not involved) |
Folder sketch
Identity/
Domain/
Events/UserRegistered.php # rich: userId, email hash/code, occurredAt, schemaVersion, eventId
Ports/Module/IdentityAuthModuleInterface.php # thin: validate token / resolve subject
Application/UseCases/Auth/…
Infrastructure/…
Directory/
Domain/Ports/Acl/AuthenticatedSubjectPortInterface.php # optional if Directory must verify
Domain/Ports/Module/DirectoryMemberModuleInterface.php # thin: getTier(memberCode), …
Application/UseCases/Member/ProvisionMemberFromRegistrationUseCase.php
Infrastructure/
ExternalServices/… # ACL adapters
Messaging/IdentityUserRegisteredTranslationListener.php
Sequence — register then provision
Sequence — resolve subject for a Directory admin action
Prefer resolving the subject in UI/Infrastructure (host auth middleware) and passing a subject code into the Directory Application DTO. If Directory Application must verify:
Directory Use Case → AuthenticatedSubjectPortInterface → ACL → IdentityAuthModuleInterface::resolve(token) → local result DTO.
Never inject IdentityAuthModuleInterface into Directory Use Cases.
Ownership pitfalls
| Pitfall | Fix |
|---|---|
| Directory stores passwords | Credentials stay in Identity |
| Identity stores member pricing tier | Tier is Directory (or another BC); Identity may only hold auth attributes |
Shared User entity for both | Split models; share only opaque userId / memberCode via contracts |
| Filament/admin in Directory importing Identity Eloquent | ACL or host auth bridge |
Related Core
- Contracts — thin Identity/Directory façades
- Event delivery — idempotent provisioning
- Reads — profile screens vs auth
Also see Ordering ↔ Warehouse.