Environment: Foundation SDK 1.0.0 (foundation 1.0.0 (039881500da0)), KeyOS 1.4.0-beta3, retail Passport Prime, third-party publisher.
Summary
A third-party app currently has no way to learn any address derived from the device's master seed. That forces read-only "show me my assets" apps into one of two bad options, and I'd like to propose a third that gives them what they need without giving them signing power.
The gap, as gated today
| message |
gating |
third-party |
GetSeed (id 6) |
ungrouped — so Foundation-only despite approval = "autoAllow" |
❌ |
GetAppSeed (id 8) |
device-secrets.app-scoped-seed, grantOnFirstUse |
✅ |
GetAppSeed is the right primitive for an app's own secrets, and I'm using it happily elsewhere. But it is hmac256(app_id, master_seed) — a different key. The addresses it derives hold none of the user's assets, so it cannot answer "what does this user own?".
That leaves a read-only app two choices, and both are bad:
- Ask the user to type an address. 42 hex characters on a touchscreen, per address, and it has to be re-entered on every device.
- Ask the user to type their seed phrase. This is the one I want to argue against, and it's why I'm filing rather than just building it. On a device whose entire purpose is that the seed never leaves it, a third-party app prompting for the seed is the exact phishing pattern the product exists to defeat — and worse, "this app cannot sign" would be a promise rather than a property. Any app holding seed bytes can sign; nothing structurally prevents it. I don't want to ship that, and I don't think you want third-party apps on Prime training users to do it.
What I'd like
A watch-only public derivation message — public keys only, no private material, no signing:
DerivePublicKey { path: "m/44'/60'/0'/0/0" } -> compressed pubkey (33 bytes)
or an extended-public-key form (GetXpub { path }) if that's a better fit for how the seed is held, so an app can derive a range of addresses itself without a round trip per index.
Gated exactly like GetAppSeed: a permissionGroup (something like device-secrets.watch-only-derivation) plus grantOnFirstUse, so the user sees and consents to a distinct prompt.
Why this shape
- No private key material crosses the boundary. The seed stays in
os/security; the app receives public keys it could have derived from an xpub anyway.
- "Cannot sign" becomes a structural property, not something the app promises. That's the whole point — it's the difference between a design I'd ship and one I won't.
- It's the familiar watch-only pattern. Exporting an xpub to a watch-only wallet is well-understood in Bitcoin tooling; this is the same idea, and the privacy trade-off (an xpub reveals a whole address range) is one users and reviewers already reason about. Per-path
DerivePublicKey is the tighter variant if you'd rather not hand out an xpub at all.
- It's strictly weaker than something you already grant.
GetAppSeed hands third-party apps real secret material behind a group and a consent prompt. This asks for public keys behind the same machinery.
Concrete use case
passport-nft-viewer — an offline, read-only NFT gallery (public repo, gui-app + removable-read only, no crypto permissions at all today). Images are fetched host-side and staged onto a USB drive; the device only reads files. The one thing it cannot do is know which addresses to show without the user typing them. With watch-only derivation it becomes "your Passport's own assets" with no address entry and no key exposure.
What I'm explicitly not asking for
Not GetSeed, and not a third-party signing path. If the answer is "public derivation is fine but only for Foundation-signed apps", that's useful to know too — I'd rather design against a clear no than guess.
Environment: Foundation SDK 1.0.0 (
foundation 1.0.0 (039881500da0)), KeyOS 1.4.0-beta3, retail Passport Prime, third-party publisher.Summary
A third-party app currently has no way to learn any address derived from the device's master seed. That forces read-only "show me my assets" apps into one of two bad options, and I'd like to propose a third that gives them what they need without giving them signing power.
The gap, as gated today
GetSeed(id 6)approval = "autoAllow"GetAppSeed(id 8)device-secrets.app-scoped-seed,grantOnFirstUseGetAppSeedis the right primitive for an app's own secrets, and I'm using it happily elsewhere. But it ishmac256(app_id, master_seed)— a different key. The addresses it derives hold none of the user's assets, so it cannot answer "what does this user own?".That leaves a read-only app two choices, and both are bad:
What I'd like
A watch-only public derivation message — public keys only, no private material, no signing:
or an extended-public-key form (
GetXpub { path }) if that's a better fit for how the seed is held, so an app can derive a range of addresses itself without a round trip per index.Gated exactly like
GetAppSeed: apermissionGroup(something likedevice-secrets.watch-only-derivation) plusgrantOnFirstUse, so the user sees and consents to a distinct prompt.Why this shape
os/security; the app receives public keys it could have derived from an xpub anyway.DerivePublicKeyis the tighter variant if you'd rather not hand out an xpub at all.GetAppSeedhands third-party apps real secret material behind a group and a consent prompt. This asks for public keys behind the same machinery.Concrete use case
passport-nft-viewer — an offline, read-only NFT gallery (public repo,
gui-app+removable-readonly, no crypto permissions at all today). Images are fetched host-side and staged onto a USB drive; the device only reads files. The one thing it cannot do is know which addresses to show without the user typing them. With watch-only derivation it becomes "your Passport's own assets" with no address entry and no key exposure.What I'm explicitly not asking for
Not
GetSeed, and not a third-party signing path. If the answer is "public derivation is fine but only for Foundation-signed apps", that's useful to know too — I'd rather design against a clear no than guess.