epistery 1.3.2 → 1.3.3

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 (48) hide show
  1. package/MobileIdentity.md +222 -0
  2. package/artifacts/build-info/4b5aa62ad21f91b268d8ca803f49dd33.json +1 -0
  3. package/artifacts/contracts/IdentityContract.sol/IdentityContract.dbg.json +1 -1
  4. package/artifacts/contracts/agent.sol/Agent.dbg.json +1 -1
  5. package/artifacts/contracts/agent.sol/Agent.json +2 -7
  6. package/cli/epistery.mjs +1 -1
  7. package/contracts/agent.sol +2 -3
  8. package/dist/epistery.d.ts.map +1 -1
  9. package/dist/epistery.js +21 -6
  10. package/dist/epistery.js.map +1 -1
  11. package/dist/utils/CliWallet.js +1 -1
  12. package/dist/utils/CliWallet.js.map +1 -1
  13. package/dist/utils/Utils.d.ts +1 -1
  14. package/dist/utils/Utils.d.ts.map +1 -1
  15. package/dist/utils/Utils.js +2 -2
  16. package/dist/utils/Utils.js.map +1 -1
  17. package/hardhat.config.js +2 -1
  18. package/index.mjs +6 -8
  19. package/package.json +1 -1
  20. package/src/epistery.ts +18 -6
  21. package/src/utils/CliWallet.ts +1 -1
  22. package/src/utils/Utils.ts +2 -2
  23. package/artifacts/build-info/77fa7a8b1d8980b54997e3a44ae9801d.json +0 -1
  24. package/artifacts/build-info/d543a0323a7b2da80b60c3056668fbde.json +0 -1
  25. package/dist/api.d.ts +0 -2
  26. package/dist/api.d.ts.map +0 -1
  27. package/dist/api.js +0 -130
  28. package/dist/api.js.map +0 -1
  29. package/dist/controllers/baseController.d.ts +0 -8
  30. package/dist/controllers/baseController.d.ts.map +0 -1
  31. package/dist/controllers/baseController.js +0 -25
  32. package/dist/controllers/baseController.js.map +0 -1
  33. package/dist/controllers/create/CreateController.d.ts +0 -6
  34. package/dist/controllers/create/CreateController.d.ts.map +0 -1
  35. package/dist/controllers/create/CreateController.js +0 -17
  36. package/dist/controllers/create/CreateController.js.map +0 -1
  37. package/dist/controllers/ssl/SSLController.d.ts +0 -17
  38. package/dist/controllers/ssl/SSLController.d.ts.map +0 -1
  39. package/dist/controllers/ssl/SSLController.js +0 -129
  40. package/dist/controllers/ssl/SSLController.js.map +0 -1
  41. package/dist/controllers/status/StatusController.d.ts +0 -6
  42. package/dist/controllers/status/StatusController.d.ts.map +0 -1
  43. package/dist/controllers/status/StatusController.js +0 -29
  44. package/dist/controllers/status/StatusController.js.map +0 -1
  45. package/dist/controllers/write/WriteController.d.ts +0 -7
  46. package/dist/controllers/write/WriteController.d.ts.map +0 -1
  47. package/dist/controllers/write/WriteController.js +0 -50
  48. package/dist/controllers/write/WriteController.js.map +0 -1
@@ -0,0 +1,222 @@
1
+ # Mobile Identity: Platform Restrictions and Strategic Implications
2
+
3
+ ## The Problem
4
+
5
+ Safari's Intelligent Tracking Prevention (ITP) deletes localStorage and IndexedDB data after 7 days of no user interaction with a site. This policy, introduced in Safari 13.1 (March 2020), is framed as a privacy protection but has significant implications for decentralized identity systems.
6
+
7
+ Epistery uses non-extractable CryptoKeys stored in IndexedDB to create device-locked wallets ("rivets"). These keys never leave the device and cannot be extracted even via XSS attacks. On iOS Safari, Apple purges these keys after 7 days of inactivity.
8
+
9
+ ## The Security Tradeoff
10
+
11
+ Because Apple will not allow persistent secure storage, iOS users cannot benefit from the same security model as Android and desktop users.
12
+
13
+ | Platform | Key Storage | Security Property |
14
+ |----------|-------------|-------------------|
15
+ | Android/Desktop | Non-extractable CryptoKey in IndexedDB | Private key **never** leaves device, immune to XSS extraction |
16
+ | iOS Safari | Extractable key, server-escrowed | Key exists on server (encrypted), theoretically extractable |
17
+
18
+ This is not a design choice. It is a forced degradation. To maintain continuity for iOS users, Epistery must backup keys to the server, fundamentally weakening the security model.
19
+
20
+ **Implementation consequence:**
21
+
22
+ ```javascript
23
+ const isIOSSafari = /iPad|iPhone|iPod/.test(navigator.userAgent) &&
24
+ !window.MSStream &&
25
+ /Safari/.test(navigator.userAgent);
26
+
27
+ if (isIOSSafari) {
28
+ // BrowserWallet with server escrow - extractable, less secure
29
+ // Because Apple won't let us keep non-extractable keys
30
+ } else {
31
+ // RivetWallet - non-extractable, device-locked, actually private
32
+ }
33
+ ```
34
+
35
+ ## The FIDO/Passkey Double Standard
36
+
37
+ Apple, Google, and Microsoft control the FIDO Alliance, which develops the WebAuthn/Passkey standards. These passkeys receive special treatment that third-party cryptographic keys do not.
38
+
39
+ ### Storage Comparison
40
+
41
+ | Credential Type | Where Stored | Subject to ITP? |
42
+ |----------------|--------------|-----------------|
43
+ | Web Crypto API keys (non-extractable) | IndexedDB | **YES** - purged after 7 days |
44
+ | FIDO Passkeys | Secure Enclave + iCloud Keychain | **NO** - OS-level, persists indefinitely |
45
+
46
+ Both are conceptually "device-bound credentials." Both use hardware security features. The difference is control.
47
+
48
+ ### ITP Scope
49
+
50
+ From Apple's documentation, ITP targets "script-writable storage":
51
+ - localStorage
52
+ - IndexedDB
53
+ - Cookies set via JavaScript
54
+
55
+ Passkeys are stored at the OS level (Secure Enclave) and synced via iCloud Keychain. They are explicitly outside the browser sandbox and therefore exempt from ITP purging.
56
+
57
+ ### FIDO Alliance Control
58
+
59
+ The FIDO Alliance was founded in 2013 and now comprises 250+ members. However, board-level control rests with:
60
+ - Google
61
+ - Apple
62
+ - Microsoft
63
+ - Amazon
64
+ - Meta
65
+
66
+ These companies "led development of this expanded set of capabilities and are now building support into their respective platforms." The standard claims decentralization ("PII stays on device"), but the sync mechanism routes through their clouds (iCloud Keychain, Google Account, Microsoft Account).
67
+
68
+ ## The Architecture of Control
69
+
70
+ 1. **Web Crypto API** allows developers to create non-extractable keys that never leave the device
71
+ 2. **Apple purges these keys** via ITP after 7 days of inactivity
72
+ 3. **Passkeys** are also device-bound cryptographic credentials
73
+ 4. **Apple preserves passkeys** indefinitely and syncs them via iCloud
74
+
75
+ The technical difference? Passkeys live in Apple-controlled infrastructure. Developer-created keys do not.
76
+
77
+ This is not a privacy measure. It is a competitive moat. The W3C WebAuthn working group has acknowledged this tension - see [Issue #1569: Prevent browsers from deleting credentials that the RP wanted to be server-side](https://github.com/w3c/webauthn/issues/1569).
78
+
79
+ ## Strategic Implications for Epistery
80
+
81
+ ### The Messaging Opportunity
82
+
83
+ Apple's "privacy" policies force less private implementations:
84
+
85
+ > "On Android and desktop, your Epistery wallet keys never leave your device. On iOS, Apple's storage policies require server backup, making your keys objectively less secure. Apple claims this is for privacy while their own passkey credentials - also device-bound keys - are exempt and sync through iCloud. The difference is control: they purge your secure keys while preserving theirs."
86
+
87
+ This is factual, documentable, and inverts Apple's privacy narrative.
88
+
89
+ ### The Multi-Domain Advantage
90
+
91
+ Epistery's architecture provides some resilience:
92
+
93
+ - Each publisher domain runs its own Epistery instance (first-party context)
94
+ - Chain verification is the shared layer, not browser storage
95
+ - There is no single `epistery.com` domain to classify as a tracker
96
+ - ITP's cross-site tracking heuristics don't easily apply
97
+
98
+ ### Recovery Mechanisms
99
+
100
+ The Identity Contract provides a path forward:
101
+
102
+ 1. **First device/site**: Creates invisible rivet, registers on-chain
103
+ 2. **Additional devices**: Authorized by existing device via multi-sig
104
+ 3. **Recovery after iOS purge (with other devices live)**: Invisible re-authorization
105
+ 4. **Recovery with no devices live**: One-time re-affirmation required
106
+
107
+ Server-set httpOnly cookies (not subject to the same ITP rules as script-writable storage) can bridge the gap by maintaining an encrypted pointer to the user's chain identity.
108
+
109
+ ## FidoWallet Integration
110
+
111
+ Rather than fight the platform, use its tools. FIDO/WebAuthn credentials persist because Apple blesses them. By integrating FidoWallet as a third wallet type alongside RivetWallet and Web3Wallet, Epistery can leverage platform-blessed persistence while maintaining the on-chain identity as the sovereign anchor.
112
+
113
+ ### Wallet Type Comparison
114
+
115
+ | Wallet Type | Key Location | Persistence | User Experience | iOS Safari |
116
+ |-------------|--------------|-------------|-----------------|------------|
117
+ | **RivetWallet** | IndexedDB (non-extractable) | Fragile (ITP purge) | Invisible | Unreliable |
118
+ | **Web3Wallet** | MetaMask / external | Persistent | Popup on connect + each sign | Works |
119
+ | **FidoWallet** | Secure Enclave | Persistent | One biometric touch | **Reliable** |
120
+
121
+ ### User Experience Flow
122
+
123
+ **First visit (registration):**
124
+ 1. User triggers "Secure this device" (prompted or via status page)
125
+ 2. Single biometric touch (Face ID / Touch ID / fingerprint)
126
+ 3. WebAuthn credential created, stored in Secure Enclave
127
+ 4. Epistery stores credential ID + public key server-side, tied to session or chain identity
128
+
129
+ **Return visit (authentication):**
130
+ 1. Server sees session cookie, knows user has FIDO credential
131
+ 2. Requests WebAuthn assertion
132
+ 3. Single biometric touch
133
+ 4. Session re-established
134
+
135
+ **Recovery after iOS purge:**
136
+ - Cookie survives (server-set httpOnly, not subject to ITP)
137
+ - One touch to re-authenticate
138
+ - New rivet created and linked to existing Identity Contract
139
+ - Chain state intact, local key reconstructed
140
+
141
+ ### UX Comparison by Scenario
142
+
143
+ | Scenario | RivetWallet | Web3Wallet | FidoWallet |
144
+ |----------|-------------|------------|------------|
145
+ | First visit | Invisible | Popup + approve | One touch |
146
+ | Return (storage intact) | Invisible | Reconnect popup | Invisible (cookie) |
147
+ | Return (storage purged) | **Broken** | Reconnect popup | One touch |
148
+ | Sign operation | Invisible | Popup each time | Invisible (rivet signs) |
149
+ | iOS Safari | Unreliable | Works (external app) | **Reliable** |
150
+
151
+ FidoWallet is less intrusive than Web3Wallet while providing the persistence that RivetWallet lacks on iOS.
152
+
153
+ ### The Curve Problem
154
+
155
+ FIDO uses P-256 (secp256r1). Ethereum uses secp256k1. Direct on-chain signature verification requires reconciliation:
156
+
157
+ | Approach | Tradeoff |
158
+ |----------|----------|
159
+ | **Account abstraction (ERC-4337)** | Smart contract wallets can verify P-256, adds complexity |
160
+ | **FIDO as auth, rivet for signing** | FIDO proves identity, authorizes secp256k1 rivet for chain ops |
161
+ | **PRF-derived key** | Derive secp256k1 from passkey, but extractable |
162
+
163
+ **Recommended architecture:** FIDO as the persistence/recovery anchor, rivet as the signing key.
164
+
165
+ This mirrors the Web3Wallet model:
166
+ - MetaMask holds keys externally, Epistery requests signatures
167
+ - FIDO holds credential externally, Epistery uses it to authorize rivets
168
+
169
+ The FIDO credential proves "I am this user" to the server. The server trusts the FIDO-authenticated session to authorize rivet keys. Those rivets do the actual chain signing.
170
+
171
+ ### Server Configuration
172
+
173
+ The epistery host already decides which wallet types to accept. FidoWallet becomes a third option:
174
+
175
+ ```
176
+ Wallet types accepted by publisher:
177
+ ├── RivetWallet (device-locked, invisible, iOS-fragile)
178
+ ├── Web3Wallet (external, persistent, popup-heavy)
179
+ └── FidoWallet (platform-blessed, one-touch, persistent)
180
+ ```
181
+
182
+ Server config example: `acceptWallets: ['rivet', 'fido']` or `['fido', 'web3']`
183
+
184
+ ### Status Page Integration
185
+
186
+ The status page at `/.well-known/epistery/status` already allows users to manage wallet selection. FidoWallet credentials would appear alongside existing options, letting power users manage their constellation of keys across the Identity Contract.
187
+
188
+ ### Strategic Position
189
+
190
+ Using FIDO means accepting Apple/Google's infrastructure for credential persistence. However:
191
+
192
+ 1. **The FIDO server is independent** - Epistery runs its own relying party, no platform servers in the auth flow
193
+ 2. **The Identity Contract remains sovereign** - On-chain identity is the anchor, FIDO is a convenience bridge
194
+ 3. **Users can extricate further** - Add more devices, hardware keys, full self-custody at their own pace
195
+ 4. **Playing by their rules** - FIDO is an open standard; using it is legitimate, not an exploit
196
+
197
+ The gesture is heavier than invisible rivet creation, but lighter than MetaMask, and it survives the iOS purge.
198
+
199
+ ## Conclusion
200
+
201
+ The mobile identity landscape is shaped by platform vendors who have constructed privacy policies that handicap alternatives while exempting their own infrastructure. iOS Safari's localStorage purging is not a neutral privacy measure - it is a selective restriction that degrades third-party security while preserving first-party (Apple-controlled) credential persistence.
202
+
203
+ Epistery's response:
204
+
205
+ 1. **Document the tradeoff** - iOS users get weaker security, and they should know why
206
+ 2. **Implement graceful degradation** - Server escrow for iOS, full device-lock for others
207
+ 3. **Leverage on-chain identity** - The chain is the persistent layer; local storage is reconstructible
208
+ 4. **Build the coalition** - Every publisher using Epistery has incentive to amplify this message
209
+
210
+ The monopolies assume identity lives in their silos. Epistery puts identity on-chain, making their storage sabotage an inconvenience rather than a kill switch.
211
+
212
+ ---
213
+
214
+ ## Sources
215
+
216
+ - [Apple: About the security of passkeys](https://support.apple.com/en-us/102195)
217
+ - [Apple: Expanded support for FIDO standard (2022)](https://www.apple.com/newsroom/2022/05/apple-google-and-microsoft-commit-to-expanded-support-for-fido-standard/)
218
+ - [FIDO Alliance - Wikipedia](https://en.wikipedia.org/wiki/FIDO_Alliance)
219
+ - [W3C WebAuthn Issue #1569: Credential deletion](https://github.com/w3c/webauthn/issues/1569)
220
+ - [Corbado: Passkeys & WebAuthn PRF for E2E Encryption](https://www.corbado.com/blog/passkeys-prf-webauthn)
221
+ - [Didomi: Apple 7-Day Cap on Script-Writable Storage](https://support.didomi.io/apple-adds-a-7-day-cap-on-all-script-writable-storage)
222
+ - [Safari ITP Current Status - cookiestatus.com](https://www.cookiestatus.com/safari/)