Skip to content

feat: add host-owned IPNS deployments - #664

Merged
lthibault merged 1 commit into
masterfrom
phase-3-ipns
Aug 23, 2026
Merged

feat: add host-owned IPNS deployments#664
lthibault merged 1 commit into
masterfrom
phase-3-ipns

Conversation

@lthibault

Copy link
Copy Markdown
Contributor

Architecture

Wetware now owns IPNS semantics and identity:

~/.ww/identity
      ↓
  rust-ipns
sign / verify
      ↓
raw signed record
      ↓
HTTP Routing V1
      ↓
     Kubo

Kubo is transport and routing only. Kubo does not hold the Wetware private key.

IPNS uses the existing deployment pipeline:

stem::ipns::Source
      ↓
  deployment

The change does not add a parallel deployment pipeline.

Identity

  • ~/.ww/identity is both the Wetware host/network identity and the default IPNS publication identity.
  • The default IPNS name derives from the host PeerID.
  • Rotating the host identity changes both the PeerID and the default IPNS name.
  • Identity persistence is private, atomic, and durable.
  • Wetware no longer creates or uses the automatic Kubo "ww" signing key for Wetware-owned publication.
  • Existing Kubo "ww" keys remain untouched.

Following

IPNS Stem following uses signed raw records and a durable rollback watermark.

  • A valid persisted record can seed boot.
  • An expired persisted record preserves the ordering floor but does not seed boot.
  • Stale records are ignored.
  • Duplicate records do not create deployment transitions.
  • Same-value refreshes update persistence and EOL without advancing deployment Epoch.
  • Higher-sequence same-value records advance the watermark without advancing deployment Epoch.
  • Higher-sequence new values persist before the Source emits a deployment update.
  • Invalid signatures, wrong signers, and malformed records do not affect authority.
  • Same-sequence different-value records are publisher equivocation.
  • deployment::Epoch.seq remains host-local and never derives from the IPNS sequence.

Runtime EOL

The signed record EOL is an authority deadline. stem::ipns::Source races routing retrieval and retry against the EOL deadline. Network backoff cannot extend authority past signed validity.

authoritative-invalid update
        ↓
local Epoch advances
        ↓
root=None
        ↓
old PID0 terminates
        ↓
host remains alive
        ↓
later valid IPNS record can recover

Durable watermark

Follower state stores the raw signed IPNS record under private host state:

~/.ww/ipns/follow/<canonical-name>.record

Publisher state uses the corresponding private path:

~/.ww/ipns/publish/<canonical-name>.record

Writes use restrictive permissions, atomic replacement, and durable synchronization. Wetware persists the accepted raw record before Source emission and before publication PUT. The ordering floor survives record expiry.

The trusted-state threat model assumes one process per private state directory. The implementation does not defend against malicious local filesystem rollback.

Publication

Wetware signs records locally with ~/.ww/identity and publishes them with:

PUT /routing/v1/ipns/{name}

The publisher preserves sequence continuity across restart and failure:

  • The first publication begins at sequence 0.
  • A changed value increments above the highest reconciled floor.
  • A same-value refresh retains the sequence and extends EOL.
  • A failed PUT retries the exact persisted signed bytes.
  • Local state persists before PUT.
  • Higher remote same-value state reconciles without sequence regression.
  • Unexpected higher remote different-value state causes a single-writer conflict and blocks publication.

The last behavior is deliberate. A newer record signed by the same key but selecting another value can indicate another writer, stale local configuration, or key compromise. Wetware fails clearly instead of silently reasserting local state.

Republisher

Wetware owns the republisher lifecycle because Kubo does not hold the host private key. The current policy mirrors practical Kubo behavior:

  • 48-hour record lifetime;
  • 5-minute TTL;
  • 4-hour republish interval;
  • 1-minute initial delay;
  • 5-minute temporary-failure retry.

Same-value republishing retains the sequence and extends EOL.

Routing V1 / Kubo

Raw record transport uses:

GET /routing/v1/ipns/{name}
PUT /routing/v1/ipns/{name}

The media type is application/vnd.ipfs.ipns-record.

Kubo 0.33 requires:

ipfs config --json Gateway.ExposeRoutingAPI true

Kubo must restart after the configuration change. Routing V1 runs on the Gateway listener, normally http://localhost:8080, not the administrative RPC listener on port 5001.

The client handles Kubo 0.33-style 404 missing-record responses and newer successful text/plain no-record responses. Other unexpected successful media types remain malformed.

Interoperability

Live Rust/Wetware to Kubo verification covered these properties:

  • Rust signed with an Ed25519 key absent from the Kubo keystore.
  • Routing V1 PUT succeeded.
  • GET returned identical bytes.
  • Signer, value, sequence, EOL, TTL, and signatures validated.
  • The Kubo keystore remained unchanged.

Live Kubo/Boxo to Rust verification covered these record forms:

  • V2-only Ed25519;
  • hybrid V1+V2 Ed25519;
  • V2-only RSA with a non-inline PeerID.

rust-ipns dependency

Wetware temporarily pins commit 02c5ae7bf3f9568c7dbbb1308ae9299cfc7ba2d9 from https://github.com/wetware/rust-ipfs.

The reviewed change is pending in dariusc93/rust-ipfs#503. The pin must be replaced by an upstream release that contains the reviewed V2-only fix when such a release becomes available.

Migration

  • ww perform install creates only the host identity and reports the derived default IPNS name.
  • Installation no longer creates a Kubo "ww" signing key.
  • ww perform update configures the host-derived name and Routing V1 endpoint.
  • Existing Kubo "ww" keys are ignored but not deleted.
  • Operators must enable and configure Routing V1 before publication.
  • Bootstrap preserves availability while initial publication retries.

Deferred work

This PR does not include:

  • Routing / ARCH-13 guest capability redesign;
  • changes to guest Routing.publish;
  • Cap'n Proto changes;
  • WIT changes;
  • capnp/stem.capnp cleanup;
  • multi-writer coordination;
  • state-directory locking;
  • embedded IPFS;
  • unrelated annealing.

Validation

The changelog includes the Phase 3-IPNS behavior and migration requirements.

The following commands passed:

cargo fmt --all -- --check
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --no-fail-fast
git diff --check

Additional verification passed:

  • RoutingClient and publisher focused tests: 26 passed.
  • IPNS Source and EOL tests: 12 passed.
  • Kubo 0.33 live Routing V1 interoperability passed.
  • PID0 replacement end-to-end tests passed.
  • Kubo validation used isolated disposable state.

@lthibault
lthibault merged commit 3cfd54b into master Aug 23, 2026
14 checks passed
@lthibault
lthibault deleted the phase-3-ipns branch August 23, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant