-
Notifications
You must be signed in to change notification settings - Fork 0
Security Privacy and Reliability
James Daley edited this page Jun 18, 2026
·
3 revisions
Forsetti's security model is based on explicit capabilities, host-owned services, entitlement gates, registration records, runtime requirements, and bounded module communication.
flowchart LR
Module["Module"] --> Context["ForsettiContext"]
Context --> Services["Host-owned services"]
Context --> EventBus["Event bus"]
Context --> Logger["Logger"]
Context --> Router["Overlay router"]
Host["Host app"] --> Policy["Capability and entitlement policy"]
Host --> Registration["RegistrationStore"]
Policy --> Runtime["Runtime activation"]
Registration --> Runtime
Runtime --> Module
Modules are not trusted with arbitrary host access. They receive the capabilities and services the host chooses to expose.
| Area | Practice |
|---|---|
| Capabilities | Request only the capabilities the module actually needs. |
| Runtime requirements | Declare required I/O, UI IDs, data isolation, and provider roles before activation. |
| Registration records | Treat manifest drift as a deployment signal, not as a recoverable runtime guess. |
| Entitlements | Treat iapProductID as activation policy, not display state. |
| Services | Resolve protocols from ForsettiContext; do not reach into host internals. |
| Secure storage | Use KeychainSecureStorageService through default platform services for production. Keep InMemorySecureStorageService for explicit tests/debug wiring only. |
| File export | Treat suggested filenames as untrusted input; LocalFileExportService sanitizes names and writes inside its configured directory. |
| Events | Avoid sensitive payloads in broad framework events. |
| Logging | Do not log secrets, purchase tokens, or user-sensitive data. |
flowchart TD
Event["Module event or telemetry"] --> Review{"Contains user-sensitive data?"}
Review -- yes --> Minimize["Remove or minimize payload"]
Review -- no --> Policy{"Host telemetry policy allows it?"}
Minimize --> Policy
Policy -- yes --> Track["Track through TelemetryService"]
Policy -- no --> Drop["Do not emit"]
Telemetry is a host-owned decision. Modules should describe intent through service protocols and avoid embedding analytics vendors.
| Concern | Guidance |
|---|---|
| Cold start | Keep manifests small and module start(context:) fast. |
| Large module counts | Prefer service modules for shared background work and keep UI module discovery deterministic. |
| Offline entitlements | StoreKit can use local entitlement state; design paid modules to handle temporary refresh delays. |
| Activation failures | Fail before start(context:) when registration, compatibility, entitlements, capabilities, or runtime requirements are invalid. |
| Deactivation | Implement stop(context:) idempotently and release module-owned resources. |
| UI composition | Keep view injection slots stable and avoid expensive work during surface rebuilds. |
flowchart LR
Manifest["Manifest"] --> Registration["Registration check"]
Registration --> EarlyFail["Early activation failure"]
Requirement["Runtime requirements"] --> EarlyFail
Entitlement["Entitlement"] --> EarlyFail
Registry["Registry"] --> Start["start(context)"]
Start --> Success["Active module"]
Start --> Failure["Rollback and log"]
Success --> EntitlementChange["Entitlement change"]
EntitlementChange --> Reconcile["Deactivate if no longer unlocked"]
- Capability list reviewed for each module.
- Runtime requirements reviewed for service, UI, data isolation, and default-role dependencies.
- Registration store behavior is verified for the app deployment model.
- Entitlement provider is production-appropriate for the target platform.
- Debug unlock providers are not used in release builds.
- Sensitive services are host-owned and backed by production storage.
- File export paths cannot escape the configured export directory.
- Module
start(context:)andstop(context:)are idempotent. - Logs avoid user-sensitive payloads.
- Runtime failure paths have tests.