2 - Security Model and Threat Notes

Security Model & Threat Notes

Read this before this library guards anything that can hurt a user — camera, microphone, screen capture, files. It's honest about the edges.


What it does protect

  • The UI can't self-assert identity. Requester IDs come from XRUIOS.Manager, not from the calling window. An app is whoever the Manager says it is.
  • Per-app keys isolate stores. Each app's store is encrypted with a key the Manager generated for that app. Without the right key you can't read or write that app's permissions — GetVariable simply fails to decrypt. This is the real gate, more than the requester ID is.
  • Encrypted at rest, in RAM too. SecureData keeps keys/IDs/values AES-encrypted in memory and wipes them on dispose, so a memory scanner doesn't just find them lying around.
  • Fail closed. Missing store, wrong key, corrupt file → the answer is no.
  • Auditable denials. Handler.OnStoreError separates "denied" from "the store is broken/tampered." See 1 - How Caching and Rate Limiting Work.
  • No lost revocations under concurrency. Per-store locking means two simultaneous writes can't drop one.

What it does not protect against (know these)

Same-process code that holds the key can act as the app. This library authorizes based on the per-app key + requester ID. It cannot, by itself, prove a running process is the app it claims to be. If hostile code is executing inside the app's process with access to its key, it has the app's authority. Process/app attestation is the Manager's responsibility — this library assumes the Manager did that job when it issued the key.
  • Out-of-band store edits. If something can decrypt and rewrite the store file directly (i.e. it already has the per-app key), it can grant itself anything. Guard the key; guard the file location.
  • Revocation latency on cached grants. Going through the handler evicts the cache immediately. A grant changed outside the handler can linger up to the 5-minute TTL. For high-risk permissions, only mutate through the handler, and consider a shorter TTL.
  • Levels are not capabilities. permValue >= requiredLevel models tiers on one permission name. It does not express independent capabilities. "Has camera but not mic" must be two permission names, not two levels on one — don't try to encode unrelated grants as a single number.

  1. Issue requester IDs and per-app keys only through XRUIOS.Manager. Never let a UI supply either.
  2. Put gated functions behind the Manager's dispatch so [RequiresPermission] is actually enforced (see 3 - Auto-Gating Functions (The Attribute)).
  3. Use distinct permission names per capability ("Use Camera", "Use Microphone", "Edit Camera Footage"), and levels only for tiers within a capability.
  4. Always mutate permissions through the handler so the cache is evicted — never hand-edit the store while the app is live.
  5. Subscribe to Handler.OnStoreError and treat a store error on a security-critical path as an incident, not a shrug.

The honest one-liner

This is a solid per-device permission store with correct caching, locking, and rate limiting. It becomes an OS-grade authority only because the XRUIOS.Manager sits underneath it issuing identities and keys. Keep that layer honest and the rest holds; weaken it and everything above it is decoration.