@seams/wallet-server 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/README.md +19 -4
  2. package/artifact-manifest.json +28 -13
  3. package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
  4. package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
  5. package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
  6. package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
  7. package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
  8. package/dist/esm/application-auth.js +2 -0
  9. package/dist/esm/auth/applicationAuth.js +85 -0
  10. package/dist/esm/auth/externalAuthService.js +149 -0
  11. package/dist/esm/auth/externalAuthStore.js +353 -0
  12. package/dist/esm/auth/externalOwnerOperations.js +82 -0
  13. package/dist/esm/authorization/domain.js +2 -2
  14. package/dist/esm/authorization/factorEvidence.js +1 -1
  15. package/dist/esm/authorization/service.js +2 -2
  16. package/dist/esm/authorization/vaultProxyUse.js +1 -1
  17. package/dist/esm/cloud-host.js +12 -11
  18. package/dist/esm/core/ThresholdService/validation.js +1 -1
  19. package/dist/esm/core/WebAuthnCredentialBindingStore.js +1 -1
  20. package/dist/esm/core/authService/webauthn.js +1 -1
  21. package/dist/esm/core/d1EcdsaSignerRead.js +1 -1
  22. package/dist/esm/core/d1WalletAuthMethodStore.js +2 -2
  23. package/dist/esm/core/d1WalletStore.js +1 -1
  24. package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -1
  25. package/dist/esm/core/deviceLinking/linkedDeviceManagement.js +1 -1
  26. package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -2
  27. package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -2
  28. package/dist/esm/hosted-wallet-gateway.js +3 -3
  29. package/dist/esm/index.js +1 -1
  30. package/dist/esm/router/auth/webAuthnCredentialCodecs.js +1 -1
  31. package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +2 -0
  32. package/dist/esm/router/cloudflare/d1/auth/d1RecordedOwnerOperation.js +43 -0
  33. package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +27 -3
  34. package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +2 -2
  35. package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +2 -2
  36. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +3 -3
  37. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +1 -1
  38. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +2 -2
  39. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +1 -1
  40. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSourceContributionPreparationPlanner.js +1 -1
  41. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetAuthenticatorStore.js +1 -1
  42. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
  43. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetPlanner.js +1 -1
  44. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkBuilder.js +2 -2
  45. package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkSourceReader.js +1 -1
  46. package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +1 -1
  47. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +1 -1
  48. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +1 -1
  49. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
  50. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +2 -2
  51. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +3 -3
  52. package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +1 -1
  53. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +1 -1
  54. package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +3 -3
  55. package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +7 -1
  56. package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +1 -1
  57. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -4
  58. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +4 -4
  59. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +1 -1
  60. package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +3 -3
  61. package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +1 -1
  62. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +11 -2
  63. package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +1 -1
  64. package/dist/esm/router/cloudflare/d1/registration/d1WalletExecutionAuthority.js +9 -16
  65. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +1 -1
  66. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +46 -4
  67. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetup.js +12 -0
  68. package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +1 -0
  69. package/dist/esm/router/cloudflare/d1/registration/registrationCompletionWrite.js +1 -0
  70. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -1
  71. package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +36 -1
  72. package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +1 -1
  73. package/dist/esm/router/cloudflare/d1/wallet/authorizationSnapshotLayout.js +1 -0
  74. package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdWalletSessionChallenges.js +2 -2
  75. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodBoundary.js +1 -1
  76. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodRevocationReplayStore.js +1 -1
  77. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +6 -5
  78. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -2
  79. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationCleanup.js +2 -1
  80. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationIntake.js +1 -1
  81. package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationSnapshot.js +1 -1
  82. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationChallenges.js +1 -1
  83. package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationOwnerRequest.js +2 -2
  84. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +2 -2
  85. package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +2 -2
  86. package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +9 -0
  87. package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +6 -0
  88. package/dist/esm/router/cloudflare-adaptor.js +1 -1
  89. package/dist/esm/router/cloudflare.js +6139 -5567
  90. package/dist/esm/router/domains/ecdsa/routerAbEcdsaStrictRegistration.js +1 -1
  91. package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +5 -5
  92. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js +2 -2
  93. package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +1 -1
  94. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoHttpRegistrationBackend.js +1 -1
  95. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistration.js +1 -1
  96. package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +1 -1
  97. package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +2 -2
  98. package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +1 -1
  99. package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +2 -2
  100. package/dist/esm/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.js +37 -3
  101. package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -1
  102. package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +1 -1
  103. package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +18 -3
  104. package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +12 -4
  105. package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +3 -3
  106. package/dist/esm/router/framework/http.js +1 -1
  107. package/dist/esm/router/framework/routeDefinitions.js +2 -1
  108. package/dist/esm/router/transport/fetch/createFetchRouter.js +5 -3
  109. package/dist/esm/router/transport/fetch/routes/auth.js +1 -1
  110. package/dist/esm/router/transport/fetch/routes/deviceLinking.js +3 -3
  111. package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
  112. package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +3 -3
  113. package/dist/esm/router/transport/fetch/routes/externalAuth.js +351 -0
  114. package/dist/esm/router/transport/fetch/routes/normalSigningRouterProxy.js +1 -1
  115. package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +46 -306
  116. package/dist/esm/router/transport/fetch/routes/sessions.js +4 -4
  117. package/dist/esm/router/transport/fetch/routes/syncAccount.js +2 -2
  118. package/dist/esm/router/transport/fetch/routes/syncAccountBootstrap.js +1 -1
  119. package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +4 -4
  120. package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +6 -6
  121. package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +2 -2
  122. package/dist/esm/router/transport/fetch/routes/walletRegistration.js +4 -4
  123. package/dist/esm/router/transport/fetch/walletOwnerOperationAuthorization.js +306 -0
  124. package/dist/esm/shared-ts/src/auth/externalAuth.js +118 -0
  125. package/dist/esm/shared-ts/src/authorization/index.js +1 -1
  126. package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +1 -1
  127. package/dist/esm/shared-ts/src/authorization/walletAuthority.js +2 -2
  128. package/dist/esm/shared-ts/src/authorization/{walletCustodyOperation.js → walletOwnerOperation.js} +4 -4
  129. package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -1
  130. package/dist/esm/shared-ts/src/device-linking/digests.js +1 -1
  131. package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +1 -1
  132. package/dist/esm/shared-ts/src/device-linking/parsers.js +2 -2
  133. package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +1 -1
  134. package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -1
  135. package/dist/esm/shared-ts/src/device-linking/wireFields.js +2 -2
  136. package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +1 -1
  137. package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +1 -1
  138. package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +1 -1
  139. package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
  140. package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -1
  141. package/dist/esm/shared-ts/src/wallet-recovery/index.js +3 -3
  142. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
  143. package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +1 -1
  144. package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +1 -1
  145. package/dist/esm/threshold/session/signingSessionSeal/service.js +1 -1
  146. package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +1 -1
  147. package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +1 -1
  148. package/dist/types/shared-ts/src/auth/externalAuth.d.ts +127 -0
  149. package/dist/types/shared-ts/src/authorization/index.d.ts +1 -1
  150. package/dist/types/shared-ts/src/authorization/walletOwnerOperation.d.ts +10 -0
  151. package/dist/types/shared-ts/src/utils/registrationEstablishedSession.d.ts +4 -0
  152. package/dist/types/shared-ts/src/utils/registrationIntent.d.ts +2 -0
  153. package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +1 -1
  154. package/dist/types/wallet-server/src/application-auth.d.ts +3 -0
  155. package/dist/types/wallet-server/src/auth/applicationAuth.d.ts +29 -0
  156. package/dist/types/wallet-server/src/auth/externalAuthService.d.ts +55 -0
  157. package/dist/types/wallet-server/src/auth/externalAuthStore.d.ts +115 -0
  158. package/dist/types/wallet-server/src/auth/externalOwnerOperations.d.ts +18 -0
  159. package/dist/types/wallet-server/src/cloud-host.d.ts +2 -1
  160. package/dist/types/wallet-server/src/core/threeRouteRegistrationContracts.d.ts +12 -0
  161. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.d.ts +5 -1
  162. package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RecordedOwnerOperation.d.ts +16 -0
  163. package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcBoundary.d.ts +5 -0
  164. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.d.ts +1 -0
  165. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetup.d.ts +2 -0
  166. package/dist/types/wallet-server/src/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.d.ts +7 -1
  167. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/authorizationSnapshotLayout.d.ts +1 -1
  168. package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthMethodService.d.ts +1 -0
  169. package/dist/types/wallet-server/src/router/cloudflare/runtime/staticWalletConsoleBinding.d.ts +2 -0
  170. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.d.ts +2 -2
  171. package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +1 -1
  172. package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +1 -0
  173. package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationReservation.d.ts +11 -6
  174. package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +1 -0
  175. package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +12 -0
  176. package/dist/types/wallet-server/src/router/transport/fetch/routes/externalAuth.d.ts +5 -0
  177. package/dist/types/wallet-server/src/router/transport/fetch/walletOwnerOperationAuthorization.d.ts +23 -0
  178. package/migrations/d1-signer/0085_external_wallet_auth.sql +158 -0
  179. package/migrations/d1-signer/0086_application_auth.sql +67 -0
  180. package/migrations/d1-signer/0087_registration_without_session.sql +43 -0
  181. package/package.json +7 -2
  182. package/dist/types/shared-ts/src/authorization/walletCustodyOperation.d.ts +0 -10
package/README.md CHANGED
@@ -4,14 +4,22 @@ This package owns the reusable signer server surface: route adapters,
4
4
  WebAuthn verification policy, threshold signing services, signer storage
5
5
  adapters, and server wasm bindings.
6
6
 
7
- The current published package is `@seams/wallet-server@0.17.0`, checked
8
- October 21, 2026. Pair it with `@seams/wallet@0.17.0` and matching hosted assets.
9
- Use `@seams/wallet-cli@0.17.0`.
7
+ The current release is `@seams/wallet-server@0.29.0`. Pair it with
8
+ `@seams/wallet@0.29.0` and matching hosted assets. Use `@seams/wallet-cli@0.29.0`.
9
+ The wallet iframe protocol is **19.0.0**.
10
10
 
11
11
  ```sh
12
- pnpm add @seams/wallet-server@0.17.0
12
+ pnpm add @seams/wallet-server@0.29.0
13
13
  ```
14
14
 
15
+ ## Google BYO authentication
16
+
17
+ Version 0.29.0 verifies a configured application's signed session assertion or the app's Google ID token or exchanges it for a browser-bound handoff.
18
+ An environment-specific Google client configuration and an owner-approved wallet association are required.
19
+ Apply the packaged signer migrations before enabling the feature.
20
+ External sessions grant settings reads and remain separate from owner and signing credentials.
21
+ See the [Google SSO guide](https://wallet.seams.sh/docs/guides/google-sso) for configuration, backend exchange, and revocation.
22
+
15
23
  ## Supported runtime and entry points
16
24
 
17
25
  The packaged Wallet backend runs on Cloudflare Workers with Durable Objects,
@@ -56,3 +64,10 @@ and [release notes](https://wallet.seams.sh/docs/releases).
56
64
 
57
65
  Hosted product services and their operational tooling live in the private
58
66
  `seams-monorepo` repository.
67
+
68
+
69
+ Use `createApplicationAuthAssertion` from `@seams/wallet-server/application-auth` on the authenticated application backend.
70
+ Configure the issuer and public key through the existing environment trust setting.
71
+ The assertion binds the stable subject, environment, wallet, Seams attempt, purpose, and expiry.
72
+ Fresh wallet-origin owner proof remains required for identity changes and NEAR transactions.
73
+ See the [application-session guide](https://wallet.seams.sh/docs/guides/application-auth).
@@ -3,17 +3,17 @@
3
3
  "walletSecurityPolicy": "scoped_seals_and_owner_proofs_v1",
4
4
  "package": {
5
5
  "name": "@seams/wallet-server",
6
- "version": "0.27.0"
6
+ "version": "0.29.0"
7
7
  },
8
8
  "workers": {
9
9
  "router": {
10
10
  "entry": "cloudflare-router-ab/build/router/worker/shim.mjs",
11
- "fingerprint": "f4d14f9f1a23c8f98f5d12085061337aaf6e80fd79def737d2142527872d29dc",
11
+ "fingerprint": "bc4c3fb74b4869b98d280dff20ea71488b6e41d9de440d10d26b292360243673",
12
12
  "files": [
13
13
  {
14
14
  "path": "cloudflare-router-ab/build/router/build-stamp.json",
15
15
  "bytes": 119,
16
- "sha256": "ed5b9ff7628a165828660dbff6765db796f0a6bd4ca3292805d08a2ade9c9365"
16
+ "sha256": "f1f625e28fd7c2de2ba5d7a5f84ec06d21411d0fcb59a0d6ac687373c4a2a0fd"
17
17
  },
18
18
  {
19
19
  "path": "cloudflare-router-ab/build/router/index.js",
@@ -39,12 +39,12 @@
39
39
  },
40
40
  "deriver-a": {
41
41
  "entry": "cloudflare-router-ab/build/deriver-a/worker/shim.mjs",
42
- "fingerprint": "3ec071d957795f9ff6d0f20a0c5b33e1e5713b777733a2beb68c0b2b1391bcab",
42
+ "fingerprint": "5ed3fc53704436a171fc57434e2ad732eb008cf12f1a30c3c2c0d895aaec2b36",
43
43
  "files": [
44
44
  {
45
45
  "path": "cloudflare-router-ab/build/deriver-a/build-stamp.json",
46
46
  "bytes": 122,
47
- "sha256": "e54fb17f4c621cef06421c00e4d46714210336eb8a740476704bcebeae36f325"
47
+ "sha256": "70c82f021615ac41e7b6e68ec7f64c21ba5202d97463710f3184489c693e5d67"
48
48
  },
49
49
  {
50
50
  "path": "cloudflare-router-ab/build/deriver-a/index.js",
@@ -70,12 +70,12 @@
70
70
  },
71
71
  "deriver-b": {
72
72
  "entry": "cloudflare-router-ab/build/deriver-b/worker/shim.mjs",
73
- "fingerprint": "b56cb2596e6673329b2fc4cbfa7386fc9f4620cc56c3ed6e2485de66ec2bee13",
73
+ "fingerprint": "8861d75c70c0660f85abdb2fb1d5e05f346c0185180de6482c676b16188e1d89",
74
74
  "files": [
75
75
  {
76
76
  "path": "cloudflare-router-ab/build/deriver-b/build-stamp.json",
77
77
  "bytes": 122,
78
- "sha256": "37a251c69a161ada391e28bf6585b512f3074adfef3b160ea6e847bc9fb99b5c"
78
+ "sha256": "01cd377ff0a7934d33794174f1f9ddfe3e274bcf14d850516e3b0482f7593986"
79
79
  },
80
80
  {
81
81
  "path": "cloudflare-router-ab/build/deriver-b/index.js",
@@ -101,12 +101,12 @@
101
101
  },
102
102
  "signing-worker": {
103
103
  "entry": "cloudflare-router-ab/build/signing-worker/worker/shim.mjs",
104
- "fingerprint": "62f97b4156ded53b921aa1f7ff4406c89b08666bb3ba17bca90e2460f5333c87",
104
+ "fingerprint": "c88383e59192e1d8fe7424cd29b4d2045cac3d5fdb6be31770e825ff25c59358",
105
105
  "files": [
106
106
  {
107
107
  "path": "cloudflare-router-ab/build/signing-worker/build-stamp.json",
108
108
  "bytes": 127,
109
- "sha256": "6a85061edaecf85c36190d0fdceac7e0674f74f6646924d21ecc839b23e51505"
109
+ "sha256": "3ed8b25f8604a6d815c5c2f83d82c7775c1d360840ea6f3d58f1335d3ddc0f23"
110
110
  },
111
111
  {
112
112
  "path": "cloudflare-router-ab/build/signing-worker/index.js",
@@ -132,12 +132,12 @@
132
132
  },
133
133
  "tenant-root-control-plane": {
134
134
  "entry": "cloudflare-router-ab/build/tenant-root-control-plane/worker/shim.mjs",
135
- "fingerprint": "c4214e28c3296088b1150f3c56d1fe7536a32dd2e107dc32fe319236cd2cbad5",
135
+ "fingerprint": "87fcae5b88541e0f69333ae632568e286939ec22bf75395d490be3ba6aeb4272",
136
136
  "files": [
137
137
  {
138
138
  "path": "cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json",
139
139
  "bytes": 139,
140
- "sha256": "91362b12400759dc63b6893896e2fca6a9d2f3d3c3dad46fb71354119861119c"
140
+ "sha256": "ff8878e625a5202b8d8607c590a89c2b169ae385c826eb154b5797babb3bf73d"
141
141
  },
142
142
  {
143
143
  "path": "cloudflare-router-ab/build/tenant-root-control-plane/index.js",
@@ -165,8 +165,8 @@
165
165
  "migrations": {
166
166
  "signer": {
167
167
  "directory": "migrations/d1-signer",
168
- "head": "0084_voiceid_wallet_auth_methods.sql",
169
- "fingerprint": "724414d2bc4d41dd761541a0dc465145957275303a1c49610f1fbdc1e60c0316",
168
+ "head": "0087_registration_without_session.sql",
169
+ "fingerprint": "2901c4c1b711fde38af1371311fea9e8ae8133c5cc4f47fc0cd5588e1ddf23aa",
170
170
  "files": [
171
171
  {
172
172
  "path": "migrations/d1-signer/0001_signer_d1_initial.sql",
@@ -587,6 +587,21 @@
587
587
  "path": "migrations/d1-signer/0084_voiceid_wallet_auth_methods.sql",
588
588
  "bytes": 17185,
589
589
  "sha256": "01af96f95131fb6ce8e42301bfdc2bd99ead260c817833b6b03a501f836d34a9"
590
+ },
591
+ {
592
+ "path": "migrations/d1-signer/0085_external_wallet_auth.sql",
593
+ "bytes": 9757,
594
+ "sha256": "62e98c8200f18cc1d6bc399891f2fd7c57e5b0639f251d10ad6cf7d7b5e30461"
595
+ },
596
+ {
597
+ "path": "migrations/d1-signer/0086_application_auth.sql",
598
+ "bytes": 4354,
599
+ "sha256": "a9ecaeec04383536993cb9052aebe188a5035f766fd1ef73b51b9e85736a6bb1"
600
+ },
601
+ {
602
+ "path": "migrations/d1-signer/0087_registration_without_session.sql",
603
+ "bytes": 2906,
604
+ "sha256": "1ed454bb25fa5a9b28567bc1f18aad718c086f8b182255fabe2ee01215292ff3"
590
605
  }
591
606
  ]
592
607
  },
@@ -1 +1 @@
1
- {"profile":"release","wallet_objects":true,"features":"strict-worker-deriver-a-entrypoint","started_at_ms":1793201442665}
1
+ {"profile":"release","wallet_objects":true,"features":"strict-worker-deriver-a-entrypoint","started_at_ms":1793310989490}
@@ -1 +1 @@
1
- {"profile":"release","wallet_objects":true,"features":"strict-worker-deriver-b-entrypoint","started_at_ms":1793201567116}
1
+ {"profile":"release","wallet_objects":true,"features":"strict-worker-deriver-b-entrypoint","started_at_ms":1793311149098}
@@ -1 +1 @@
1
- {"profile":"release","wallet_objects":true,"features":"strict-worker-router-entrypoint","started_at_ms":1793201683620}
1
+ {"profile":"release","wallet_objects":true,"features":"strict-worker-router-entrypoint","started_at_ms":1793311295695}
@@ -1 +1 @@
1
- {"profile":"release","wallet_objects":true,"features":"strict-worker-signing-worker-entrypoint","started_at_ms":1793201252625}
1
+ {"profile":"release","wallet_objects":true,"features":"strict-worker-signing-worker-entrypoint","started_at_ms":1793310743369}
@@ -1 +1 @@
1
- {"profile":"release","wallet_objects":false,"features":"strict-worker-tenant-root-control-plane-entrypoint","started_at_ms":1793201821080}
1
+ {"profile":"release","wallet_objects":false,"features":"strict-worker-tenant-root-control-plane-entrypoint","started_at_ms":1793311468276}
@@ -0,0 +1,2 @@
1
+ import { createApplicationAuthAssertion } from "./auth/applicationAuth.js";
2
+ export { createApplicationAuthAssertion };
@@ -0,0 +1,85 @@
1
+ import { requireCanonicalString, requireRecord } from "../shared-ts/src/utils/validation.js";
2
+ import { base64UrlDecode, base64UrlEncode } from "../shared-ts/src/utils/base64.js";
3
+ import { externalAuthFailure } from "../shared-ts/src/auth/externalAuth.js";
4
+ //#region src/auth/applicationAuth.ts
5
+ const ASSERTION_TTL_MS = 12e4;
6
+ function parseClaims(raw) {
7
+ const value = requireRecord(raw, "application assertion claims");
8
+ if (typeof value.iat !== "number" || typeof value.exp !== "number" || typeof value.sessionExp !== "number") throw new Error("Application assertion timestamps are missing");
9
+ if (!Number.isSafeInteger(value.iat) || !Number.isSafeInteger(value.exp) || !Number.isSafeInteger(value.sessionExp)) throw new Error("Application assertion timestamps must be integer seconds");
10
+ if (value.purpose !== "authenticate" && value.purpose !== "associate") throw new Error("Application assertion purpose is invalid");
11
+ return {
12
+ iss: requireCanonicalString(value.iss, "iss"),
13
+ sub: requireCanonicalString(value.sub, "sub"),
14
+ aud: requireCanonicalString(value.aud, "aud"),
15
+ walletId: requireCanonicalString(value.walletId, "walletId"),
16
+ attemptId: requireCanonicalString(value.attemptId, "attemptId"),
17
+ iat: value.iat,
18
+ exp: value.exp,
19
+ sessionExp: value.sessionExp,
20
+ purpose: value.purpose
21
+ };
22
+ }
23
+ function encodeJson(value) {
24
+ return base64UrlEncode(new TextEncoder().encode(JSON.stringify(value)));
25
+ }
26
+ function decodeJson(value) {
27
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(base64UrlDecode(value)));
28
+ }
29
+ function audience(environmentId) {
30
+ return `seams:external-auth:${environmentId}`;
31
+ }
32
+ /** Called only by the application's authenticated backend with its enrolled issuer key. */
33
+ async function createApplicationAuthAssertion(input) {
34
+ if (input.privateKey.type !== "private" || input.privateKey.algorithm.name !== "Ed25519") throw new Error("Application issuer requires an Ed25519 signing key");
35
+ const claims = parseClaims({
36
+ iss: input.issuer,
37
+ sub: input.subject,
38
+ aud: audience(requireCanonicalString(input.environmentId, "environmentId")),
39
+ walletId: input.walletId,
40
+ attemptId: input.attemptId,
41
+ iat: Math.floor(input.nowMs / 1e3),
42
+ exp: Math.floor(Math.min(input.nowMs + ASSERTION_TTL_MS, input.sessionExpiresAtMs) / 1e3),
43
+ sessionExp: Math.floor(input.sessionExpiresAtMs / 1e3),
44
+ purpose: input.purpose
45
+ });
46
+ const signed = `${encodeJson({
47
+ alg: "EdDSA",
48
+ typ: "JWT"
49
+ })}.${encodeJson(claims)}`;
50
+ return `${signed}.${base64UrlEncode(await crypto.subtle.sign("Ed25519", input.privateKey, new TextEncoder().encode(signed)))}`;
51
+ }
52
+ async function verifyApplicationAuthAssertion(input) {
53
+ try {
54
+ const segments = input.assertion.split(".");
55
+ if (segments.length !== 3) return externalAuthFailure("invalid_credential");
56
+ const [headerText, claimsText, signatureText] = segments;
57
+ if (!headerText || !claimsText || !signatureText) return externalAuthFailure("invalid_credential");
58
+ const header = requireRecord(decodeJson(headerText), "application assertion header");
59
+ if (header.alg !== "EdDSA" || header.typ !== "JWT" || "crit" in header) return externalAuthFailure("invalid_credential");
60
+ const key = await crypto.subtle.importKey("raw", base64UrlDecode(input.trust.publicKeyB64u), "Ed25519", false, ["verify"]);
61
+ if (!await crypto.subtle.verify("Ed25519", key, base64UrlDecode(signatureText), new TextEncoder().encode(`${headerText}.${claimsText}`))) return externalAuthFailure("invalid_credential");
62
+ const claims = parseClaims(decodeJson(claimsText));
63
+ const expiresAtMs = claims.exp * 1e3;
64
+ const issuedAtMs = claims.iat * 1e3;
65
+ if (expiresAtMs <= input.nowMs) return externalAuthFailure("expired");
66
+ if (claims.iss !== input.trust.issuer || claims.aud !== audience(input.environmentId) || claims.walletId !== input.walletId || claims.attemptId !== input.attemptId || claims.purpose !== input.purpose || issuedAtMs > input.nowMs + 3e4 || expiresAtMs <= issuedAtMs || expiresAtMs - issuedAtMs > ASSERTION_TTL_MS || claims.sessionExp < claims.exp) return externalAuthFailure("invalid_credential");
67
+ return {
68
+ ok: true,
69
+ value: {
70
+ identity: {
71
+ provider: "application",
72
+ issuer: claims.iss,
73
+ subject: claims.sub
74
+ },
75
+ expiresAtMs: claims.sessionExp * 1e3
76
+ }
77
+ };
78
+ } catch {
79
+ return externalAuthFailure("invalid_credential");
80
+ }
81
+ }
82
+ //#endregion
83
+ export { createApplicationAuthAssertion, verifyApplicationAuthAssertion };
84
+
85
+ //# sourceMappingURL=applicationAuth.js.map
@@ -0,0 +1,149 @@
1
+ import { base64UrlEncode } from "../shared-ts/src/utils/base64.js";
2
+ import { sha256HexUtf8 } from "../shared-ts/src/utils/digests.js";
3
+ import { externalAuthFailure } from "../shared-ts/src/auth/externalAuth.js";
4
+ import { verifyApplicationAuthAssertion } from "./applicationAuth.js";
5
+ import { verifyGoogleOidcToken } from "../router/cloudflare/d1/oidc/googleOidcToken.js";
6
+ //#region src/auth/externalAuthService.ts
7
+ var ExternalAuthService = class {
8
+ constructor(store, wallets, methods) {
9
+ this.store = store;
10
+ this.wallets = wallets;
11
+ this.methods = methods;
12
+ }
13
+ async verifyGoogle(trust, idToken) {
14
+ const proof = await verifyGoogleOidcToken(trust.clientId, idToken);
15
+ if (!proof.ok) return externalAuthFailure(proof.code === "expired" ? "expired" : "invalid_credential");
16
+ if (proof.audienceCount > 1 && proof.authorizedParty === null || proof.authorizedParty !== null && proof.authorizedParty !== trust.clientId) return externalAuthFailure("invalid_credential");
17
+ return {
18
+ ok: true,
19
+ value: {
20
+ identity: {
21
+ provider: "google",
22
+ issuer: "https://accounts.google.com",
23
+ subject: proof.sub
24
+ },
25
+ expiresAtMs: proof.expiresAtMs
26
+ }
27
+ };
28
+ }
29
+ async prepare(input) {
30
+ const attemptId = crypto.randomUUID();
31
+ const expiresAtMs = Date.now() + 12e4;
32
+ await this.store.prepareAttempt({
33
+ purpose: input.purpose,
34
+ attemptId,
35
+ walletId: input.walletId,
36
+ originBinding: input.originBinding,
37
+ bindingHash: await sha256HexUtf8(input.binding),
38
+ sessionTokenHash: await sha256HexUtf8(input.sessionToken),
39
+ expiresAtMs
40
+ });
41
+ return {
42
+ ok: true,
43
+ value: {
44
+ purpose: input.purpose,
45
+ attemptId,
46
+ walletId: input.walletId,
47
+ expiresAtMs
48
+ }
49
+ };
50
+ }
51
+ async exchange(input) {
52
+ const purpose = await this.store.readPreparedPurpose(input.walletId, input.attemptId, Date.now());
53
+ if (purpose === null) return externalAuthFailure("access_denied");
54
+ const verified = await this.verifyIdentity({
55
+ trust: input.trust,
56
+ proof: input.proof,
57
+ walletId: input.walletId,
58
+ attemptId: input.attemptId,
59
+ purpose
60
+ });
61
+ if (!verified.ok) return verified;
62
+ const code = base64UrlEncode(crypto.getRandomValues(new Uint8Array(32)));
63
+ const nowMs = Date.now();
64
+ return await this.store.verifyAttempt({
65
+ attemptId: input.attemptId,
66
+ walletId: input.walletId,
67
+ identity: verified.value.identity,
68
+ trust: input.trust,
69
+ codeHash: await sha256HexUtf8(code),
70
+ nowMs,
71
+ sessionExpiresAtMs: Math.min(nowMs + 36e5, verified.value.expiresAtMs),
72
+ purpose
73
+ }) ? {
74
+ ok: true,
75
+ value: { code }
76
+ } : externalAuthFailure("access_denied");
77
+ }
78
+ async prepareUnlink(input) {
79
+ const attemptId = crypto.randomUUID();
80
+ const code = base64UrlEncode(crypto.getRandomValues(new Uint8Array(32)));
81
+ const expiresAtMs = Date.now() + 12e4;
82
+ return await this.store.prepareUnlink({
83
+ walletId: input.walletId,
84
+ associationId: input.associationId,
85
+ attemptId,
86
+ originBinding: input.originBinding,
87
+ bindingHash: await sha256HexUtf8(input.binding),
88
+ sessionTokenHash: await sha256HexUtf8(input.sessionToken),
89
+ codeHash: await sha256HexUtf8(code),
90
+ expiresAtMs,
91
+ trustRevision: input.trustRevision
92
+ }) ? {
93
+ ok: true,
94
+ value: {
95
+ attemptId,
96
+ code,
97
+ expiresAtMs
98
+ }
99
+ } : externalAuthFailure("access_denied");
100
+ }
101
+ async verifyIdentity(input) {
102
+ if (input.trust.kind === "google" && input.proof.kind === "google") return this.verifyGoogle(input.trust, input.proof.idToken);
103
+ if (input.trust.kind === "application" && input.proof.kind === "application") return verifyApplicationAuthAssertion({
104
+ trust: input.trust,
105
+ assertion: input.proof.assertion,
106
+ environmentId: this.store.scope.envId,
107
+ walletId: input.walletId,
108
+ attemptId: input.attemptId,
109
+ nowMs: Date.now(),
110
+ purpose: input.purpose
111
+ });
112
+ return externalAuthFailure("invalid_credential");
113
+ }
114
+ async settings(authentication) {
115
+ const walletId = authentication.walletId;
116
+ const [ed25519, ecdsa, methods, devices] = await Promise.all([
117
+ this.wallets.listEd25519SignersForWallet({ walletId }),
118
+ this.wallets.listEcdsaSignersForWallet({ walletId }),
119
+ this.methods.listForWalletV2({ walletId }),
120
+ this.store.devices(walletId)
121
+ ]);
122
+ const accounts = [];
123
+ for (const signer of ed25519) accounts.push({
124
+ family: "ed25519",
125
+ address: signer.nearAccountId,
126
+ publicKey: signer.publicKey
127
+ });
128
+ for (const signer of ecdsa) accounts.push({
129
+ family: "ecdsa",
130
+ address: signer.walletKey.thresholdOwnerAddress,
131
+ publicKey: signer.walletKey.thresholdEcdsaPublicKeyB64u
132
+ });
133
+ const summaries = [];
134
+ for (const method of methods) if (method.status === "active") summaries.push({
135
+ id: method.walletAuthMethodId,
136
+ kind: method.kind
137
+ });
138
+ return {
139
+ authentication,
140
+ accounts,
141
+ methods: summaries,
142
+ devices
143
+ };
144
+ }
145
+ };
146
+ //#endregion
147
+ export { ExternalAuthService };
148
+
149
+ //# sourceMappingURL=externalAuthService.js.map