Skip to content

v0.1+: Generation suffix for child key rotation (/0, /1, /2) #8

@hanwencheng

Description

@hanwencheng

Summary

In the MSK-derived key model, child keys are derived from a master key at a specific path. Add a numeric generation suffix to the path convention to support key rotation without path recycling.

Problem

Path recycling (reusing the same path for a different agent) is disabled because it:

  1. Produces the same derived key as the previous agent at that path
  2. Gives the new agent access to the old agent's untorn-down credentials
  3. Destroys the recovery model (recovery re-derives the same key from MSK + path — if the path was recycled, recovery produces the wrong agent's key)

However, key rotation within a single agent's lifetime is a legitimate need (periodic security rotation, post-incident rotation, compliance-driven rotation).

Proposed design

Path convention

Base path:      /agent-1
With generation: /agent-1/0    ← initial key
After rotation:  /agent-1/1    ← rotated key (different derived key, same logical agent)
After rotation:  /agent-1/2    ← rotated again

The generation suffix is a monotonically increasing integer starting at 0.

Derivation

initial:  child_key_v0 = soft_derive(master_key, "/agent-1/0")
rotated:  child_key_v1 = soft_derive(master_key, "/agent-1/1")

Different generation → different derived key → different wallet address → clean cryptographic separation.

Rotation flow

master CLI → TEE: rotate_child_key("/agent-1")
  ↓
TEE reads current generation from chain state (e.g., generation=0)
TEE increments: generation=1
TEE derives new key at /agent-1/1
TEE submits on-chain:
  - suspend event for /agent-1/0 (old generation)
  - activation event for /agent-1/1 (new generation)
  - credential re-encryption from old wallet to new wallet (if needed)
TEE issues new JWT for /agent-1/1 to the daemon
  ↓
daemon receives new JWT, starts using it
old JWT for /agent-1/0 expires naturally or is rejected (suspended path)

Chain state

Per child path, the chain stores:

current_generation: u32    ← monotonically increasing

This is one integer per agent — minimal on-chain state.

Path recycling stays disabled

Recycling means: decommission agent-1, then create a NEW, DIFFERENT agent at path "/agent-1". This is disabled.

Generation suffix means: the SAME agent at path "/agent-1" gets a fresh key. Different semantics.

The distinction: rotation preserves agent identity (same logical agent, new key). Recycling replaces agent identity (different logical agent, same path).

Priority

Enhancement. Not required for v0.1 MVP, but should be designed into the path convention from the start so the suffix slot is reserved even if rotation isn't implemented yet.

Implementation notes

  • The initial pair flow should use /agent-alias/0 (not just /agent-alias) so the generation slot is always present
  • Generation counter stored on chain as a single u32 per agent path
  • Credential migration on rotation: credentials keyed by wallet address need re-encryption to the new wallet, OR credentials should be keyed by the base path (not the wallet address) so they survive rotation without re-encryption

References

  • wiki/blockchain-tee-architecture.md — MSK-derived key design, path conventions
  • docs/spec/plans/development-stages.md Stage 9 — design decisions for key derivation model

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestv0.1development plan for blockchain backend integration

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions