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.
- package/MobileIdentity.md +222 -0
- package/artifacts/build-info/4b5aa62ad21f91b268d8ca803f49dd33.json +1 -0
- package/artifacts/contracts/IdentityContract.sol/IdentityContract.dbg.json +1 -1
- package/artifacts/contracts/agent.sol/Agent.dbg.json +1 -1
- package/artifacts/contracts/agent.sol/Agent.json +2 -7
- package/cli/epistery.mjs +1 -1
- package/contracts/agent.sol +2 -3
- package/dist/epistery.d.ts.map +1 -1
- package/dist/epistery.js +21 -6
- package/dist/epistery.js.map +1 -1
- package/dist/utils/CliWallet.js +1 -1
- package/dist/utils/CliWallet.js.map +1 -1
- package/dist/utils/Utils.d.ts +1 -1
- package/dist/utils/Utils.d.ts.map +1 -1
- package/dist/utils/Utils.js +2 -2
- package/dist/utils/Utils.js.map +1 -1
- package/hardhat.config.js +2 -1
- package/index.mjs +6 -8
- package/package.json +1 -1
- package/src/epistery.ts +18 -6
- package/src/utils/CliWallet.ts +1 -1
- package/src/utils/Utils.ts +2 -2
- package/artifacts/build-info/77fa7a8b1d8980b54997e3a44ae9801d.json +0 -1
- package/artifacts/build-info/d543a0323a7b2da80b60c3056668fbde.json +0 -1
- package/dist/api.d.ts +0 -2
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -130
- package/dist/api.js.map +0 -1
- package/dist/controllers/baseController.d.ts +0 -8
- package/dist/controllers/baseController.d.ts.map +0 -1
- package/dist/controllers/baseController.js +0 -25
- package/dist/controllers/baseController.js.map +0 -1
- package/dist/controllers/create/CreateController.d.ts +0 -6
- package/dist/controllers/create/CreateController.d.ts.map +0 -1
- package/dist/controllers/create/CreateController.js +0 -17
- package/dist/controllers/create/CreateController.js.map +0 -1
- package/dist/controllers/ssl/SSLController.d.ts +0 -17
- package/dist/controllers/ssl/SSLController.d.ts.map +0 -1
- package/dist/controllers/ssl/SSLController.js +0 -129
- package/dist/controllers/ssl/SSLController.js.map +0 -1
- package/dist/controllers/status/StatusController.d.ts +0 -6
- package/dist/controllers/status/StatusController.d.ts.map +0 -1
- package/dist/controllers/status/StatusController.js +0 -29
- package/dist/controllers/status/StatusController.js.map +0 -1
- package/dist/controllers/write/WriteController.d.ts +0 -7
- package/dist/controllers/write/WriteController.d.ts.map +0 -1
- package/dist/controllers/write/WriteController.js +0 -50
- 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/)
|