Add Product key signature scheme - #111
Merged
Merged
Conversation
15 tasks
knzeng-e
marked this pull request as ready for review
August 3, 2026 13:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outcome
Adds an API-side
product-sr25519-v1signature scheme for Dotify session sign-in and protected content-key requests.Product-host clients can now sign the same canonical Dotify request message bytes with the app-scoped Product account, send the Product public key, and have the backend bind that public key to the requester H160 before nonce consumption and runtime access checks. The existing standalone
eip191path remains the default for omittedsignatureScheme.Issue and context
Refs #85.
Stacked on #110, which adds the experimental Product CDM runtime adapter. This PR addresses the next backend authentication boundary from the Product roadmap: Product identity must not become a protected playback account unless the API can verify the Product signature and prove that the Product account maps to the same H160 address used by
musicAccCanAccess.Local scope docs:
docs/backlog/polkadot-product-readiness-and-killer-dapp-roadmap.mddocs/explanation/product-devnet-architecture.mddocs/operations/deployment-configuration.mddocs/product/ux-signature-flows.mdArchitecture and key concepts
The backend now has two request schemes:
eip191: default/backward-compatible standalone wallet path usingviem.verifyMessageagainst the requester H160.product-sr25519-v1: Product-host path requiringsignatureplusproductPublicKey; the backend verifies sr25519 over the canonical Dotify message bytes and derives H160 from the Product public key using the Product SDK / pallet-revive mapping.The canonical message format did not change. This avoids splitting Dotify's access protocol by host environment: the signer changes, but the payload still binds action, purpose, content hash, requester, chain, nonce, and expiry.
How it works
POST /api/auth/sessionandPOST /api/tracks/:contentHash/key-requestnow validate a discriminated signature shape.For
product-sr25519-v1:productPublicKeyand 64-byte sr25519signature.musicAccCanAccesscheck before key derivation.Unknown schemes fail at the API schema boundary before signature verification or access checks. Product public-key mismatches fail before nonce consumption.
Design decisions and tradeoffs
The API supports Product signatures before the Product frontend sends them. That keeps the security boundary reviewable independently from UI wiring and prevents frontend work from needing to invent the backend contract.
Alternatives considered:
Security, failure, and operations
Security invariants preserved:
musicAccCanAccess.Operational docs now call out that no new env variable is required and that the shipped Product frontend still needs a follow-up to submit this Product proof shape.
npm audit --omit=dev --audit-level=moderatecurrently fails on existing production dependency advisories infast-uri,find-my-way, andviem/ws. The new@scure/sr25519dependency is not listed in that audit output. I did not broaden this PR into dependency remediation.Review guide
Suggested order
services/api/src/services/signatures.ts- verify the scheme dispatch, Product sr25519 verification, H160 derivation, and nonce-consumption ordering.services/api/src/routes/auth.tsandservices/api/src/routes/keys.ts- verify request schemas reject unknown/malformed Product schemes before verifier/access calls.services/api/src/services/signatures.test.ts,services/api/src/routes/auth.test.ts, andservices/api/src/routes/keys.test.ts- verify real sr25519 positive/negative cases plus HTTP boundary behavior.docs/product/ux-signature-flows.md,docs/operations/deployment-configuration.md,docs/explanation/product-devnet-architecture.md,README.md,spec.md,web/README.md, anddocs/index.html- verify the docs distinguish API readiness from shipped frontend Product playback.Verify carefully
signatureSchemeremain backward-compatible with existing EIP-191 clients?Validation
cd services/api && npm run typecheckcd services/api && npm testcd services/api && npm run buildgit diff --checknode scripts/backlog-sync.mjs --check --offlinecd services/api && npm audit --omit=dev --audit-level=moderatefast-uri,find-my-way, andviem/ws; new@scure/sr25519is not in the reported vulnerable paths.Known limitations and follow-ups
This PR should remain
Refs #85, notCloses #85.Remaining before #85 can close:
product-sr25519-v1payloads;cdm.jsonmanifest and generated Product contract types into Product mode;Metadata checklist
Dotify sprints) - connector does not expose Project v2 mutation and localghauth is invalid in this sessionknzeng-edotify-backlog,product-sdk