Skip to content

feat(delegate): add list_secrets key enumeration to secret-storage API#80

Merged
iduartgomez merged 2 commits into
mainfrom
feat/delegate-secret-key-enumeration
Jun 21, 2026
Merged

feat(delegate): add list_secrets key enumeration to secret-storage API#80
iduartgomez merged 2 commits into
mainfrom
feat/delegate-secret-key-enumeration

Conversation

@iduartgomez

Copy link
Copy Markdown
Contributor

Problem

The delegate secret-storage API (get_secret / set_secret / has_secret / remove_secret) is opaque key→value with no way to enumerate keys. An app that stores an open-ended family of keys (one per entity, e.g. River's room:<owner_vk>) cannot discover what it has stored. This bites hardest during migration: delegate keys are BLAKE3(code_hash || params), so any delegate-WASM change produces a new delegate with empty storage that must migrate the old data — but with no enumeration, migration can only probe a fixed, hardcoded key set, silently stranding dynamic key families. River hit exactly this in freenet/river#345.

Solution

Add a first-class list_secrets (optionally prefix-scoped) operation to the delegate secret-storage API:

  • New request/response surface + DelegateCtx::list_secrets, encode/decode_secret_key_list codec.
  • Two new hostcalls under the freenet_delegate_secrets import module.

The new variants are additive on the #[non_exhaustive] wire-boundary enums — existing bincode discriminants are unchanged, no existing variant is reordered, and deployed delegate WASM compiled against earlier 0.x stdlib continues to deserialize existing variants unmodified.

Version bumped 0.8.1 → 0.8.2 so freenet-core can depend on the published release (stdlib-first policy — this PR merges + publishes before the freenet-core consumer PR opens for review).

Testing

Wire-format pin tests (4/4) confirm existing variant tags are unchanged; codec round-trip tests (4/4) cover the new list encode/decode incl. empty and prefix cases. clippy/fmt clean.

Fixes

Part of freenet/freenet-core#4355 (stdlib half). The freenet-core host-side handler lands in a follow-up PR once this publishes to crates.io.

The delegate secret-storage hostcall API (get_secret/set_secret/
has_secret/remove_secret) was opaque key->value with no way to
enumerate stored keys. Apps storing an open-ended key family (e.g.
River's room:<owner_vk>) could not rediscover what they had stored,
which strands dynamic key families across a delegate-WASM rebuild
(new delegate key = empty storage, migration could only probe a
hardcoded key set). River hit this in freenet/river#345 and had to
build app-level ListRequest/ListResponse.

Add a first-class enumerate operation to the hostcall surface:

- two new `freenet_delegate_secrets` imports,
  `__frnt__delegate__list_secrets_len` / `__frnt__delegate__list_secrets`,
  following the existing len-then-fill two-call pattern used by
  get_secret so a variable-length result crosses the WASM boundary
  without a fixed cap on the guest side;
- `DelegateCtx::list_secrets(prefix)` returning the raw keys (optionally
  prefix-scoped; empty prefix lists all);
- a single authoritative wire codec (`encode_secret_key_list` /
  `decode_secret_key_list`, length-prefixed records) shared by the host
  emitter, the guest decoder, and the round-trip tests so the two sides
  cannot drift.

Additive only: no existing import signatures or enum variants change, so
deployed delegate WASM is unaffected.

Claude-Session: https://claude.ai/code/session_01JZGPSEa8g1Z8Nomv528c8g
The branch adds new public symbols (encode/decode_secret_key_list, the
two __frnt__delegate__list_secrets{,_len} hostcalls, and
DelegateCtx::list_secrets) but kept version = 0.8.1, which is ALREADY
published to crates.io. crates.io refuses to re-publish an existing
version, so the publish that is meant to unblock the freenet-core PR
(#4355) would itself fail.

Bump to 0.8.2: the additions are wire-format-additive (the touched enums
are #[non_exhaustive] and no existing tag numbers move), so this is a
backward-compatible patch release. Verified the wire-format pin tests
(*_wire_format_is_stable) and the new secret_key_list_codec round-trip
tests still pass at 0.8.2.

Stdlib-first: this must merge and publish to crates.io BEFORE the
freenet-core PR (which now depends on "0.8.2") opens for review.

Claude-Session: https://claude.ai/code/session_01JZGPSEa8g1Z8Nomv528c8g
@iduartgomez iduartgomez enabled auto-merge (squash) June 21, 2026 06:52
@iduartgomez iduartgomez disabled auto-merge June 21, 2026 06:52
@iduartgomez iduartgomez merged commit f56e5f9 into main Jun 21, 2026
9 checks passed
@iduartgomez iduartgomez deleted the feat/delegate-secret-key-enumeration branch June 21, 2026 06:52
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