generated from coulomb/repo-seed
121 lines
5.1 KiB
Markdown
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.
|