Files
user-engine/docs/family-dataspace-onboarding.md

121 lines
5.1 KiB
Markdown

# Family Dataspace Onboarding
Status: implemented MVP facade
Date: 2026-06-05
Related workplan: USER-WP-0008
## Purpose
Family dataspace onboarding is the first concrete convenience use case for
`user-engine` as a NetKingdom identity-domain integration layer. It lets a
consumer represent a family as a tenant-scoped identity context, invite family
members, bind a personal dataspace application, and produce SSO-ready identity
context without making callers sequence low-level user, profile, membership,
application, audit, and projection operations themselves.
## Model
| Use-case concept | user-engine representation | Source of truth |
| --- | --- | --- |
| Family | NetKingdom tenant plus `family` membership scope | NetKingdom tenant/organization infrastructure |
| Family owner | `User`, `Account`, active `TenantAccount`, `family:owner` membership | user-engine for local facts |
| Family member | invited `User`, `Account`, `TenantAccount`, `FamilyInvitation` | user-engine for local lifecycle |
| SSO identity | linked `ExternalIdentity` from verified `(issuer, subject)` | NetKingdom IAM for authentication |
| Family role | scoped `Membership.kind` such as `owner`, `adult`, `child`, `guest` | user-engine fact, authorization consumes it |
| Personal dataspace | registered `Application` with `ApplicationBinding` | user-engine binding, external runtime owns app |
| SSO claims input | `identity_context` plus `CLAIMS_ENRICHMENT` projection | user-engine read model, NetKingdom IAM consumes it |
## Public Flow
1. Resolve the owner through `me(...)` or pass an already-normalized actor.
2. Call `onboard_family_dataspace(...)` with a `FamilyDataspaceRequest`.
3. user-engine ensures the owner exists, registers the dataspace application,
publishes a minimal dataspace catalog, assigns owner membership, creates
pending member invitations, and returns identity context plus a
claims-enrichment projection for SSO.
4. Invited members accept through `accept_family_invitation(...)` using
verified NetKingdom claims. user-engine links the external identity,
activates account state, records audit/outbox events, and returns SSO-ready
context for the member.
5. Pending invitations can be resent or revoked through
`resend_family_invitation(...)` and `revoke_family_invitation(...)`.
## Example
```python
from user_engine.domain import FamilyDataspaceRequest, FamilyMemberSpec, FamilyRole
owner = service.me(owner_claims, correlation_id="corr-owner")
onboarding = service.onboard_family_dataspace(
owner.actor,
FamilyDataspaceRequest(
tenant="tenant:worsch-family",
family_scope_id="family:worsch",
family_display_name="Worsch Family",
application_id="app.personal-dataspace",
oidc_client_id="personal-dataspace-client",
protected_system_id="dataspace.personal.worsch",
member_specs=(
FamilyMemberSpec(
primary_email="child@example.test",
display_name="Child Member",
role=FamilyRole.CHILD,
),
),
),
correlation_id="corr-family-onboard",
)
member = service.accept_family_invitation(
member_claims,
onboarding.invitations[0].invitation.invitation_id,
correlation_id="corr-member-accept",
)
```
`onboarding.identity_context` and `member.identity_context` contain the
canon-facing actor, user, account, authenticated subject, authorization
principal, tenant, family group, membership, grant-like, and evidence
references. `claims_projection` contains application-visible profile values
such as the family display name and member display name.
## Boundary
user-engine does not issue tokens, manage credentials, run MFA, provision the
family tenant, or implement the personal dataspace runtime. Those remain
NetKingdom IAM, tenant, security, and application responsibilities.
Family roles are exported as scoped membership facts. The authorization port
decides whether those facts allow an action.
Invitation tokens and proofing are deliberately adapter-owned. The MVP
invitation record tracks local lifecycle state and assumes NetKingdom IAM has
already verified claims before acceptance.
## Audit And Events
The facade emits high-level events in addition to the lower-level events from
the operations it composes:
- `family_dataspace.onboarded`
- `family_member.invited`
- `family_invitation.resent`
- `family_invitation.revoked`
- `family_invitation.accepted`
Lower-level events such as `user.created`, `tenant_account.status_changed`,
`membership.added`, `identity.linked`, `application.registered`,
`catalog.published`, and `profile.value_set` remain visible for replay and
traceability.
## Current MVP Limits
- Invitations are stored in the current store boundary and need durable-store
backing before production use.
- Invitation delivery, one-time token material, and proofing are external
adapter responsibilities.
- Membership revocation and historical role lifecycle are not yet fully
modeled beyond invitation revoke and account status changes.
- The default dataspace catalog is intentionally minimal and should evolve with
real dataspace claims requirements.