Isolation Model
The PSI toolkit is designed to achieve three goals simultaneously:
- Freedom -- anyone can create feature modules with whatever functionality they like
- Reuse -- partners are encouraged to use modules created by other partners
- Robustness -- a misbehaving module should only damage the instances it was enabled on
Isolation Layers
graph TD
subgraph "Instance Isolation"
A[Feature on Instance A] -.-|"Cannot access"| B[Data on Instance B]
A -->|"Full access"| A_data[Data on Instance A]
end
subgraph "Module Isolation"
M1[Module 1 Data] -.-|"Cannot access"| M2[Module 2 Data]
end
subgraph "Feature Gating"
F1[Feature X code] -.-|"Not executed"| I_disabled[Instance without Feature X]
F1 -->|"Runs"| I_enabled[Instance with Feature X]
end
style B fill:#f66,stroke:#333
style M2 fill:#f66,stroke:#333
style I_disabled fill:#f66,stroke:#333 Instance Isolation
Most data access is isolated to the current instance:
- The
Datastore(client) only exposes data for the instance the user is viewing - The
ServerStore(server) is scoped to the instance that triggered the API call - Accessing other instances requires explicit
Remotemethods that trigger closer review
Example: A feature enabled on question "Are cats cute?" can manipulate comments on that question, but cannot touch comments on other questions.
Module Isolation
Each module declares its own data using moduleData:
- Module data is namespaced -- only code in that module should access it
- Even if a module completely corrupts its own data, that corruption won't matter for instances where the module isn't enabled
- The constrained data abstractions (
ModuleGlobal,ModuleMap,ModuleMapMap) limit the surface area for bugs
Feature Gating
Client-side feature code only executes when explicitly enabled on an instance:
- Each instance has a
featuresdictionary listing enabled features - Feature config is only merged into the structure's config if the feature is enabled
- Different instances of the same structure can have different features active
Server Code Isolation
Server-side code has the potential for more damage, so additional safeguards apply:
moduleDatawithPRIVATEandPUBLICmodes can only be written from the server- All server code operates through the
ServerStoreinterface, which enforces scoping - Breaking out of the scoped context requires explicit
RemoteAPI calls - The architecture minimizes the need for server code -- most features are client-only
Data Access Control Summary
| Data Type | Who Can Read | Who Can Write |
|---|---|---|
| Instance Properties | All users | Admin only |
| Collection Objects | All users | Creator of each object |
| Module Data (PRIVATE) | Server only | Server only |
| Module Data (PUBLIC) | All users | Server only |
| Module Data (USER_GLOBAL) | Owning user | Owning user |
| Module Data (USER_READ) | Owning user | Server only |
| Session Data | Current user | Current user (client-only) |
Core vs. Open Module Guarantees
| Aspect | Core Module | Open Module |
|---|---|---|
| Maintained by | PSI core team | Contributing partner |
| Design review | Required | Encouraged, not required |
| Engineering review | Detailed, full review | Minimal (no destabilization) |
| Can be default | Yes | Only for contributing partner's silos |
| Dependencies | Can depend on other core modules | Cannot be depended on by core |
Further Reading
- Isolation Model reference (psi-product) -- detailed explanation
- Data Model -- how data access patterns enforce isolation
- Open Modules (psi-product) -- core vs. open module policies