Skip to content

Repository files navigation

Affinidi DID Hosting Service

A collection of services to operate WebVH DIDs in production.

IMPORTANT: did-hosting-service crates are provided "as is" without any warranties or guarantees, and by using this framework, users agree to assume all risks associated with its deployment and use including implementing security, and privacy measures in their applications. Affinidi assumes no liability for any issues arising from the use or modification of the project.

Architecture

The workspace contains six crates that can be deployed independently or combined into a single binary:

Standalone mode:                          Daemon mode:

┌──────────────┐                         ┌───────────────────────┐
│ did-hosting-control│ (UI + proxy + registry) │    did-hosting-daemon       │
│   :8532      │──────┐                  │       :8534           │
└──────────────┘      │                  │ ┌───────────────────┐ │
                      ├─► did-hosting-server   │ │ /          server │ │
┌──────────────┐      │     :8530        │ │ /witness   witness│ │
│ did-hosting-server │◄─────┘                  │ │ /watcher   watcher│ │
│   :8530      │      ├─► webvh-witness  │ │ /control   control│ │
└──────────────┘      │     :8531        │ └───────────────────┘ │
┌──────────────┐      │                  │   (shared listener,   │
│webvh-witness │◄─────┘                  │    separate stores)   │
│   :8531      │      ├─► webvh-watcher  └───────────────────────┘
└──────────────┘      │     :8533
┌──────────────┐      │
│webvh-watcher │◄─────┘
│   :8533      │ (read-only DID mirror)
└──────────────┘

Components

Crate Binary Description
did-hosting-server did-hosting-server Read-only DID hosting edge node — serves DID documents publicly and receives sync updates from the control plane via DIDComm
webvh-witness webvh-witness Witness node — generates and manages cryptographic witness proofs for DID integrity verification
webvh-watcher webvh-watcher Read-only DID mirror — receives pushed DID updates from servers and serves them publicly for redundancy
did-hosting-control did-hosting-control Control plane — DID lifecycle management via DIDComm and REST API, management UI, service registry, passkey authentication
did-hosting-daemon did-hosting-daemon Unified daemon — embeds server + witness + watcher + control plane in a single binary (recommended for most deployments)
did-hosting-common (library) Shared types, traits, auth, ACL, storage, config, and passkey modules used by all services

Quick Start

Requirements

  • Rust 1.94.0+ (2024 Edition)
  • Node.js 20+ (only if building the management UI)

Option 1: Unified daemon (recommended for getting started)

The daemon runs all services on a single port:

git clone https://github.com/affinidi/did-hosting-service.git
cd did-hosting-service
cargo build -p did-hosting-daemon --release
./target/release/did-hosting-daemon

The daemon supports two identity modes at setup time:

  • VTA-managed (default) — a parent VTA provisions the daemon's keys and DID. Requires VTA credentials.
  • Self-managed — the daemon generates its own keys and self-hosts a did:webvh identifier. No VTA required. Daemon-only. See docs/bootstrap_startup.md.

See did-hosting-daemon/README.md for configuration details.

Option 2: Standalone services

Run each service independently for distributed deployments:

# Build all services
cargo build --workspace --release

# Run each service with its own config
did-hosting-server setup && did-hosting-server
webvh-witness setup && webvh-witness
did-hosting-control setup && did-hosting-control
webvh-watcher --config watcher-config.toml

See each crate's README for detailed setup instructions.

Building with --no-default-features? The DID-method features (method-webvh, method-web) are part of the default set on did-hosting-server and did-hosting-common. A minimal build that drops them compiles fine but silently 404s every public DID resolution. If you customise features, opt the methods back in explicitly — see did-hosting-server/README.md.

Option 3: Non-interactive / scripted setup

Every setup subcommand accepts --from <recipe.toml> for CI / scripted deployments. The recipe is declarative TOML with no secrets — keys are generated by setup; cloud credentials come from the environment.

Online (VTA reachable from CI runner):

# Phase 1: mint an ephemeral did:key, get the operator's PNM command, exit.
did-hosting-server setup --setup-key-out setup.key --context webvh
# (operator enrols the printed did:key at the VTA on a workstation)

# Phase 2: recipe drives everything else.
did-hosting-server setup --from examples/did-hosting-server-build.toml \
                   --setup-key-file setup.key

Air-gapped (no VTA network access — both phases non-interactive):

# Phase 1: vta_mode = "offline-prepare" in the recipe.
did-hosting-server setup --from recipe.toml
# → writes bootstrap-request.json + persists ephemeral seed in secret backend.
# (operator ferries the request to the VTA admin and receives sealed bundle)

# Phase 2: flip vta_mode = "offline-complete" + add bundle_path/expect_digest.
did-hosting-server setup --from recipe.toml
# → opens the sealed bundle, finishes setup. No TTY required.

VTA-less daemon (self-managed):

# daemon recipe with vta_mode = "self-managed" — generates its own keys.
did-hosting-daemon setup --from examples/did-hosting-daemon-build.toml

Other flags: --force-reprovision to rotate an existing install (backs up config.toml first), --non-interactive to fail fast on missing fields instead of prompting, <binary> uninstall to tear down. Full reference in docs/bootstrap_startup.md.

Example Client

The did-hosting-server crate includes an example CLI (did-hosting-server/examples/client.rs) that demonstrates the full flow of programmatically creating a did:webvh DID and uploading it to a running did-hosting-control or did-hosting-daemon. It handles DIDComm v2 authentication, DID document construction, WebVH log entry creation, and upload.

Building

cargo build -p did-hosting-server --example client

Usage

  1. Start the did-hosting-server with DIDComm authentication configured.

  2. Run the example, pointing it at the server. --webvh-did is the service's own DID — it's printed by did-hosting-server setup and did-hosting-daemon setup on completion. Re-print it any time with did-hosting-server show-did (or did-hosting-daemon show-did):

    cargo run -p did-hosting-server --example client -- \
      --server-url http://localhost:8530 \
      --webvh-did did:webvh:...:localhost%3A8530:server
  3. The example will generate a did:key identity and pause, printing the DID:

    Generated DID: did:key:z6Mk...
    Ensure this DID is in the server ACL (e.g. via did-hosting-server invite).
    Press Enter to continue...
    

    Add the printed DID to the server's ACL (for example, by running the did-hosting-server add-acl command in another terminal), then press Enter.

  4. The example will authenticate, create the DID, upload it, and verify resolution. On success it prints a summary:

    DID Created and Hosted Successfully!
      Mnemonic:   apple-banana
      SCID:       FHcGtSJ...
      DID URL:    http://localhost:8530/apple-banana/did.jsonl
      DID:        did:webvh:FHcGtSJ...:localhost%3A8085:apple-banana
      Public Key: z6Mk...
    

Support & feedback

If you face any issues or have suggestions, please don't hesitate to contact us using this link.

Reporting technical issues

If you have a technical issue with the Affinidi DID Hosting Service codebase, you can also create an issue directly in GitHub.

  1. Ensure the bug was not already reported by searching on GitHub under Issues.

  2. If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behaviour that is not occurring.

Contributing

Want to contribute?

Head over to our CONTRIBUTING guidelines.

About

WebVH DID Infrastructure Services

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages