Skip to content

Security Privacy and Reliability

Jim Daley edited this page May 1, 2026 · 3 revisions

Security, Privacy, and Reliability

Forsetti's security model is based on explicit capabilities, host-owned services, entitlement gates, and bounded module communication.

Trust Boundary Map

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"]
    Policy --> Runtime["Runtime activation"]
    Runtime --> Module
Loading

Modules are not trusted with arbitrary host access. They receive the capabilities and services the host chooses to expose.

Security Practices

Area Practice
Capabilities Request only the capabilities the module actually needs.
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.

Privacy Boundaries

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"]
Loading

Telemetry is a host-owned decision. Modules should describe intent through service protocols and avoid embedding analytics vendors.

Performance and Reliability

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 compatibility or entitlements 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.

Reliability Flow

flowchart LR
    Manifest["Manifest"] --> EarlyFail["Early compatibility failure"]
    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"]
Loading

Production Readiness Checklist

  • Capability list reviewed for each module.
  • 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:) and stop(context:) are idempotent.
  • Logs avoid user-sensitive payloads.
  • Runtime failure paths have tests.

Clone this wiki locally