-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Context
Similar to contracts (#59), updating the chat delegate WASM results in a new DelegateKey because the key is derived from:
DelegateKey = Blake3(CodeHash || Parameters)
This means any change to delegate logic creates an entirely new delegate identity. Since all delegate secrets (signing keys, key-value storage) are tied to the DelegateKey, upgrading the delegate effectively orphans all user data stored by the old delegate.
Current State
The chat delegate stores critical user data via the Freenet secret storage system:
- Signing keys for each room (32-byte Ed25519 keys)
- Key-value storage for room-specific data
- Key indices tracking what data exists
This data is encrypted using XChaCha20Poly1305 with a cipher registered per-delegate. When the delegate code changes:
- A new
CodeHashis computed (BLAKE3 of WASM) - A new
DelegateKeyis derived - The new delegate cannot access secrets stored under the old key
- Users lose their signing keys and stored data
Options to Explore
1. UI-Mediated Migration (short-term)
The UI already communicates with delegates via ApplicationMessage. A migration flow could:
- Detect when a new delegate version is available
- Request data export from old delegate (new
ExportDatamessage type) - Register new delegate
- Import data to new delegate (new
ImportDatamessage type) - Unregister old delegate
Questions:
- How does the UI know a new delegate version exists?
- Should export/import be one message type or separate per data category?
- How do we handle partial migration failures?
2. Direct Delegate-to-Delegate Communication
Delegates currently communicate only with their registering contract/app. Enabling direct delegate communication could allow:
- Old delegate receives "migration request" from new delegate
- Old delegate exports secrets to new delegate directly
- New delegate validates and stores the imported data
Questions:
- What authentication ensures only the legitimate new version can request migration?
- How do we prevent malicious delegates from extracting secrets?
- Does this require Freenet protocol changes?
3. Stable Delegate Identity Layer
Separate delegate identity from code hash:
- Introduce
DelegateIdentityindependent of code DelegateKeybecomesBlake3(DelegateIdentity || Version)- Secrets keyed by
DelegateIdentity, notDelegateKey - New versions of same identity can access existing secrets
Questions:
- How is
DelegateIdentityestablished and verified? - Who controls what code versions map to an identity?
- Does this require significant Freenet changes?
4. Secret Storage Migration at Protocol Level
Add Freenet support for secret migration:
MigrateSecrets(old_delegate_key, new_delegate_key, proof)operation- Runtime transfers encrypted secrets between delegate keys
- Proof validates the migration is authorized
Questions:
- What constitutes valid migration proof?
- Should old secrets be deleted or preserved?
- How does this interact with the encryption cipher per-delegate?
5. Versioned Delegate with Backward Compatibility
Include version handling in delegate code:
- Delegate parameters include version field
- Same code handles multiple storage formats
- Backward-compatible changes reuse existing secrets
Limitations:
- Doesn't solve code hash change problem
- Only works for additive changes
- WASM size bloat over time
Related
- Explore graceful contract upgrade mechanisms #59 - Graceful contract upgrade mechanisms (same problem for contracts)
delegates/chat-delegate/src/handlers.rs- current secret storage logicfreenet-stdlib/rust/src/delegate_interface.rs- delegate identification
Next Steps
Looking for input on:
- Which approach(es) are most feasible for delegates specifically?
- Can we leverage any contract migration work from Explore graceful contract upgrade mechanisms #59?
- What's the minimal viable solution that preserves user signing keys?
[AI-assisted - Claude]