Hosting domains

What a hosting domain is, how one WebVH Hosting deployment serves DIDs on several domains, how the default domain and per-owner domain scopes are chosen, and what disabling or purging a domain does.

A did:webvh identifier embeds the host it resolves from. An organisation that serves DIDs for several brands or tenants needs each one on its own domain, without running a separate deployment for each.

A WebVH Hosting deployment can serve DIDs on many hosting domains at once, scope each owner to the domains it may publish on, and retire a domain together with every DID on it. Create your first hosted DID →

What a hosting domain is

A hosting domain is a host name, such as did.example.com, that the deployment serves DIDs from. A DID’s domain is the host in its identifier, so a DID created on did.example.com always resolves from did.example.com. Each domain has a canonical name, which cannot be changed after it is created, and a status of active or disabled.

Domains are seeded once, on a standalone edge server’s or unified daemon’s first start:

  • From configuration: the domains in bootstrap_domains under [hosting], with the first one as the default.
  • Fallback: the host of public_url, when that list is empty.
  • After first start: an admin manages domains on the Domains page of the management UI, or through the control plane’s /api/domains routes.

How the domain for a new DID is chosen

When a caller creates a DID, the domain is chosen in this order:

  1. The domain the caller names explicitly, for example with --domain on pnm did-mgmt dids create.
  2. The default domain on the caller’s ACL entry, if it has one.
  3. The system default domain, but only for callers whose ACL entry allows all domains.

If none of these applies, the request is refused and the caller must name a domain. The system default must be an active domain. To disable or delete it, first make another domain the default.

How one deployment serves several tenants

Each owner’s ACL entry can limit the owner to a list of domains, with one of them as its default. Give each tenant’s owner a scope listing only that tenant’s domain, with that domain as its default, and the tenant can publish only there. See Roles and access for the scope options.

Your VTA can list the domains it may use on a server. See Create and manage DIDs.

How a request is matched to a domain

When a resolution request arrives, the server compares its host with the host embedded in the requested DID, and returns 404 if they differ.

  • Default: the server uses the request’s literal Host header.
  • Behind a reverse proxy: list the proxy’s addresses in trusted_proxy_cidrs under [server]. The server then takes the host from the proxy’s Forwarded or X-Forwarded-Host header, and ignores those headers from anyone else.

What disabling or deleting a domain does

Disabling a domain is how you retire it:

  • Resolution on the domain returns 503 straight away, and new DIDs and updates on it are refused.
  • After a grace period, set by disable_purge_grace under [hosting] and 30 days by default, the edge servers permanently delete every DID on the domain, then the domain itself.
  • Enabling the domain again within the grace period cancels the deletion.

An admin can delete a disabled domain earlier. Deleting a domain requires a session at the higher assurance level, from a passkey sign-in or a passkey or VTA step-up, and the request must repeat the domain’s name to confirm it.

Creating, updating, disabling, or enabling a domain, and changing the default domain, is replicated from the control plane to every registered edge server. Deleting a domain removes it from the control plane, and sends a purge only to the edge servers that serve it when you request purging.

What assigning and unassigning a domain does

On the Servers page of the management UI, an admin assigns domains to each registered edge server:

  • + Assign domain: records that the server hosts the domain, and cancels any pending purge of it.
  • Unassign: schedules the server’s copies of the domain’s DIDs for deletion after unassigned_purge_grace under [hosting], 2 hours by default. Re-assigning within that window cancels it.
  • Purge now: deletes the domain’s DIDs from that server immediately. This cannot be undone.

  Roles and access

  DID lifecycle

  Create and manage DIDs