webvh-watcher 0.8.3

WebVH Watcher, read-only DID mirror service
Documentation

Affinidi WebVH Watcher

The WebVH Watcher is a read-only DID mirror that receives pushed DID updates from did-hosting-server instances and serves them publicly. It provides redundancy, geographic distribution, and load balancing for DID resolution without managing DIDs directly.

The watcher has no authentication, no ACL, and no DID lifecycle management — it simply stores and serves replicated DID content.

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.

Getting Started

Prerequisites

  • Rust 1.94.0+ (2024 Edition)

1. Build

cargo build -p webvh-watcher --release

The binary is produced at target/release/webvh-watcher.

2. Configure

Create a config.toml:

[server]
host = "0.0.0.0"
port = 8533

[log]
level = "info"

[store]
data_dir = "data/webvh-watcher"

[sync]
# Shared secret tokens that source servers must present when pushing
push_tokens = ["my-shared-secret-token"]

# Optional: source servers to pull from for reconciliation
# [[sync.sources]]
# url = "http://server1:8530"
# token = "pull-token"

3. Configure the source server

On the did-hosting-server that will push DID updates, add the watcher to its config.toml:

[[watchers]]
url = "http://watcher1.example.com:8533"
token = "my-shared-secret-token"

The token must match one of the watcher's sync.push_tokens.

4. Start the watcher

webvh-watcher --config config.toml

How It Works

did-hosting-server ──(POST /api/sync/did)──► webvh-watcher
             ──(POST /api/sync/delete)──►

Clients ──(GET /{mnemonic}/did.jsonl)──► webvh-watcher
  1. A DID is published on a did-hosting-server
  2. The server pushes the DID content to all registered watchers
  3. The watcher stores the content and serves it at the same public paths as the original server
  4. Clients can resolve DIDs from any watcher instance

Push failures on the server side are logged but do not block the primary publish operation.

Configuration

The watcher is configured via a TOML file. By default it looks for config.toml in the current directory. You can specify a different path with the --config flag or the WATCHER_CONFIG_PATH environment variable.

Environment Variable Overrides

Variable Description
WATCHER_CONFIG_PATH Path to config file
WATCHER_SERVER_HOST Bind host
WATCHER_SERVER_PORT Bind port
WATCHER_LOG_LEVEL Log level

CLI Commands

webvh-watcher                                  # Run watcher (default)
webvh-watcher setup                            # Interactive config wizard
webvh-watcher setup --from <recipe.toml>       # Non-interactive (see examples/)
webvh-watcher setup --from <recipe.toml> --force-reprovision  # overwrite existing

The watcher has no VTA / no secret store, so the recipe is just [deployment], [output], [server], and [watcher] — see examples/webvh-watcher-build.toml.

API Endpoints

Public (unauthenticated)

Method Path Description
GET /api/health Health check
GET /{mnemonic}/did.jsonl Resolve DID log
GET /{mnemonic}/did-witness.json Resolve witness
GET /.well-known/did.jsonl Root DID log
GET /.well-known/did-witness.json Root witness

Sync (token-authenticated)

Method Path Description
POST /api/sync/did Receive pushed DID
POST /api/sync/delete Receive DID deletion

Sync endpoints require a Bearer token matching one of the configured sync.push_tokens.

Library Usage

The webvh-watcher crate can be used as a library (e.g., by the did-hosting-daemon). It exposes:

  • webvh_watcher::config::AppConfig — configuration
  • webvh_watcher::server::AppState — application state
  • webvh_watcher::routes::router() — Axum router
  • webvh_watcher::server::run() — standalone entry point

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.