release(v4.4.0): public accessor for device identity public key

Expose the local device's 32-byte Ed25519 identity public key on Shade
so apps can hand it to their own backend at enrollment time for
signature verification, key pinning or per-device safety-number
computation. Closes the gap that forced consumers to ship placeholder
random bytes their backend could store but never verify against.

- @shade/sdk Shade.identityPublicKey: Promise<Uint8Array> — getter
  mirrors the existing fingerprint accessor. Throws pre-init,
  reflects the current key after rotate(), retired key preserved in
  retired-identities storage per existing grace-period contract.
  Private key remains unreachable.
- Test in shade-sdk/tests/sdk.test.ts: round-trip match against the
  underlying storage's signingPublicKey, plus value updates after
  rotate().
- Lockstep version bump 4.3.0 → 4.4.0 across all 25 packages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 17:58:45 +02:00
parent f5f42fe557
commit dbb3a090d8
29 changed files with 268 additions and 26 deletions

View File

@@ -5,6 +5,35 @@ All notable changes to Shade are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [4.4.0] — 2026-05-05 — Public accessor for the device's identity public key
Browser-based Shade consumers building enrollment flows had no way to
hand the device's actual Ed25519 identity public key to their own
backend — the key was reachable only via the private
`storage.getIdentityKeyPair()` call inside `Shade`. Apps shipped with
placeholder bytes (`crypto.getRandomValues(new Uint8Array(32))`) that
the backend stored but couldn't verify against, deferring real
cryptographic device binding until the SDK exposed the key.
### Added
#### `@shade/sdk`
- `Shade.identityPublicKey: Promise<Uint8Array>` — getter returning the
local device's 32-byte Ed25519 identity public key. Mirrors the
`fingerprint` accessor shape. Throws if accessed before
`initialize()`. Reflects the current key after `rotate()`; the
previous key remains in retired-identities storage for the
configured grace period. Use `fingerprint` (12-group safety number)
for human side-channel comparison; use `identityPublicKey` when
handing the raw key to a backend for signature verification or
pinning.
### Tests
- `packages/shade-sdk/tests/sdk.test.ts` — `identityPublicKey exposes
the device Ed25519 key and tracks rotation` covers the round-trip
match against the underlying storage and that the value updates
after `rotate()`.
## [4.3.0] — 2026-05-05 — Browser persistence via `@shade/storage-indexeddb`
Browser-based Shade consumers had no path to session persistence: the only