Skip to content

Claim schema

A namespace claim is a typed Space-path mapped to a spaceId and authorityRoot. This page is the field-by-field reference for the record and the validation rules.

IHostPublicNamespaceClaim

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

ts
interface IHostPublicNamespaceClaim {
  readonly routeKey?: string;            // v1 alias for spacePath
  readonly publicNamespace: string;      // typed name, e.g. 'space.alt.stories'
  readonly canonicalRouteKey?: string;
  readonly canonicalNamespace?: string;
  readonly spaceId: string;              // 'space_<hex>' or 'spc_<hex>'
  readonly authorityRoot: string;        // bus authority root
  readonly canonical: boolean;           // true if this is the canonical claim for the Space
  readonly claimType: 'space' | 'domain' | 'system';
  readonly parentNamespace?: string;
  readonly verificationLevel: 'self' | 'org-admin' | 'dns' | 'platform';
  readonly status: 'active' | 'reserved' | 'suspended' | 'released';
  readonly createdAt: string;            // ISO timestamp
  updatedAt: string;
}

Field meanings

FieldPurpose
routeKeyv1 alias for spacePath. New UI says "Space path"; existing storage keeps routeKey.
publicNamespaceTyped claim. Always starts with space., domain., or system..
canonicalRouteKeyIf multiple routeKeys map to the same Space, this is the canonical one.
canonicalNamespaceSame idea for typed names.
spaceIdThe Space this claim points to.
authorityRootThe bus authority root associated. New: derived from spaceId.
canonicalFirst claim per Space is canonical; later claims for the same Space are aliases.
claimTypespace for user-claimed, domain for DNS-verified, system for reserved.
parentNamespaceIf nested (e.g. space.alt.stories.ghost-stories has parent space.alt.stories).
verificationLevelself (just authentication), org-admin (delegated), dns (TXT verified), platform (system-managed).
statusActive, reserved (target state), suspended, or released (target state).
createdAt/updatedAtStandard timestamps.

Validation patterns

Source: host-auth.ts:1801-1854.

PUBLIC_NAMESPACE_PATTERN

regex
^(space|domain|system)\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?
   (?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$
  • Type prefix is one of space, domain, system.
  • Each label is 1-63 chars, lowercase letters/digits/hyphens, must not start or end with hyphen.

ROUTE_KEY_PATTERN

regex
^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?
   (?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$

Same shape but no type prefix. A routeKey that already matches PUBLIC_NAMESPACE_PATTERN is rejected (avoids ambiguity).

RESERVED_ROUTE_KEYS

A set of HTTP-path-reserved words rejected by normalizeRouteKey:

api, auth, login, logout, signup, setup, settings, apps, app, assets,
static, branding, nats-ws, matrix, system, admin, root, support, docs,
help, billing, status, healthz, well-known, favicon.ico,
manifest.json, hivecast, open-matrix, me

These are reserved because the HTTP gateway has paths under each.

DNS_LIKE_ROUTE_KEY_TLDS

If a multi-label routeKey ends in one of these (com, org, io, ai, app, dev, net, …), it's rejected as DNS-like:

ai, app, au, ca, co, com, de, dev, edu, fr, gov, io, jp, mil, net,
org, uk, us, xyz

The intent is to push DNS-like names through the domain.* typed path, which requires DNS verification.

Claim lifecycle

(no record)        ──► [ auth.namespace.claim ]
                          ├─► refused: invalid namespace
                          ├─► refused: domain.* requires DNS
                          ├─► refused: system.* reserved
                          ├─► refused: parent not delegated
                          ├─► refused: namespace already claimed
                          ├─► refused: routeKey already claimed
                          └─► success: status: 'active'

active             ──► [ Space suspended ]      ──► status: 'suspended'
active             ──► [ release op (target state) ] ──► status: 'released'
suspended          ──► [ Space resumed ]         ──► status: 'active'
released           ──► [ available for new claim ]

Cross-claim Space ownership

A Space (IHostSpaceRecord) can have multiple namespace claims. This happens when:

  • A principal claims space.alt.stories (creates a Space).
  • Later claims space.aliases.alt-stories (sub-claim under same Space's spaceId).
  • The first claim has canonical: true; later ones don't.

canonicalRouteKey and canonicalNamespace point at the canonical public name, useful when rendering "Space path" in UI.

Sample record

json
{
  "routeKey": "alt.stories.ghost-stories.funny",
  "publicNamespace": "space.alt.stories.ghost-stories.funny",
  "canonicalRouteKey": "alt.stories.ghost-stories.funny",
  "canonicalNamespace": "space.alt.stories.ghost-stories.funny",
  "spaceId": "spc_7f3a9b2c4d5e6f7a8b9c",
  "authorityRoot": "space.spc-7f3a9b2c4d5e6f7a8b9c",
  "canonical": true,
  "claimType": "space",
  "parentNamespace": "space.alt.stories.ghost-stories",
  "verificationLevel": "self",
  "status": "active",
  "createdAt": "2026-05-04T12:00:00.000Z",
  "updatedAt": "2026-05-04T12:00:00.000Z"
}

See also

Source: projects/matrix-3/packages/system-auth/src/host-auth.ts (IHostPublicNamespaceClaim at lines 71-85, PUBLIC_NAMESPACE_PATTERN, ROUTE_KEY_PATTERN, RESERVED_ROUTE_KEYS, DNS_LIKE_ROUTE_KEY_TLDS at lines 1801-1854).