Skip to content

Ownership

Every Space has an owner. The owner is the entity allowed to:

  • Create Host Links bonded to that Space.
  • Approve Device pairings into the Space.
  • Claim public namespaces for the Space.
  • Suspend or release the Space.

This page enumerates the owner types defined in the schema and what each one means today.

Owner-type schema

Source: projects/matrix-3/packages/system-auth/src/host-auth.ts:55.

ts
export type HostSpaceOwnerType = 'principal' | 'organization' | 'system' | 'service';
Owner typeMeaningImplemented?
principalOne signed-in user owns the Space.Yes — the only fully implemented case.
organizationAn organization owns the Space; members access it through membership roles.Schema only. See Organizations.
systemThe Space is platform-owned (housekeeping, public directory, etc.).Schema only.
serviceThe Space is owned by a service identity (a non-human principal).Schema only.

How principal ownership works

When a user signs in for the first time:

  1. A principal record is created (p_xxx).
  2. A Space is created (spc_xxx) with ownerType: 'principal', ownerPrincipalId: p_xxx.
  3. A public-namespace claim is created (e.g., space.alt.stories.ghost-stories.funny with routeKey: alt.stories.ghost-stories.funny).
  4. The Space becomes the principal's default Space.

From then on, every authorization check involving the Space verifies space.ownerPrincipalId === request.principalId. Examples:

  • auth.hostLink.create (system-auth/src/index.ts:719-757) explicitly checks space.ownerPrincipalId !== principalId and rejects with Host link requires a Space owned by the principal.
  • auth.space.default (index.ts:695-700) checks space.ownerPrincipalId !== principalId and rejects setting a default to a Space the principal does not own.

This single check is the platform's authorization model today. Anything more nuanced (delegation, scoped grants) is target state.

Owner-type system

Reserved for platform-internal Spaces. Examples a future implementation might use:

  • A platform-wide directory Space serving the federated catalog.
  • An admin Space holding global housekeeping records.
  • A "public" Space for anonymous users.

Today none of these exist. The platform Host runs as a principal-owned setup with a configured admin principal.

Owner-type service

Reserved for non-human service identities — bots, integrations, automation accounts. The pattern is:

  • Create a principal with no email/displayName.
  • Create a Space owned by that principal but stamped ownerType: 'service'.
  • Issue a long-lived NATS user JWT for the service.

The current code allows you to do this manually but does not surface a "service account" creation flow. Target state.

Transferring ownership

ownerPrincipalId is mutable in the schema. There is no op that performs a safe transfer. A correct transfer needs to:

  1. Verify the new owner principal is active.
  2. Revoke or migrate every Host Link bonded to the Space (each carries the old owner's NATS user JWT).
  3. Update space.ownerPrincipalId.
  4. Update default-Space mappings if relevant.
  5. Audit-log the transfer.

The data model accommodates this. The op is target state.

Suspended Spaces

A suspended Space (status: 'suspended') keeps its owner — suspension is independent of ownership. Re-activating a suspended Space restores the prior owner's access. Suspension is target state today (no op exposes the transition).

What ownership does NOT control

A few things are deliberately scoped outside Space ownership:

  • Inference credentials. Per Rule 4, inference credentials are local-only and Factotum-owned. The Space owner cannot grant another principal access to inference credentials by transferring the Space.
  • Local Device state. A Device's local Host Service supervises whatever runtimes its <host-home>/runtimes/*.json declares. Re-bonding the Device to a different Space does not migrate local runtime records.
  • Federation discovery. A signed-in user can see published mounts from any principal via system.registry. Ownership does not gate read access to public mounts; only mount-claim creation.

Authorization model summary

Until system-security lands a richer authorization framework, every Space-scoped op asks one question: "is the calling principal the owner?" That is good enough for a single-tenant-per-Space launch but does not support:

  • Read-only collaborators.
  • Admin-vs-member role distinction within a Space.
  • Time-limited grants.
  • Capability tokens (see Security: Capability tokens for the bus-token primitive that exists today).

These are explicitly target state.

See also

Source: projects/matrix-3/packages/system-auth/src/host-auth.ts:55 for the enum, index.ts:655-757 for the ops that enforce ownership today.