@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.
- package/README.md +19 -4
- package/artifact-manifest.json +28 -13
- package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
- package/dist/esm/application-auth.js +2 -0
- package/dist/esm/auth/applicationAuth.js +85 -0
- package/dist/esm/auth/externalAuthService.js +149 -0
- package/dist/esm/auth/externalAuthStore.js +353 -0
- package/dist/esm/auth/externalOwnerOperations.js +82 -0
- package/dist/esm/authorization/domain.js +2 -2
- package/dist/esm/authorization/factorEvidence.js +1 -1
- package/dist/esm/authorization/service.js +2 -2
- package/dist/esm/authorization/vaultProxyUse.js +1 -1
- package/dist/esm/cloud-host.js +12 -11
- package/dist/esm/core/ThresholdService/validation.js +1 -1
- package/dist/esm/core/WebAuthnCredentialBindingStore.js +1 -1
- package/dist/esm/core/authService/webauthn.js +1 -1
- package/dist/esm/core/d1EcdsaSignerRead.js +1 -1
- package/dist/esm/core/d1WalletAuthMethodStore.js +2 -2
- package/dist/esm/core/d1WalletStore.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceManagement.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -2
- package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -2
- package/dist/esm/hosted-wallet-gateway.js +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/router/auth/webAuthnCredentialCodecs.js +1 -1
- package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +2 -0
- package/dist/esm/router/cloudflare/d1/auth/d1RecordedOwnerOperation.js +43 -0
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +27 -3
- package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +3 -3
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSourceContributionPreparationPlanner.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetAuthenticatorStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetPlanner.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkBuilder.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkSourceReader.js +1 -1
- package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +2 -2
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +3 -3
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +3 -3
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +7 -1
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +1 -1
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -4
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +4 -4
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +1 -1
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +3 -3
- package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +11 -2
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletExecutionAuthority.js +9 -16
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +46 -4
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetup.js +12 -0
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +1 -0
- package/dist/esm/router/cloudflare/d1/registration/registrationCompletionWrite.js +1 -0
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +36 -1
- package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/authorizationSnapshotLayout.js +1 -0
- package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdWalletSessionChallenges.js +2 -2
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodBoundary.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodRevocationReplayStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +6 -5
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationCleanup.js +2 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationIntake.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationSnapshot.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationChallenges.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationOwnerRequest.js +2 -2
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +2 -2
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +2 -2
- package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +9 -0
- package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +6 -0
- package/dist/esm/router/cloudflare-adaptor.js +1 -1
- package/dist/esm/router/cloudflare.js +6139 -5567
- package/dist/esm/router/domains/ecdsa/routerAbEcdsaStrictRegistration.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +5 -5
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js +2 -2
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoHttpRegistrationBackend.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistration.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +1 -1
- package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +2 -2
- package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +1 -1
- package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +2 -2
- package/dist/esm/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.js +37 -3
- package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -1
- package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +1 -1
- package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +18 -3
- package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +12 -4
- package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +3 -3
- package/dist/esm/router/framework/http.js +1 -1
- package/dist/esm/router/framework/routeDefinitions.js +2 -1
- package/dist/esm/router/transport/fetch/createFetchRouter.js +5 -3
- package/dist/esm/router/transport/fetch/routes/auth.js +1 -1
- package/dist/esm/router/transport/fetch/routes/deviceLinking.js +3 -3
- package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
- package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +3 -3
- package/dist/esm/router/transport/fetch/routes/externalAuth.js +351 -0
- package/dist/esm/router/transport/fetch/routes/normalSigningRouterProxy.js +1 -1
- package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +46 -306
- package/dist/esm/router/transport/fetch/routes/sessions.js +4 -4
- package/dist/esm/router/transport/fetch/routes/syncAccount.js +2 -2
- package/dist/esm/router/transport/fetch/routes/syncAccountBootstrap.js +1 -1
- package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +4 -4
- package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +6 -6
- package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +2 -2
- package/dist/esm/router/transport/fetch/routes/walletRegistration.js +4 -4
- package/dist/esm/router/transport/fetch/walletOwnerOperationAuthorization.js +306 -0
- package/dist/esm/shared-ts/src/auth/externalAuth.js +118 -0
- package/dist/esm/shared-ts/src/authorization/index.js +1 -1
- package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +1 -1
- package/dist/esm/shared-ts/src/authorization/walletAuthority.js +2 -2
- package/dist/esm/shared-ts/src/authorization/{walletCustodyOperation.js → walletOwnerOperation.js} +4 -4
- package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/digests.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/parsers.js +2 -2
- package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/wireFields.js +2 -2
- package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +1 -1
- package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +1 -1
- package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +1 -1
- package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
- package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -1
- package/dist/esm/shared-ts/src/wallet-recovery/index.js +3 -3
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/service.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +1 -1
- package/dist/types/shared-ts/src/auth/externalAuth.d.ts +127 -0
- package/dist/types/shared-ts/src/authorization/index.d.ts +1 -1
- package/dist/types/shared-ts/src/authorization/walletOwnerOperation.d.ts +10 -0
- package/dist/types/shared-ts/src/utils/registrationEstablishedSession.d.ts +4 -0
- package/dist/types/shared-ts/src/utils/registrationIntent.d.ts +2 -0
- package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +1 -1
- package/dist/types/wallet-server/src/application-auth.d.ts +3 -0
- package/dist/types/wallet-server/src/auth/applicationAuth.d.ts +29 -0
- package/dist/types/wallet-server/src/auth/externalAuthService.d.ts +55 -0
- package/dist/types/wallet-server/src/auth/externalAuthStore.d.ts +115 -0
- package/dist/types/wallet-server/src/auth/externalOwnerOperations.d.ts +18 -0
- package/dist/types/wallet-server/src/cloud-host.d.ts +2 -1
- package/dist/types/wallet-server/src/core/threeRouteRegistrationContracts.d.ts +12 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.d.ts +5 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RecordedOwnerOperation.d.ts +16 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcBoundary.d.ts +5 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.d.ts +1 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetup.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.d.ts +7 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/authorizationSnapshotLayout.d.ts +1 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthMethodService.d.ts +1 -0
- package/dist/types/wallet-server/src/router/cloudflare/runtime/staticWalletConsoleBinding.d.ts +2 -0
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.d.ts +2 -2
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +1 -1
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +1 -0
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationReservation.d.ts +11 -6
- package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +1 -0
- package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +12 -0
- package/dist/types/wallet-server/src/router/transport/fetch/routes/externalAuth.d.ts +5 -0
- package/dist/types/wallet-server/src/router/transport/fetch/walletOwnerOperationAuthorization.d.ts +23 -0
- package/migrations/d1-signer/0085_external_wallet_auth.sql +158 -0
- package/migrations/d1-signer/0086_application_auth.sql +67 -0
- package/migrations/d1-signer/0087_registration_without_session.sql +43 -0
- package/package.json +7 -2
- 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
|
|
8
|
-
|
|
9
|
-
|
|
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.
|
|
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).
|
package/artifact-manifest.json
CHANGED
|
@@ -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.
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
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": "
|
|
169
|
-
"fingerprint": "
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
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":
|
|
1
|
+
{"profile":"release","wallet_objects":false,"features":"strict-worker-tenant-root-control-plane-entrypoint","started_at_ms":1793311468276}
|
|
@@ -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
|