ANTI_CHEAT_AND_GAMEPLAY_AUTHORITY.md
# Anti-Cheat and Gameplay Authority: ScreechVR

## What PUN 2 currently permits
- Photon Cloud relays messages. No game logic validation.
- Master client is a player with a flag. Controls room properties, scene sync, spawning.
- RPCs route through Photon. No server-side param validation.
- Ownership transfer is client-initiated (Takeover/Request).
- Voice is relayed (PunVoiceClient).

## Why Master Client is not a trusted server
- Master client is a player's client. Can be modified.
- Controls AutomaticallySyncScene (forces scene loads on all clients).
- Can manipulate room properties.
- Can kick players (Kick_Player trigger).
- Cannot be used for security decisions.

## Strongest practical v1 protections (no dedicated server)
1. Heuristic movement detection (speed/teleport flags, manual review).
2. Server-side currency validation (worker/CloudScript).
3. Server-side moderator verification (PlayFab).
4. Photon custom auth ban check on connect.
5. Per-player RPC rate limits.
6. Backend inventory verification for cosmetics.
7. Version enforcement via title data + custom auth.
8. Null crash guards.

## Long-term target (v2+)
- Dedicated authoritative server for movement, scoring, bans.
- Photon Fusion or self-hosted Photon Server.
- Full server-side game simulation.
- Instant kick enforcement.

## Residual cheat capabilities (v1, honest)
- Movement exploits can only be detected, not prevented (no dedicated server).
- Client-side visual mods (harmless, log only).
- Master client can manipulate room state (mitigated by minimizing authority).
- Frida/injection can bypass client checks (server-side enforcement limits blast radius).
- A determined attacker can still cheat; goal is detection + enforcement, not prevention.

ANTI_CHEAT_PREVENTION_DETECTION_MATRIX.md
# Anti-Cheat Prevention and Detection Matrix: ScreechVR

## Matrix (attack -> prevention/detection/mitigation)

| Attack | Prevent? | Detect reliably? | Detect heuristically? | Mitigate after? | Backend reject? | Current arch? | Needs new infra? | Residual if client controlled |
|---|---|---|---|---|---|---|---|---|
| Modified APK | Partially (signing) | Partially (version) | No | Yes (ban) | Yes (version check) | Yes | No | Can bypass version check |
| Asset mod (visual) | No | No | No | N/A | No | N/A | N/A | N/A (harmless) |
| Asset mod (gameplay) | No | Partially (hash) | No | Yes (ban) | Yes (outcome validation) | Partial | No | Can fake outcomes |
| Memory mod (currency) | No | No | Partially (anomaly) | Yes (revert) | Yes (server balance) | Yes (PlayFab) | No | Can desync display |
| Memory mod (position) | No | No | Partially (speed/teleport flags) | Yes (flag+review) | No (no dedicated server) | Partial | Yes (dedicated server) | Can move freely |
| Frida/injection | No | Heuristically | Yes (low conf) | Yes (flag) | No | Yes (flag) | No | Can bypass detection |
| RPC flood | Partially (rate limit) | Yes (rate) | Yes | Yes (kick) | Yes (rate limit) | Yes | No | Can flood within limits |
| Ban evasion | Partially (Photon auth) | Partially (alt detection) | Yes (IP/hardware) | Yes (ban) | Yes (ban check on connect) | Yes | No | Can create new account |
| Moderator spoof | Yes (server-side) | Yes (if backend verifies) | No | Yes (revoke) | Yes | Yes (after fix) | No | Cannot if server-enforced |
| Master client abuse | Partially (minimize authority) | Partially (logs) | No | Yes (flag) | Partially | Partial | Yes (dedicated server) | Can manipulate room state |
| Leaderboard faking | No | No | Partially (anomaly) | Yes (remove score) | Yes (server validation) | Partial | No | Can submit fake scores |
| IAP bypass | Partially (PlayFab validates) | Partially (receipt) | No | Yes (revoke) | Yes (receipt validation) | Partial | No | Can fake receipt (if not validated) |
| Tag/Infection spoof | No | No | Partially (state validation) | Yes (flag) | Partially | Partial | Yes (server-side tag) | Can send forged RPCs |
| Cosmetic spoof | No | No | Partially (inventory check) | Yes (flag) | Yes (inventory check) | Yes (after fix) | No | Can claim unowned cosmetic |
| Null crash trigger | Partially (null guards) | No | No | Yes (flag) | No | Partial | No | Can trigger NREs |
| Duplicate session | No | Yes (heartbeat) | Yes | Yes (kick older) | Yes | Yes (after fix) | No | Can reconnect |
| Version spoof | Partially (title data) | Partially (version check) | No | Yes (kick) | Yes (custom auth) | Partial | No | Can ignore title data |
| Attestation failure | No | Heuristically | Yes (low conf) | Yes (flag) | Partially | No (unverified) | Yes (if available) | Can run on untrusted device |

## Graduated response model
1. Allow and observe (all signals logged).
2. Record low-confidence signal (confidence < 0.3).
3. Increase validation or restrict sensitive operation (confidence 0.3-0.5).
4. Require fresh authentication or attestation (confidence 0.5-0.7).
5. Flag for human review (confidence >= 0.5).
6. Kick on clearly defined authoritative protocol violation (server-verified).
7. Ban under documented evidence policy (human-confirmed, except repeated high-confidence).

## Auto-action policy
- NEVER auto-ban on client-reported signals alone.
- Kick allowed for: ban status, version mismatch, duplicate session, attestation failure (if configured).
- Ban requires human confirmation unless explicitly configured otherwise (default: human confirmation).
- Every auto-action must be logged with evidence reference and confidence score.

AUTHENTICATION_PROVIDER_MASTER_COMPARISON.md
# Authentication Provider Master Comparison: ScreechVR

## Providers evaluated

| Provider | Type | Free plan | CC required | Unity support | Quest support | Identity proof | Token validation | Session security | MFA | Realistic cost (1k CCU) | ScreechVR fit |
|---|---|---|---|---|---|---|---|---|---|---|---|
| PlayFab (current) | Game backend | Free tier (limited) | No | Official SDK | Verified (in use) | Custom ID (Oculus ID) | PlayFab session ticket | Session ticket + Photon token | No (admin only) | $0-50/mo (usage-based) | Good (already integrated) |
| Meta User Verification | Platform identity | Free (platform API) | No | Oculus SDK | Verified (Oculus SDK) | Server-side proof validation | Meta's verification endpoint | Nonce-based, one-time | N/A (platform) | $0 | Excellent (root identity) |
| Firebase Auth | Identity provider | Free (Spark plan) | No (for auth) | Official SDK | Unverified (Android SDK) | Firebase ID token | Server-side ID token verify | JWT, refresh, revocation | Yes (TOTP, SMS) | $0-25/mo (Blaze if exceeded) | Good (but adds complexity) |
| Supabase Auth | Identity provider | Free tier (pauses after 7 days inactivity) | No | Community SDK | Unverified | JWT + external OAuth | Server-side JWT verify | JWT, refresh, RLS | Yes (TOTP) | $0-25/mo (Pro if active) | Moderate (pausing risk) |
| Nakama | Game backend | Open source (self-host) | No (software) | Official SDK | Verified (Unity SDK) | Session tokens | Server-side session verify | Session tokens, expiry | Custom | $0 software + hosting ($5-50/mo) | Good (authoritative, but migration) |
| Appwrite | Backend platform | Free cloud tier | No | Community SDK | Unverified | JWT + OAuth | Server-side JWT verify | JWT, session mgmt | Yes (TOTP) | $0-15/mo | Moderate (limited Unity support) |
| PocketBase | Open source | Free (self-host) | No (software) | Community | Unverified | JWT | Server-side JWT verify | JWT, session expiry | Custom | $0 software + hosting ($5-20/mo) | Low (no official Unity SDK) |
| Keycloak | Identity server | Free (self-host) | No (software) | Community | Unverified | OAuth2/OIDC | Server-side token verify | OIDC, session mgmt | Yes (TOTP, WebAuthn) | $0 software + hosting ($10-30/mo) | Low (heavy, overkill for solo dev) |
| Auth0 | Identity provider | Free (7,500 MAU) | No | Official SDK | Unverified | OAuth2/OIDC | Server-side JWT verify | JWT, refresh, revocation | Yes (TOTP, push) | $0 (free tier) -> $35/mo (Essential) | Moderate (MAU limits) |
| Clerk | Identity provider | Free (10,000 MAU) | No | Official SDK | Unverified | JWT + OAuth | Server-side JWT verify | JWT, session mgmt | Yes (TOTP, passkeys) | $0 (free tier) -> $25/mo (Pro) | Moderate (MAU limits) |
| AWS Cognito | Identity provider | Free (50,000 MAU) | Yes (AWS account) | AWS SDK | Unverified | JWT + OAuth | Server-side JWT verify | JWT, refresh, revocation | Yes (TOTP, SMS) | $0 (free tier) -> usage-based | Low (complex, AWS lock-in) |

## Rankings

### Best genuinely free authentication option
**Meta User Verification + PlayFab.** Meta identity is hardware-bound (strongest proof), PlayFab is already integrated, free for auth. No new provider needed.

### Best complete free-first security architecture
**Cloudflare Workers + D1 + PlayFab + Photon PUN2.** Already in use, free tier covers low scale, extends existing infrastructure.

### Best open-source architecture
**Nakama (self-hosted) + Meta identity.** Authoritative multiplayer + auth + economy. But requires hosting ($5-50/mo) and migration (20-30 weeks).

### Least disruptive migration
**Keep PlayFab + Photon, add server-side validation via Cloudflare worker.** Minimal changes to existing code.

### Best long-term production design
**Cloudflare + PlayFab + Photon (v1) -> migrate to Nakama or dedicated server (v2) if cheating becomes serious.** Staged approach.

## Key findings
- Meta User Verification (getUserProof) is the strongest identity proof available for Quest. Server-side validation required.
- PlayFab Custom ID (Oculus ID) is a client-provided identifier, NOT proof of identity. Must verify via Meta User Verification.
- Firebase/Supabase add complexity without clear benefit for a Quest game already on PlayFab.
- Nakama is the best open-source option but requires significant migration.
- No free provider offers authoritative multiplayer out of the box. All require hosting.

BACKEND_PROVIDER_COMPARISON.md
# Backend Provider Comparison: ScreechVR

## Candidates evaluated
1. Cloudflare Workers + D1 + KV + R2 (extend existing)
2. PlayFab (already in use, keep)
3. Photon PUN 2 + Voice (already in use, keep)
4. Nakama (authoritative multiplayer)
5. Photon Fusion (dedicated server)
6. GameLift (dedicated hosting)
7. Self-hosted VPS (Hetzner)
8. Supabase/Firebase (general backend)

## Comparison matrix

| Criteria | Cloudflare+PlayFab+Photon (v1) | +Nakama | +Photon Fusion | +GameLift | Self-hosted |
|---|---|---|---|---|---|
| Security | Good (backend validation) | Better (authoritative) | Better | Better | Best (full control) |
| Gameplay authority | Heuristic only | Full | Full | Full | Full |
| Identity | PlayFab (Oculus custom ID) | Nakama auth | Photon auth | GameLift auth | Custom |
| Economy | PlayFab (server-side) | Nakama economy | PlayFab | Custom | Custom |
| Ban enforcement | Photon custom auth + PlayFab | Nakama bans | Photon bans | Custom | Custom |
| Real-time networking | Photon PUN2 (relay) | Nakama (authoritative) | Fusion (authoritative) | GameLift | Custom |
| Quest compatibility | Verified (already running) | Unity SDK available | Unity SDK available | Unity SDK available | Unity dedicated server |
| Photon compatibility | N/A (already using) | Replaces PUN2 | Replaces PUN2 | Replaces PUN2 | Replaces PUN2 |
| Migration effort | Low (extend existing) | High (rewrite networking) | High (rewrite networking) | High | Very high |
| Reliability | High (Cloudflare + PlayFab SLA) | Medium (self-managed) | Medium | High (AWS) | Low (solo ops) |
| Scaling | Auto (Cloudflare) | Manual | Manual | Auto (AWS) | Manual |
| Cost (1k CCU) | $20-50/mo | $50-150/mo | $50-150/mo | $100-300/mo | $80-200/mo |
| Solo dev effort | Low | High | High | High | Very high |
| Dashboard | Cloudflare Pages (free) | Nakama console | Custom | AWS console | Custom |
| Privacy | Cloudflare (GDPR compliant) | Self-managed | Self-managed | AWS | Self-managed |
| Vendor risk | Medium (Cloudflare + PlayFab + Photon) | Medium (Nakama) | Medium (Photon) | Low (AWS) | Low (self) |

## Recommendation
**Best security overall:** Dedicated authoritative server (Option 3) - but high cost/complexity.
**Best security-to-cost for solo dev:** Cloudflare + PlayFab + Photon PUN2 (Option 1) - recommended for v1.
**Best short-term improvement:** Same as above - extend existing stack with backend validation + detection + dashboard.

## Runner-up
Nakama (integrated multiplayer backend) - combines auth, matchmaking, authoritative matches, persistence. Would replace PlayFab + Photon. Migration cost high (20-30 weeks). Consider for v2 if cheating becomes serious.

## Lifecycle note
Unity Multiplay Hosting shut down March 31, 2026. Do not recommend. Use GameLift or self-hosted dedicated servers instead.

## Trade-offs of recommended architecture
- Cannot authoritatively validate movement (no dedicated server).
- Master client remains a player (mitigated by minimizing authority).
- Detection is heuristic for movement (flag + review, not auto-ban).
- Cost savings vs dedicated server: ~$500-1300/mo at 1k CCU.

CLOUD_AND_DATABASE_SECURITY.md
# Cloud and Database Security: ScreechVR

## Cloudflare services
- Workers: edge compute, 50ms CPU (free), 30s (paid). API entry point.
- D1: SQLite, 5GB free, 5M reads/day, 100k writes/day. Primary DB.
- KV: eventual consistency, cache only. 100k reads/day free.
- R2: object storage, 10GB free. Evidence storage.
- Pages: static hosting, free. Dashboard.
- Rate limiting: built-in, per-IP/per-key.

## Database security
- D1: SQLite (single-writer). Parameterized queries via worker binding.
- No SQL injection risk if using parameterized queries (D1 binding API).
- Schema: sessions, players, flags, bans, audit_log, ccu_snapshots, webhooks, detection_rules, evidence.
- Indexes: sessions(player_id, started_at), flags(status, created_at), bans(player_id, status), ccu_snapshots(ts).
- Backups: D1 automatic daily backups. Test restore quarterly.
- Retention: sessions 30 days, flags 90 days, bans 1 year, audit log 1 year, CCU 1 year.

## Secret management
- All secrets in worker env vars (Cloudflare dashboard, encrypted at rest).
- No secrets in Unity client, no secrets in repo.
- Bot token in discord-bot/bot-token.txt (not in repo).
- Rotate on suspected compromise.

## API security
- Authentication: JWT (HS256, secret in worker env).
- Authorization: RBAC (Owner/Admin/Moderator/Viewer).
- Rate limiting: per-IP and per-user.
- Input validation: Zod schemas (or manual validation in worker).
- CORS: allowlist dashboard origin only.
- CSRF: SameSite cookies + CSRF tokens if cookie-based.
- Error handling: structured errors, no stack traces in production.

## Environment separation
- Dev: separate worker, separate D1, separate Photon app, separate PlayFab title.
- Staging: same as prod but isolated data.
- Prod: production worker, D1, Photon app, PlayFab title.
- Never use prod credentials in dev.

## OWASP API Security Top 10 (2023) coverage
- API1 BOLA: server-side ownership checks on all endpoints.
- API2 Broken Auth: JWT + MFA + rate limiting.
- API3 BOPLA: field-level authorization (don't return sensitive fields).
- API4 Unrestricted Resource Consumption: rate limits, input size limits.
- API5 Broken Function Level Auth: RBAC enforced server-side.
- API6 Unrestricted Access to Sensitive Business Flows: rate limits, idempotency.
- API7 SSRF: no user-supplied URLs in backend.
- API8 Security Misconfiguration: environment separation, secret management.
- API9 Improper Inventory Management: API versioning, deprecation.
- API10 Unsafe Consumption of APIs: validate all external API responses.

CORRECTIONS_TO_PREVIOUS_RESEARCH.md
# Corrections to Previous Research

## Corrections made during this research phase

1. **Photon architecture:** Earlier reports conflated "Photon" as a single trusted component. Corrected: Photon Cloud is a relay (semi-trusted). Master client is a player (untrusted). Photon custom auth delegates to backend (trusted). Dedicated server is separate (v2+).

2. **Meta attestation:** Earlier reports said "Meta attestation is Layer One" as if confirmed. Corrected: native symbol present (confirmed), but API docs inaccessible (404). Availability, permissions, verification endpoint UNVERIFIED. Must be optional module.

3. **Cost estimates:** Earlier reports said 10-17 weeks. Revised to 12-20 weeks (part-time). Final MVP: 9-14 weeks (focused scope). Initial cost $1-35/mo (not $600/mo Tomahawk).

4. **Tomahawk SDK:** Earlier reports treated SDK as "older snapshot" based on enum discrepancies. Ghidra analysis confirmed: error counts stubbed, Photon.IsAvailable() returns false, TomahawkPhoton is a stub. SDK is older/simplified. Docs are more complete.

5. **Currency vulnerability:** Earlier reports said "client-trusted currency." Corrected: PlayFab AddUserVirtualCurrency validates session ticket but NOT amount. Client can grant arbitrary currency with valid session. This is worse than initially assessed. Mitigation: move to CloudScript/worker.

6. **Moderator status:** Earlier reports said "client-trusted." Corrected: PlayFab UserData "Moderator" key is likely client-writable (PlayFab default). If true, any player can self-promote. CRITICAL. Verify in dashboard.

7. **Master client:** Earlier reports didn't emphasize that master client controls scene sync. Added: AutomaticallySyncScene=true means master can force scene loads. Minimize master authority.

8. **Detection rules:** Earlier reports had generic rules. Corrected: 12 ScreechVR-specific rules (S-001..S-012) derived from actual code (Player.cs, Oculus_Login.cs, BuyCosmetic.cs, TagPlayer.cs, etc.).

9. **Photon custom auth response codes:** Verified from official docs: ResultCode 0=incomplete, 1=success, 2=failure, 3=invalid params. Earlier reports didn't specify.

10. **Free tier limits:** Added specific Cloudflare free tier limits (100k req/day, 5GB D1, 100k KV reads/day). Earlier reports were vague.

## What was NOT corrected (still valid)
- Tomahawk public site research (features, pricing, roles, integration methods).
- Local file research (getting started, API reference, portal docs, unity implementation, error codes).
- Ghidra binary analysis (native lib is thin wrapper + OpenSSL).
- Quest modification threat catalog (comprehensive, verified identities).
- Trust boundary analysis (client untrusted, backend trusted).
- Detection engine design (risk scoring, graduated response).
- Dashboard design (pages, auth, security).
- Cost estimates (revised but directionally correct).

COST_CAPACITY_AND_RELIABILITY.md
# Cost, Capacity, and Reliability: ScreechVR (Voideration)

## Cost scenarios

| Scale | Workers | D1 | KV | R2 | Pages | Total/mo |
|---|---|---|---|---|---|---|
| Initial (free tier) | $0 | $0 | $0 | $0 | $0 | $1-2 (domain) |
| 100 CCU | $0-5 | $0-5 | $0-5 | $0-1 | $0 | $5-16 |
| 500 CCU | $5-10 | $5-10 | $5-10 | $1-3 | $0 | $16-33 |
| 1000 CCU | $5-10 | $5-15 | $5-10 | $1-5 | $0 | $16-40 |
| 5000 CCU | $25-50 | $25-50 | $10-20 | $5-10 | $0 | $65-130 |

vs Tomahawk: $600/mo floor. Self-hosted saves $500-580/mo at 1k CCU.

## Capacity assumptions
- Session duration: 30 min avg. Heartbeat: every 10s. CCU: peak concurrent.
- DB writes: session start/end, heartbeat (upsert), flags, bans, audit log. ~5-10 writes/sec at 1k CCU.
- D1 limit: ~100 writes/sec. Upgrade to Postgres (Neon) if exceeded.
- KV: eventual consistency, use for cache only.
- Workers: 50ms CPU limit (free), 30s (paid). Keep validation fast.

## Reliability
- PlayFab down: fail closed for auth (deny new connections), fail open for gameplay (existing sessions continue), bans still enforced from cache.
- Worker down: Photon custom auth fails -> Photon denies connections (fail closed). Existing sessions continue.
- D1 down: audit log/flags delayed, core auth still works (worker validates via PlayFab directly).
- Photon down: game unplayable (no multiplayer). Single-player not affected.
- Backup: D1 automatic daily backups. Test restore quarterly.
- Monitoring: Cloudflare Analytics, Sentry (free), Discord webhook for high-severity.

## Assumptions
- Cloudflare free tier sufficient for initial launch (untested).
- D1 throughput scales linearly (untested).
- No egress costs (Cloudflare includes bandwidth).
- Prices as of 2026-10. Verify before committing.

DECISIONS_REQUIRED.md
# Decisions Required: Voideration for ScreechVR

## 1. PlayFab UserData "Moderator" key writability
**Question:** Is the "Moderator" key in PlayFab UserData client-writable?
**If yes:** Any player can self-promote to moderator. Immediate critical vulnerability.
**Best default:** Assume client-writable (PlayFab UserData is client-writable by default). Move moderator status to server-side claim.
**Consequence of not fixing:** Moderator spoofing, unauthorized mod menu access.

## 2. Currency grants
**Question:** Move currency grants to CloudScript/worker, or keep client-side with audit logging?
**Best default:** Move to worker (server-side price validation). Client calls worker, worker validates and grants.
**Consequence of keeping client-side:** Players can grant themselves arbitrary gold.

## 3. Meta attestation
**Question:** Is Meta Device Application Integrity API available to ScreechVR?
**Best default:** Assume unavailable (docs gated). Design as optional module. Primary security via server-side validation.
**Consequence of depending on it:** Layer One missing if unavailable.

## 4. Photon custom auth
**Question:** Willing to configure custom auth URL in Photon dashboard pointing to worker?
**Best default:** Yes. Required for server-side ban enforcement on connect.
**Consequence of not configuring:** Bans remain client-side only (5s delay, ignorable).

## 5. Dashboard hosting
**Question:** Cloudflare Pages (free) or separate VPS?
**Best default:** Cloudflare Pages. Free, static, backend-enforced auth.
**Consequence of VPS:** Higher cost, more ops burden.

## 6. MFA scope
**Question:** TOTP for owner only, or all admins?
**Best default:** Owner only for v1. Expand to all admins in v1.5.
**Consequence:** Admins without MFA are weaker targets.

## 7. Evidence storage
**Question:** Telemetry only, or screenshots/video?
**Best default:** Telemetry only (cost + privacy). Add screenshots only if needed for specific investigations.
**Consequence:** Less visual evidence for ban appeals.

## 8. Real-time kick enforcement
**Question:** Accept 5s delay (KickIfBanned poll) or invest in Photon Server for instant kick?
**Best default:** Accept 5s delay for v1. Invest in Photon Server only if abuse becomes serious.
**Consequence:** 5s window for banned players to remain in room.

## 9. CloudScript/Azure Functions
**Question:** Are any CloudScript or Azure Functions deployed in PlayFab?
**Best default:** Assume none (none found in repo). Verify in dashboard.
**Consequence:** If deployed, currency flow may already be server-validated (changes V1 severity).

## 10. PlayFab PurchaseItem price validation
**Question:** Does PlayFab validate purchase price server-side?
**Best default:** Assume yes (PlayFab docs say so). Verify in dashboard/catalog config.
**Consequence:** If not validated, players can buy at wrong price.

EXECUTIVE_RECOMMENDATION.md
# Executive Recommendation: Voideration Anti-Cheat for ScreechVR

## Recommended architecture
Cloudflare Workers + D1 + KV + R2 (backend) + Cloudflare Pages (dashboard) + PlayFab (auth/inventory/bans) + Photon PUN2+Voice (networking, kept). No dedicated game server for v1. No multi-game. No cross-game ban sharing.

## Why this wins
- Extends existing infrastructure (worker already live). Zero new infra cost.
- PlayFab already handles auth, inventory, bans, title data. Don't replace what works.
- Photon PUN2 handles multiplayer. Replacing it costs 20-30 weeks for marginal security gain.
- Cloudflare provides edge compute, DDoS protection, rate limiting, free tier.
- Dashboard on Pages (free, static, backend-enforced auth).

## Biggest current vulnerabilities (verified)
1. Client-trusted currency (AddCurrency local-first; PlayFab validates session not amount).
2. Client-trusted moderator status (PlayFab UserData "Moderator" key, likely client-writable).
3. Client-side ban enforcement (KickIfBanned polls every 5s; ignorable).
4. No movement validation (speed/teleport exploits).
5. Master client abuse (scene sync, room state).
6. Cosmetic/leaderboard spoofing (client-driven).
7. RPC floods (ThusterController, Flash_Light).
8. Null crashes (many unguarded paths).

## What it costs
- Initial: $1-35/mo (Cloudflare free tier + domain).
- 1k CCU: $20-50/mo. 10k CCU: $130-260/mo.
- vs Tomahawk: $600/mo floor. Savings: $500-580/mo at 1k CCU.
- Trade-off: your engineering time (10-17 weeks MVP, 5-10h/week ops).

## What it can prevent
- Currency minting (server-side grants).
- Moderator spoof (server-side role verification).
- Ban bypass (Photon custom auth on connect).
- Cosmetic/leaderboard spoofing (backend inventory validation).
- RPC floods (rate limits).
- Duplicate sessions (heartbeat detection).

## What remains possible
- Movement exploits (heuristic detection only, no dedicated server).
- Client-side visual mods (harmless, log only).
- Master client abuse (minimize authority, move state to backend).
- Frida/injection (server-side enforcement limits blast radius).

## Next three highest-priority actions
1. Verify PlayFab UserData "Moderator" writability (critical if true).
2. Move currency grants to server-side (CloudScript/worker).
3. Implement Photon custom auth for connect-time ban enforcement.

## Direct answers to key questions
1. **Cloudflare alone?** No. Cloudflare handles API/backend. PlayFab handles auth/inventory/bans. Photon handles multiplayer. Each has a distinct role.
2. **Cloudflare+PlayFab+Photon PUN2 long-term?** Good for v1. Replace Photon only if cheating becomes serious (v2, dedicated server).
3. **Strongest realistic architecture?** Server-authoritative where possible (currency, bans, cosmetics, version) + heuristic detection for movement + manual review. No dedicated server for v1.
4. **Keep Photon Voice?** Yes. Photon Voice is separate from PUN2. Migration cost for voice is high; keep it.
5. **Authoritative source for identity/bans/currency/inventory/purchases/match results?** PlayFab (identity, bans, inventory, currency). Worker (session validation, CCU). Photon (room state, temporary). Match results: client-reported, server-validated where possible.
6. **Prove Meta identity?** Oculus auth (Core.Initialize + Users.GetLoggedInUser) -> Oculus ID -> PlayFab LoginWithCustomID. Hardware-bound ID. Stronger than client-supplied string.
7. **Meta attestation?** Symbol confirmed, docs gated. Cannot verify availability. Layer One optional, not gate. Fallback: server-side validation.
8. **Service failure?** Fail closed for bans/auth. Fail open for gameplay (allow-through for non-banned). Documented in Tomahawk's behavior.
9. **Can client promote/mint/bypass/equip/forge?** No, if server-side enforcement implemented. Currently yes (vulnerabilities exist).
10. **Detect vs prevent?** Movement exploits: detect only (no dedicated server). Currency/bans/cosmetics: prevent (server-side). RPC floods: prevent (rate limits).
11. **First security improvement?** Move currency grants server-side + server-side moderator verification + Photon custom auth ban check.
12. **Monthly costs at 100/500/1000 CCU?** ~$1-2 / ~$5-15 / ~$20-50 (Cloudflare). vs Tomahawk $600/mo floor.
13. **Worth paying for?** Cloudflare paid plan ($5/mo) if free tier exceeded. Neon Postgres if D1 limits hit. NOT worth: dedicated server, ML detection, advanced analytics (v1).
14. **Biggest remaining risks:** Movement exploits (no dedicated server), Meta attestation unavailable, false positives, solo dev burnout, scope creep.
15. **Best realistic end state:** Server-authoritative economy/bans/cosmetics + heuristic movement detection + manual review + private dashboard. Accept that movement exploits can only be detected, not prevented, without dedicated server.

STOP: research phase complete. No implementation performed. Awaiting your explicit approval.

FREE_AUTHENTICATION_ARCHITECTURES.md
# Free Authentication Architectures: ScreechVR

## Architecture A: Minimum migration (RECOMMENDED v1)
- Keep PlayFab + Photon PUN2 + Cloudflare worker.
- Add Meta User Verification (getUserProof) as identity proof.
- Worker validates Meta proof server-side, links to PlayFab account.
- Photon custom auth via worker (ban check + identity verification).
- Cost: $1-35/mo (Cloudflare free tier + domain). PlayFab free tier. Photon free tier (20 CCU).
- Limitation: No authoritative gameplay. Movement heuristic only.

## Architecture B: Best free managed identity
- Meta User Verification + PlayFab (already in use).
- No new provider needed. Meta identity is hardware-bound.
- PlayFab handles auth, inventory, currency, bans, title data.
- Cost: $0-50/mo (PlayFab usage-based).
- Limitation: PlayFab client API allows client-specified currency grants (vulnerability).

## Architecture C: Best open-source
- Nakama (self-hosted) + Meta identity.
- Requires hosting ($5-50/mo) + migration (20-30 weeks).
- Authoritative multiplayer, auth, economy, matchmaking in one platform.
- Limitation: solo dev ops burden, migration cost.

## Architecture D: Best free-first authoritative multiplayer
- No credible zero-cost authoritative game server exists.
- Cloudflare Workers can run lightweight validation (not full game simulation).
- Nakama on free tier hosting (Oracle Cloud free tier, 1 OCPU, 1GB RAM) - possible but limited.
- Recommendation: Start with Architecture A. Migrate to Nakama or dedicated server (v2) if cheating becomes serious.

## Free tier limitations
- Cloudflare Workers: 100k requests/day free. Exceeded -> 429 or paid plan ($5/mo).
- D1: 5GB storage, 5M reads/day, 100k writes/day free. Exceeded -> paid ($0.001/100k reads).
- PlayFab: free tier has limits on API calls, storage, etc. Verify in dashboard.
- Photon: free tier 20 CCU. Exceeded -> upgrade required.
- Supabase free: pauses after 7 days inactivity. Not suitable for production.
- Firebase free: Spark plan, no credit card needed for auth. Blaze (pay-as-you-go) for functions.

## What happens when free limits are exhausted
- Cloudflare: 429 Too Many Requests. Game may fail to authenticate or report telemetry. Backend auth fails closed (deny connections).
- PlayFab: API calls fail. Client gets error. Game may not function.
- Photon: connection refused. Game unplayable (no multiplayer).
- No quota-related failure should silently disable authorization or permit protected actions.

FREE_TIER_COST_AND_CAPACITY_MODEL.md
# Free Tier Cost and Capacity Model: ScreechVR

## Free tier limits (as of 2026-10)
- Cloudflare Workers: 100k requests/day (free). Paid: $5/mo + $0.50/million requests.
- Cloudflare D1: 5GB storage, 5M reads/day, 100k writes/day (free). Paid: $0.001/100k reads, $1.00/1M writes.
- Cloudflare KV: 100k reads/day, 1k writes/day (free). Paid: $0.50/million reads.
- Cloudflare R2: 10GB storage, 1M reads/mo, 1M writes/mo (free). Paid: $0.015/GB/mo storage.
- Cloudflare Pages: unlimited static sites (free).
- PlayFab: free tier (limits on API calls, storage, etc. - verify in dashboard).
- Photon: free tier 20 CCU. Paid: $95/mo for 100 CCU.
- Sentry: free tier (5k errors/mo).

## Cost scenarios

| Scale | Workers | D1 | KV | R2 | Pages | Photon | Total/mo |
|---|---|---|---|---|---|---|
| 50 CCU | $0 | $0 | $0 | $0 | $0 | $0 | $1-2 (domain) |
| 100 CCU | $0 | $0 | $0 | $0 | $0 | $0 | $1-2 |
| 500 CCU | $0-5 | $0-5 | $0-5 | $0-1 | $0 | $0 | $5-16 |
| 1000 CCU | $5-10 | $5-15 | $5-10 | $1-5 | $0 | $95 | $111-135 |
| 5000 CCU | $25-50 | $25-50 | $10-20 | $5-10 | $0 | $95+ | $160-325 |

## Key insight: Photon is the cost bottleneck
- Cloudflare scales cheaply (free tier + $5/mo paid plan).
- PlayFab scales with usage (verify limits).
- Photon free tier is only 20 CCU. At 100+ CCU, Photon becomes the dominant cost ($95/mo for 100 CCU).
- At 1000 CCU, Photon likely costs $200-500/mo (verify pricing).

## What happens when free limits are exceeded
- Cloudflare: 429 Too Many Requests. Backend auth fails closed (deny connections). Game may not function.
- PlayFab: API calls fail. Client gets error. Game may not function.
- Photon: connection refused. Game unplayable (no multiplayer).
- No quota-related failure should silently disable authorization or permit protected actions.

## Cost optimization
- Reduce heartbeat frequency (10s -> 30s) to cut worker requests.
- Batch telemetry (send every 30s instead of per-event).
- Cache PlayFab data in KV (5min TTL) to reduce PlayFab API calls.
- Use D1 for persistent data, KV for cache only.
- Monitor Cloudflare Analytics for usage trends.

IDENTITY_ECONOMY_AND_MODERATION_SECURITY.md
# Identity, Economy, and Moderation Security: ScreechVR

## Identity flow (verified)
Oculus Core.Initialize + Users.GetLoggedInUser -> Oculus ID + username -> PlayFab LoginWithCustomID (Oculus ID, CreateAccount=true) -> PlayFab session ticket -> GetPhotonAuthenticationToken -> Photon custom auth.

## Identity verification
- Oculus ID is hardware-bound (from Oculus Platform SDK). Stronger than client-supplied string.
- PlayFab LoginWithCustomID creates account if not exists. Custom ID = Oculus ID.
- Photon custom auth: Photon's servers call your backend to verify the PlayFab session ticket. Backend returns allow/deny.
- Client cannot choose its own Photon UserId (Photon assigns from auth result).

## Economy security
- Currency: PlayFab virtual currency "HC". AddUserVirtualCurrency accepts client-specified amount (VULNERABILITY). Fix: move to worker/CloudScript.
- Purchases: PlayFab PurchaseItem validates price server-side against catalog. Client gates on local balance (cosmetic issue).
- IAP: SpokesSigmaIAP (Oculus IAP). Receipt validation UNVERIFIED.
- Inventory: GetUserInventory (server-side). Cosmetic ownership should be verified server-side.
- Leaderboards: GDH client-submitted. No server validation observed.

## Moderator security
- AccountPref enum (Banned/ActiveUser/Moderator) set from PlayFab UserData "Moderator" key.
- CreateKeyIfNot creates "Moderator"="FALSE" if not exists.
- CRITICAL: PlayFab UserData is client-writable by default. If client can write "Moderator"="TRUE", any player can self-promote.
- Fix: move moderator status to server-side claim or PlayFab's read-only data. Verify in dashboard.

## Ban security
- PlayFab bans are server-side (admin API). Ban status checked via GetAccountInfo.
- KickIfBanned polls every 5s (client-side, ignorable).
- Photon custom auth can check ban status on connect (server-side, cannot be bypassed).
- Fix: add ban check to Photon custom auth endpoint.

## Permission matrix
| Role | View players | View flags | Issue bans | Revoke bans | Manage rules | Manage team | View audit log |
|---|---|---|---|---|---|---|---|
| Owner | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Admin | Yes | Yes | Yes | Yes | Yes | No | Yes |
| Moderator | Yes | Yes | Yes | No | No | No | No |
| Viewer | Yes | Yes | No | No | No | No | No |

IMPLEMENTATION_ROADMAP.md
# Implementation Roadmap: Voideration for ScreechVR

## Phase 0: Close research gaps (1 week)
- Verify PlayFab UserData "Moderator" writability.
- Verify CloudScript/Azure Functions deployment.
- Verify PlayFab PurchaseItem price validation.
- Verify Meta attestation availability (if possible).
- Verify Photon custom auth configuration in dashboard.
- Effort: 1 week. Risk: low. Outcome: confirm critical assumptions.

## Phase 1: Protect accounts and backend authorization (2-3 weeks)
- Photon custom auth endpoint in worker (validate PlayFab session + ban check).
- Server-side moderator verification (remove client-side AccountPref trust).
- Move currency grants to worker/CloudScript (server-side price validation).
- Audit log (append-only, hash-chained).
- Rate limiting on all endpoints.
- Files: worker.js, Oculus_Login.cs (remove local currency update), BuyCosmetic.cs (server-side check).
- Acceptance: banned players can't connect; moderator spoof flagged; currency grant requires server approval.

## Phase 2: Secure economy and purchases (1-2 weeks)
- Backend inventory verification for cosmetics.
- Server-side IAP receipt validation (if SpokesSigmaIAP path verified).
- Idempotency keys for /redeem and purchases.
- Transaction audit logs.
- Acceptance: client cannot grant itself currency or equip unowned cosmetics.

## Phase 3: Enforce bans and sessions (1-2 weeks)
- Heartbeat-based duplicate session detection.
- Server-side ban enforcement via Photon custom auth.
- Session revocation.
- Fail-safe behavior for upstream outages.
- Acceptance: banned players rejected on connect; duplicate sessions flagged.

## Phase 4: Layered integrity and behavioral detection (2-3 weeks)
- Movement telemetry collection (client reports samples).
- Detection rules S-001, S-002, S-005, S-006, S-008 (server-verifiable).
- Flag creation with confidence + evidence storage.
- Review queue API.
- Rate limits per player (RPC flood prevention).
- Acceptance: flags created for synthetic cheats; no false positives on clean sessions.

## Phase 5: Dashboard (2-3 weeks)
- Auth (email+password+TOTP), JWT, RBAC.
- Overview, players, flags, bans, audit log pages.
- Ban issue/revoke with Discord webhook.
- Detection rule configuration.
- Acceptance: owner can log in, view flags, issue ban, ban appears in PlayFab.

## Phase 6: Harden operations (1-2 weeks)
- Pen test, load test (k6), false-positive regression.
- Backup restore drill.
- Monitoring + alerting.
- Kill switch implementation.
- Acceptance: all tests pass, no critical findings.

## Rollback
- Each phase is independently deployable. Revert via git (no commits without approval) or worker rollback (wrangler rollback).
- Kill switch: disable detection rules without disabling backend auth.
- Emergency: set all rules to "log only".

## Total: ~9-14 weeks solo, part-time. Depends on Phase 0 findings.

META_IDENTITY_AND_ACCOUNT_LINKING.md
# Meta Identity and Account Linking: ScreechVR

## Meta User Verification (getUserProof)
- Server-side proof validation. Client requests proof from Meta, sends to backend, backend verifies with Meta's servers.
- Provides cryptographically verified proof that the user controls the Meta account.
- Starting reference: https://developers.meta.com/vr/documentation/spatial-sdk/ps-ownership/
- UNVERIFIED: exact API, SDK version requirements, eligibility, rate limits. Docs partially accessible.

## Meta Entitlement Check
- `Core.AsyncInitialize` + `Entitlements.IsUserEntitledToApplication`.
- ScreechVR's AppEntitlementCheck.cs: logs only, does NOT quit on failure (verified).
- Entitlement proves the user owns the app (Meta Store purchase). Does not prove identity.

## Meta App Attestation
- Native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` present (Ghidra confirmed).
- Reports: app signature, device integrity, OS state, security patch age.
- device_integrity_state: Advanced/Basic/NotTrusted (UNVERIFIED exact meaning).
- UNVERIFIED: API availability, permissions, verification endpoint, eligibility.
- Must be optional module. Fallback: server-side validation only.

## Account linking flow (proposed)
1. Client: Oculus Core.Initialize + Users.GetLoggedInUser -> Oculus ID + username.
2. Client: Request Meta User Proof (getUserProof) with server-generated nonce.
3. Client: Send proof + Oculus ID to backend (worker).
4. Backend: Verify proof with Meta's servers (server-to-server).
5. Backend: If verified, link/create PlayFab account (LoginWithCustomID with verified Oculus ID).
6. Backend: Issue session token (JWT) bound to verified identity.
7. Client: Use session token for all backend calls.

## Current ScreechVR flow (verified)
Oculus ID -> PlayFab LoginWithCustomID (no proof verification) -> PlayFab session ticket -> Photon token.
- VULNERABILITY: Client provides Oculus ID without proof. Modified client can claim any Oculus ID.
- FIX: Add Meta User Verification before PlayFab login. Backend verifies proof, then links account.

## What Meta identity proves vs what it doesn't
- PROVES: User controls the Meta account (hardware-bound).
- DOES NOT PROVE: Game integrity, no cheating, legitimate gameplay.
- Identity is one layer. Must combine with server-side validation and detection.

MODIFICATION_AND_RUNTIME_TAMPERING_THREATS.md
# Modification and Runtime Tampering Threats: ScreechVR

(See research/QUEST_MODIFICATION_THREAT_CATALOG.md for exhaustive version. This is the condensed deliverable.)

## Key threats applicable to ScreechVR

| Threat | Capability | ScreechVR impact | Defense | Confidence |
|---|---|---|---|---|
| APK repackaging | Modify APK, re-sign | Unauthorized builds | Meta entitlement + version enforcement | Confirmed |
| Asset modification (UABEA) | Edit textures/materials/prefabs | Visual mods, hitbox changes | Asset integrity (v2), server-side outcome validation | Confirmed |
| IL2CPP binary patching | Patch native code | Disable checks, modify values | Server-side enforcement, version check | Confirmed (harder than Mono) |
| Frida/injection | Hook methods, modify returns | Bypass client checks | Server-side enforcement, behavioral flags | Confirmed |
| Memory modification | Modify currency/position/flags | Grant gold, teleport, mod status | Server-side validation | Confirmed |
| Mod menus | Overlay cheat UI | Speed, fly, teleport toggles | Heuristic detection + server validation | Confirmed (concept) |
| Cosmetic modding | Replace textures/models | Visual only (harmless) | Log only, no enforcement | Confirmed |
| Network manipulation | Forged RPCs, invalid params, floods | Game state manipulation | Rate limits, param validation, ownership checks | Confirmed |
| Master client abuse | Force scene loads, manipulate room state | Disrupt gameplay | Minimize master authority, move state to backend | Confirmed |
| Ban evasion | Ignore KickIfBanned, new account | Banned player returns | Photon custom auth ban check on connect | Confirmed |
| Moderator spoof | Set AccountPref=Moderator | Mod menu access | Server-side moderator verification | Confirmed |
| Currency spoof | Modify _currency, call AddCurrency | Grant self gold | Move grants to server-side | Confirmed |
| Leaderboard faking | Submit fake scores | Fake rankings | Server-side score validation | Assumed |
| IAP bypass | Fake receipt, insufficient balance | Free cosmetics | PlayFab PurchaseItem validates server-side | Partial (client gates on local balance) |
| Null crash trigger | Spam NRE-inducing actions | Crash other clients | Guard null refs | Confirmed |
| RPC flood | ThusterController/Flash_Light | DoS within room | Per-player rate limits | Confirmed (open bugs) |

## Defense layers
1. Platform integrity (Meta attestation, if available) - signal only.
2. Application resilience (IL2CPP, version enforcement) - supplementary.
3. Identity/authentication (Meta User Verification, PlayFab) - strong.
4. Backend authorization (server-side validation) - strong.
5. Economy/inventory (server-side grants, price validation) - strong.
6. Multiplayer authority (heuristic detection, no dedicated server v1) - weak.
7. Detection/enforcement (flags, review, bans) - moderate.
8. Recovery/monitoring (logs, alerts, rollback) - moderate.

## What cannot be prevented (honest)
- Movement exploits (no dedicated server).
- Client-side visual mods (harmless).
- Frida/injection (server-side limits blast radius).
- Modified client ignoring client-side checks (server-side enforcement is the real gate).

MULTI_LAYER_ZERO_TRUST_ARCHITECTURE.md
# Multi-Layer Zero-Trust Architecture: ScreechVR

## 13 layers (independent, not additive)

| Layer | Component | What it protects | Independent? | If bypassed, what happens? |
|---|---|---|---|---|
| 1 | Meta User Verification | Identity proof | Yes (platform) | Attacker can claim any Oculus ID |
| 2 | Meta Entitlement Check | App ownership | Yes (platform) | Unentitled clients stay (currently log-only) |
| 3 | Meta Attestation (optional) | Device/app integrity | Yes (platform) | No device integrity signal (fallback: server validation) |
| 4 | PlayFab Auth | Account identity | Yes (backend) | Attacker can create accounts with any ID |
| 5 | Photon Custom Auth | Room admission | Yes (Photon) | Banned/invalid players can connect |
| 6 | Worker session validation | Session validity | Yes (worker) | Attacker can use stale/revoked sessions |
| 7 | Backend authorization | API permissions | Yes (worker) | Attacker can call any API |
| 8 | Server-side economy | Currency/inventory | Yes (PlayFab/worker) | Attacker can mint currency, equip unowned |
| 9 | Server-side bans | Enforcement | Yes (PlayFab) | Attacker can ignore bans |
| 10 | Detection engine | Behavioral flags | Yes (worker) | Suspicious behavior not flagged |
| 11 | Rate limiting | Abuse prevention | Yes (worker/Cloudflare) | Attacker can flood endpoints |
| 12 | Audit logging | Accountability | Yes (worker) | No evidence trail |
| 13 | Dashboard security | Admin protection | Yes (worker) | Unauthorized admin access |

## Key principle
5 checks on the same client are NOT 5 independent boundaries. True independence requires different trust domains:
- Platform (Meta): identity, entitlement, attestation.
- Backend (PlayFab + worker): auth, economy, bans, sessions.
- Network (Photon): room admission, RPC routing.
- Client (Unity): UI, input, local display (untrusted).

## Common-mode failure analysis
- If Meta platform is compromised: layers 1-3 fail. Layers 4-13 still function (backend independent).
- If PlayFab is compromised: layers 4, 8, 9 fail. Layers 1-3, 5-7, 10-13 still function (worker independent).
- If worker is compromised: layers 6, 7, 10, 11, 12, 13 fail. Layers 1-5, 8, 9 still function (PlayFab independent).
- If Photon is compromised: layers 5 fails. Layers 1-4, 6-13 still function (backend independent).

## If each layer is bypassed individually
- Layer 1 (Meta identity) bypassed: attacker claims any Oculus ID. Mitigation: server-side account linking with proof.
- Layer 4 (PlayFab auth) bypassed: attacker creates accounts with arbitrary IDs. Mitigation: Meta User Verification.
- Layer 6 (session validation) bypassed: attacker uses stale/revoked sessions. Mitigation: short token lifetime, heartbeat, revocation tracking.
- Layer 8 (economy) bypassed: attacker mints currency. Mitigation: server-side grants only.
- Layer 9 (bans) bypassed: banned player returns. Mitigation: Photon custom auth (server-side).
- Layer 10 (detection) bypassed: suspicious behavior not flagged. Mitigation: server-side validation is the real gate.

## Implementation priority
1. Layer 4 (PlayFab auth) - already exists.
2. Layer 6 (worker session validation) - new, high value.
3. Layer 5 (Photon custom auth) - new, blocks banned players.
4. Layer 8 (server-side economy) - fix currency vulnerability.
5. Layer 9 (server-side bans) - via custom auth.
6. Layer 2 (Meta entitlement) - fix log-only to quit.
7. Layer 1 (Meta User Verification) - add identity proof.
8. Layer 10 (detection) - flag + review.
9. Layer 11 (rate limiting) - per-endpoint.
10. Layer 12 (audit logging) - append-only.
11. Layer 13 (dashboard) - owner-only.
12. Layer 3 (Meta attestation) - optional, deferred.
13. Layer 7 (backend authorization) - RBAC.

PHOTON_AUTHENTICATION_BYPASSABILITY_AUDIT.md
# Photon Authentication Bypassability Audit: ScreechVR

## Current configuration (verified)
- PhotonVRManager.cs: ConnectAuthenticated(username, token) uses PlayFab token.
- Custom auth: PlayFab GetPhotonAuthenticationToken -> PhotonCustomAuthToken.
- PhotonNetwork.AuthValues set with custom auth params.
- AutomaticallySyncScene = true.
- JoinRoomOnConnect = true.
- DefaultQueue = "Default", DefaultRoomLimit = 10.

## What Photon Cloud validates
- Room membership, RPC routing, ownership transfer.
- Custom auth: Photon's servers call your backend URL to verify token (server-to-server).
- Photon enforces the auth result (allow/deny).

## What Photon Cloud CANNOT validate
- Game logic, movement, state, score, inventory.
- RPC parameters (relays without validation).
- Master client authority (master is a player).
- Scene sync (master can force scene loads).

## Bypassability assessment
- Can a modified client bypass Photon auth? NO, if custom auth is configured (Photon enforces server-side).
- Can a modified client use wrong auth path? YES, if "Allow anonymous clients" is enabled in Photon dashboard. UNVERIFIED.
- Can a modified client choose its own UserId? Photon assigns UserId from auth result. If auth is not configured, client can self-assign.
- Can a modified client ignore ban? YES, if ban is only checked client-side (KickIfBanned). Fix: add ban check to custom auth endpoint.
- Can a modified client send forged RPCs? YES, Photon relays without validation. Fix: server-side validation via backend.

## Photon custom auth response codes (verified from docs)
- ResultCode 0: incomplete (multi-step auth).
- ResultCode 1: success.
- ResultCode 2: failure.
- ResultCode 3: invalid parameters.
- Photon enforces: deny on failure, allow on success.

## What needs verification (dashboard access)
1. Is custom auth configured in Photon dashboard?
2. Is "Allow anonymous clients" disabled?
3. Is the auth URL pointing to the worker?
4. Are dev and prod app IDs separate?

## Conclusion
- Photon auth is NOT inherently bypassable IF properly configured.
- Current configuration is UNVERIFIED (dashboard not inspected).
- Even with proper auth, Photon only validates connection, not gameplay.
- Master client remains untrusted. Must minimize its authority.

PRODUCTION_OPERATIONS_AND_RECOVERY.md
# Production Operations and Recovery: ScreechVR

## Environment separation
- Dev: separate worker, separate D1, separate Photon app, separate PlayFab title.
- Staging: same as prod but isolated data.
- Prod: production worker, D1, Photon app, PlayFab title.
- Never use prod credentials in dev.

## Secret management
- All secrets in worker env vars (Cloudflare dashboard, encrypted at rest).
- No secrets in Unity client. No secrets in repo.
- Bot token in discord-bot/bot-token.txt (not in repo, .gitignored).
- Rotate on suspected compromise. Document rotation procedure.

## Monitoring
- Cloudflare Analytics (requests, errors, latency).
- Sentry (errors, crashes, free tier).
- Discord webhook for high-severity events.
- Dashboard health page (backend status, DB, Redis).

## Alerting
- Sudden spike in detections (>3x baseline).
- Unusual ban activity (>5 bans/hour).
- Auth failures (>10/5min).
- Backend outages (5xx >1%).
- API abuse (rate limit hits > threshold).
- Suspected dashboard compromise.
- Integrity verification failures (version mismatch spike).
- Mass false positives (sudden spike from one rule).
- Suspicious admin actions.

## Backup and recovery
- D1 automatic daily backups. Test restore quarterly.
- Worker code in git (version controlled).
- Dashboard code in git.
- PlayFab data: export via PlayFab API (manual or automated).
- Recovery: restore D1 from backup, redeploy worker, verify Photon custom auth.

## Incident response
1. Detect (alert fires).
2. Triage (severity: low/medium/high/critical).
3. Investigate (dashboard: players, flags, sessions, logs).
4. Contain (kill switch, rate limit, ban specific accounts).
5. Preserve evidence (export logs, flag data).
6. Recover (restore service, reverse incorrect bans).
7. Rotate credentials if compromised.
8. Document (incident report, lessons learned).

## Kill switch
- Disable specific detection rules without disabling backend auth.
- Protected by owner-only access + audit log.
- Emergency: set all detection rules to "log only" (no auto-action).

## Deployment
- Worker: wrangler deploy (Cloudflare CLI).
- Dashboard: Cloudflare Pages (git push -> auto-deploy).
- Rollback: wrangler rollback (worker), git revert (dashboard).
- No production changes without approval.

PROJECT_VULNERABILITY_AUDIT.md
# Project Vulnerability Audit: ScreechVR

## Confirmed vulnerabilities (verified against source code)

| ID | Vulnerability | File:Line | Severity | Exploit | Fix |
|---|---|---|---|---|---|
| V1 | Client-trusted currency | Oculus_Login.cs:269-344 | High | Grant self gold via AddCurrency(amount) | Move grants to worker/CloudScript |
| V2 | Client-trusted moderator status | Oculus_Login.cs:392-428 | High | Set AccountPref=Moderator client-side | Server-side role verification |
| V3 | Client-side ban enforcement | KickIfBanned.cs, Kick_Player.cs | High | Ignore Application.Quit, skip ban check | Photon custom auth ban check on connect |
| V4 | Client-trusted IAP | SpokesSigmaIAP.cs, BuyCosmetic.cs:33 | Medium-High | Buy with insufficient balance (cosmetic) | Server-side balance check |
| V5 | No movement validation | Player.cs (locomotion) | Medium | Speed/teleport exploits | Heuristic detection (flag+review) |
| V6 | Client-trusted cosmetics | GetCosmetics.cs, SecondaryCosmetics.cs | Medium | Equip unowned cosmetics | Backend inventory verification |
| V7 | Client-trusted leaderboard scores | GDH leaderboard | Medium | Submit fake scores | Server-side score validation |
| V8 | Tag/Infection RPC manipulation | TagPlayer.cs, TagManager.cs | Medium | Self-tag, infinite tags | Rate limit + ownership check |
| V9 | Master client abuse | PhotonVRManager.cs (AutomaticallySyncScene) | Medium | Force scene loads | Minimize master authority |
| V10 | Null crashes | PlayerSpawner, Hand_Physic, Monster_Track | Low-Medium | Crash other clients | Guard null refs |
| V11 | RPC floods | ThusterController, Flash_Light | Low | DoS within room | Per-player rate limits |
| V12 | AppEntitlementCheck log-only | AppEntitlementCheck.cs | Low | Unentitled clients stay | Quit on failure |
| V13 | UsernameValidator client-trusted | UsernameValidator.cs | Low | Spoof verified creator rig | Server-side check |

## Theoretical risks (unverified)
- CloudScript deployed (none in repo; verify in PlayFab dashboard).
- SpokesSigmaIAP receipt validation (not fully read).
- GDH leaderboard anti-cheat (unknown).
- ATM_TAB currency flow (not deeply read).
- Photon.VR package internals (DLL, inferred).
- PlayFab PurchaseItem price validation (assumed server-side).
- PlayFab bans server-side enforcement (assumed client-only).

## Critical verification needed
1. PlayFab UserData "Moderator" key: is it client-writable? (CRITICAL if yes)
2. CloudScript/Azure Functions deployed?
3. PlayFab PurchaseItem validates price server-side?
4. PlayFab bans enforced server-side?
5. SpokesSigmaIAP receipt validation path?

QUEST_ATTESTATION_AND_DEVICE_INTEGRITY.md
# Quest Attestation and Device Integrity: ScreechVR

## Meta User Verification (getUserProof)
- Server-side proof validation. Client requests proof with server-generated nonce.
- Backend verifies with Meta's servers (server-to-server).
- UNVERIFIED: exact API, SDK version, eligibility, rate limits. Docs partially accessible.
- Status: STRONG EVIDENCE (symbol present in native lib, Tomahawk uses it).

## Meta App Attestation
- Native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` present (Ghidra confirmed).
- Reports: app signature, device integrity, OS state, security patch age.
- device_integrity_state: Advanced/Basic/NotTrusted (UNVERIFIED exact meaning).
- security_update_pending_days: UNVERIFIED availability/meaning.
- UNVERIFIED: API availability to all developers, permissions, verification endpoint, eligibility, platform restrictions.
- Status: UNVERIFIED (docs gated, 404 on all tried URLs).

## Meta Entitlement Check
- AppEntitlementCheck.cs: Core.AsyncInitialize + Entitlements.IsUserEntitledToApplication. Logs only, does NOT quit on failure (verified).
- Proves app ownership (Meta Store purchase). Does not prove identity or device integrity.
- Status: VERIFIED (code read).

## Device integrity states (from Tomahawk research)
- ERR-5004: rooted device detected.
- ERR-5005: ADB (wireless debugging) enabled.
- ERR-5006: known cheat software detected.
- ERR-5001: modified application binary.
- ERR-5002: invalid application signature.
- ERR-5003: missing Meta security update.
- ERR-5101-5108: attestation failures (runtime error, timeout, no error, services disconnected, etc.).

## Handling policy (proposed)
- Verified trusted device: normal access.
- Potentially compromised (rooted, ADB, cheat software): flag + manual review. Do not auto-ban.
- Untrusted device: restrict sensitive actions (no purchases, no leaderboard submissions).
- Unsupported device: allow with warning (log for analysis).
- Attestation error: allow with flag (don't block on service failure).
- Network outage: allow with flag (service unavailable, not user's fault).
- Stale token: require re-verification (re-request proof).
- Suspicious but inconclusive: flag + increased monitoring.

## Fallback (if attestation unavailable)
- Server-side validation only: PlayFab auth + Photon custom auth + backend validation.
- No client attestation. Weaker but viable.
- Design attestation as optional module (enable if available, disable if not).

SECURITY_TEST_PLAN.md
# Security Test Plan: ScreechVR (Voideration)

## Authentication tests
- Invalid identity claim rejected (PlayFab LoginWithCustomID with wrong Oculus ID).
- Forged/expired session rejected (stale PlayFab session ticket).
- Stale attestation challenge rejected (if attestation used).
- Revoked session cannot continue (session revocation).
- Auth provider failure follows chosen policy (fail closed for auth).

## Privilege tests
- Normal player cannot promote themselves (set UserData "Moderator"="TRUE", verify server rejects).
- Player cannot access moderator APIs via Unity fields or Photon properties.
- Staff actions checked by backend (audit log records actor).
- Unauthorized dashboard requests rejected (401/403).
- Sensitive actions audited (ban, unban, rule change).

## Economy tests
- Currency cannot be minted (AddCurrency with arbitrary amount -> server rejects or audits).
- Purchases fail with insufficient balance (BuyCosmetic with low balance -> server rejects).
- Duplicate requests cannot duplicate rewards (idempotency key).
- Repeated redemption cannot claim same reward twice (/redeem with same code).
- Inventory/cosmetic ownership checked authoritatively (equip unowned -> flag).
- Invalid IAP claims cannot grant items (fake receipt -> server rejects).

## Multiplayer tests
- Invalid RPC params rejected (out-of-range, negative values).
- Non-owners cannot perform protected operations (ownership check).
- RPC spam rate-limited (ThusterController flood -> rate limit + flag).
- Invalid tag/infection transitions rejected (non-tagger tags).
- Old clients rejected (version mismatch -> OUTDATED scene).
- Master Client changes cannot grant backend privileges.
- Impossible movement cannot dictate trusted state (heuristic flag).

## Reliability tests
- Database outage does not cause free purchases or moderator access (fail closed).
- Retries do not duplicate economy transactions (idempotency).
- Rate limits behave correctly during bursts.
- Backups restorable in test environment.
- Admin can revoke compromised session.
- Alerts generated for high-severity abuse.
- Logs do not expose credentials or unnecessary PII.

## False-positive tests
- High latency (200ms RTT) does not trigger speed flag.
- Packet loss (10%) does not trigger teleport flag.
- VR movement edge cases (jumping, climbing, bouncing, TP_YA) do not trigger flags.
- Network jitter does not trigger flags.
- Legitimate moderator access does not trigger flags.

## Performance tests
- Client telemetry overhead < 1ms/frame.
- Backend validation < 50ms p99 at low scale.
- Dashboard load < 2s.
- Load test: k6 at 100/500/1000 concurrent, target p99 < 200ms.

## Recovery tests
- DB restore from backup: verify data integrity.
- Worker restart: verify session continuity.
- Kill switch: disable rule, verify no auto-action.
- Emergency rollback: unban all from specific rule.

Pass/fail criteria: all tests must pass before feature marked complete. No fabricated results.

SERVER_AUTHORITATIVE_GAMEPLAY_OPTIONS.md
# Server-Authoritative Gameplay Options: ScreechVR

## Option 1: Current stack (Photon PUN 2 + Cloudflare + PlayFab) - v1
- Photon Cloud relays. No game logic validation.
- Backend validates: currency, cosmetics, bans, version, moderator status.
- Movement: heuristic detection only (flag + review).
- Pros: minimal migration, low cost, extends existing stack.
- Cons: movement exploits can only be detected, not prevented. Master client abuse possible.
- Cost: $1-35/mo initial.

## Option 2: Photon Fusion (authoritative) - v2
- Fusion provides server-authoritative game state.
- Migration: rewrite networking (PhotonVRManager, PlayerSpawner, all RPCs).
- Effort: 20-30 weeks. Cost: $50-150/mo.
- Pros: authoritative movement, instant kicks, full game state validation.
- Cons: high migration cost, Photon Voice compatibility (need to verify), solo dev burden.

## Option 3: Nakama (integrated backend) - v2
- Authoritative matches, auth, economy, matchmaking in one platform.
- Migration: replace PlayFab + Photon. Rewrite networking.
- Effort: 20-30 weeks. Cost: $50-150/mo (hosting).
- Pros: single platform, authoritative, open source.
- Cons: high migration, ops burden, vendor lock-in.

## Option 4: Self-hosted Unity dedicated server - v3
- Unity dedicated server build on Hetzner/AWS.
- Full control over game logic, movement, validation.
- Effort: 30-40 weeks. Cost: $80-200/mo.
- Pros: maximum control, no vendor lock-in.
- Cons: highest complexity, solo dev ops burden.

## Recommendation
- v1: Option 1 (current stack + backend validation + heuristic detection).
- v2: Evaluate Option 2 (Photon Fusion) if cheating becomes serious. Migration cost justified only if movement exploits are a major problem.
- v3: Only if ScreechVR scales significantly and revenue justifies dedicated server ops.

## What each option can prevent
| Cheat | Option 1 (v1) | Option 2 (Fusion) | Option 3 (Nakama) | Option 4 (Dedicated) |
|---|---|---|---|---|
| Currency minting | Yes (backend) | Yes | Yes | Yes |
| Moderator spoof | Yes (backend) | Yes | Yes | Yes |
| Ban bypass | Yes (custom auth) | Yes | Yes | Yes |
| Movement exploits | Detect only | Prevent | Prevent | Prevent |
| Cosmetic spoof | Yes (backend) | Yes | Yes | Yes |
| Leaderboard faking | Partial (flag) | Yes (server validates) | Yes | Yes |
| Master client abuse | Minimize authority | N/A (server authoritative) | N/A | N/A |
| RPC flood | Rate limit | Server validates | Server validates | Server validates |

SOURCE_REGISTER.md
# Source Register: Voideration Research

## Official documentation
- Meta Quest Attestation API: https://developers.meta.com/vr/documentation/native/ps-attestation-api/ (GATED - 404 on all tried URLs)
- PlayFab login best practices: https://learn.microsoft.com/gaming/playfab/identity/player-identity/login/login-basics-best-practices
- Photon PUN 2 custom authentication: https://doc.photonengine.com/pun/current/connection-and-authentication/authentication/custom-authentication
- Photon PUN 2 Master Client and host migration: https://doc.photonengine.com/pun/current/gameplay/hostmigration
- Cloudflare Workers pricing: https://developers.cloudflare.com/workers/platform/pricing/
- Cloudflare D1 limits: https://developers.cloudflare.com/d1/platform/limits/
- Cloudflare D1 pricing: https://developers.cloudflare.com/d1/platform/pricing/
- Cloudflare Durable Objects and WebSockets: https://developers.cloudflare.com/durable-objects/best-practices/websockets/
- Nakama authoritative multiplayer: https://heroiclabs.com/docs/nakama/concepts/multiplayer/authoritative/
- Unity upgrade and service lifecycle: https://docs.unity.com/en-us/engine/7000.0/manual/upgrade-guides/upgrade-guide-unity63
- OWASP MASVS: https://mas.owasp.org/MASVS/
- OWASP API Security Top 10 2023: https://owasp.org/API-Security/editions/2023/en/0x11-t10/
- OWASP Cryptographic Storage Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html

## Local research files
- C:\Users\Void\Downloads\tomahawk stuff\ (all files, read-only)
- libTomahawkCore.so (5.3MB, static analysis only)

## Project files
- E:\! Project Screech\! Screech VR\Screech VR\ (Unity project, read-only during research)
- All scripts in Assets/Scripts/

## Research reports (in research/)
- 27 reports + consolidated architecture + critical review + technical map + threat catalog + this deliverable set.

## Confidence levels
- Confirmed: verified against source code or official docs.
- Strong evidence: multiple sources agree, code partially verified.
- Plausible: reasonable inference, not verified.
- Historical: was true in the past, current status unknown.
- Unverified: cannot confirm, needs additional access/testing.

TARGET_ARCHITECTURE.md
# Target Architecture: Voideration for ScreechVR

## Text diagram

```
[Quest Client (Unity/IL2CPP)]
    | Oculus Auth (Core.Initialize + Users.GetLoggedInUser)
    | PlayFab Login (LoginWithCustomID, Oculus ID)
    | Photon Connect (Custom Auth -> Cloudflare worker)
    | Heartbeat (every 10s -> worker)
    | Telemetry (movement samples, events -> worker)
    v
[Cloudflare Worker (trusted)]
    | /validate-session (PlayFab ticket + ban check)
    | /heartbeat (session liveness, duplicate detection)
    | /report-flag (telemetry -> detection rules)
    | /ban-check (real-time ban status)
    | /redeem (existing, PlayFab ticket required)
    | /motd (existing, public)
    | /updateplayers (existing, public, rate-limited)
    v
[D1 Database (SQLite)]
    sessions, players, flags, bans, audit_log, ccu_snapshots, webhooks, detection_rules, evidence
    v
[PlayFab (trusted backend)]
    Auth, inventory, currency, bans, title data, leaderboards, user data
    v
[Photon Cloud (semi-trusted relay)]
    Rooms, RPCs, sync, voice. Master client = player.
    Custom auth -> worker (server-to-server)
    v
[Cloudflare Pages (dashboard)]
    React + Tailwind + shadcn/ui. Auth: email+password+TOTP. JWT. RBAC.
    Reads from worker API only.
```

## Trust boundaries and sources of truth

| Data | Source of truth | Trusted? |
|---|---|---|
| Player identity | PlayFab (Oculus custom ID) | Yes |
| Session validity | Worker (PlayFab ticket validation) | Yes |
| Ban status | PlayFab (server-side) | Yes |
| Currency balance | PlayFab (server-side) | Yes (after fix) |
| Inventory/cosmetics | PlayFab (server-side) | Yes |
| Movement/position | Client (untrusted) | No |
| Game state (scores, kills) | Client (untrusted) | No |
| Room state | Photon (relay, master client untrusted) | Semi |
| Moderator status | PlayFab UserData (verify writability) | Unverified |
| CCU | Worker (heartbeat-based) | Yes |
| Audit log | Worker D1 (append-only) | Yes |

## Authentication and attestation sequence
1. Client: Oculus Core.Initialize + Users.GetLoggedInUser -> Oculus ID + username.
2. Client: PlayFab LoginWithCustomID (Oculus ID, CreateAccount=true).
3. Client: PlayFab GetPhotonAuthenticationToken -> Photon token.
4. Client: Photon ConnectUsingSettings with custom auth params (token).
5. Photon server: calls worker /validate-session with token.
6. Worker: validates PlayFab session ticket, checks ban status, returns allow/deny + UserId.
7. Photon enforces result. Client cannot bypass.

## Economy flow (after fix)
1. Client requests purchase (BuyCosmetic).
2. Client calls worker /purchase with item ID + session ticket.
3. Worker validates session, checks PlayFab inventory/balance, calls PlayFab PurchaseItem (server-side price validation).
4. Worker returns success/failure.
5. Client updates UI based on worker response (not local balance check).

## Ban enforcement flow
1. Admin issues ban in dashboard -> worker calls PlayFab BanUsers API + stores ban in D1 + Discord webhook.
2. Banned player on next login: Photon custom auth -> worker returns deny -> cannot connect.
3. Banned player in room: KickIfBanned polls (5s delay) -> displays ban screen -> quits.
4. Real-time kick: requires Photon Server (v2). For v1, accept 5s delay.

## Service failure behavior
- PlayFab down: fail closed for auth (deny new connections), fail open for gameplay (existing sessions continue), bans still enforced from cache.
- Worker down: Photon custom auth fails -> Photon denies connections (fail closed). Existing sessions continue.
- D1 down: audit log/flags delayed, core auth still works (worker can validate via PlayFab directly).
- Photon down: game unplayable (no multiplayer). Single-player not affected.

## Secret responsibilities
- Worker env vars: PlayFab title ID, PlayFab admin key (if needed), JWT secret, TOTP secret.
- No secrets in Unity client. No secrets in repo.
- Bot token in discord-bot/bot-token.txt (not in repo, .gitignored).

TOKEN_AND_SESSION_SECURITY.md
# Token and Session Security: ScreechVR

## Token types (distinct, not interchangeable)

| Token | Issuer | Purpose | Lifetime | Verified by |
|---|---|---|---|---|
| Oculus ID | Meta Platform | Hardware-bound identity | Session | PlayFab (Custom ID) |
| Meta User Proof | Meta Platform | Proof of account control | One-time (nonce-bound) | Backend (server-to-server) |
| PlayFab Session Ticket | PlayFab | Session auth | Session (expires) | PlayFab API |
| PlayFab Photon Token | PlayFab | Photon custom auth | Short (minutes) | Photon (server-to-server) |
| Meta Attestation Token | Meta Platform | Device/app integrity | Short (minutes) | Backend (server-to-server) |
| Voideration JWT | Voideration backend | Dashboard/API auth | 15min access + 7d refresh | Backend (HS256) |
| Discord bot token | Discord | Bot API auth | Permanent (rotate on compromise) | Discord |

## Session security
- Session creation: on PlayFab login (Oculus custom ID).
- Session expiry: PlayFab session ticket expires (duration varies).
- Session revocation: PlayFab doesn't support explicit revocation. Voideration must track session IDs and reject revoked ones.
- Duplicate session: same PlayFab ID, two active Photon sessions. Detection via heartbeat.
- Replay: PlayFab session ticket can be replayed within its lifetime. Mitigation: nonce binding, short lifetime, backend session tracking.

## Token flow (verified)
1. Oculus auth -> Oculus ID + username.
2. PlayFab LoginWithCustomID (Oculus ID) -> PlayFab session ticket.
3. PlayFab GetPhotonAuthenticationToken -> Photon token.
4. Photon ConnectUsingSettings (custom auth params include Photon token).
5. Photon server calls worker /validate-session with Photon token.
6. Worker validates PlayFab session ticket, checks ban status, returns allow/deny.
7. Photon enforces result.

## Security requirements
- Tokens must be short-lived (PlayFab session tickets: hours, Photon tokens: minutes).
- Tokens must be bound to the session (not reusable across sessions).
- Revocation must be enforced server-side (worker tracks session IDs).
- Replay protection: nonce binding, timestamp validation.
- No tokens in client logs or crash reports.
- No tokens in PlayerPrefs or local storage.

UNVERIFIED_CLAIMS_AND_OPEN_QUESTIONS.md
# Unverified Claims and Open Questions: ScreechVR

## Unverified claims (from previous research)

| Claim | Source | Status | Evidence needed |
|---|---|---|---|
| PlayFab UserData "Moderator" is client-writable | Technical map + review | UNVERIFIED | PlayFab dashboard: check UserData write permissions |
| No CloudScript deployed | Repo search (grep) | UNVERIFIED | PlayFab dashboard: check CloudScript/Azure Functions |
| PlayFab PurchaseItem validates price server-side | Assumed from PlayFab docs | UNVERIFIED | PlayFab dashboard: check catalog config |
| PlayFab bans are client-only enforcement | KickIfBanned.cs + technical map | UNVERIFIED | PlayFab dashboard: check ban enforcement settings |
| Meta attestation available | Native symbol in .so | UNVERIFIED | Meta developer portal access |
| SpokesSigmaIAP receipt validation | Not fully read | UNVERIFIED | Read SpokesSigmaIAP.cs + PlayFab catalog |
| GDH leaderboard anti-cheat | Unknown | UNVERIFIED | Inspect GDH package |
| ATM_TAB currency flow | Not deeply read | UNVERIFIED | Read ATM_TAB.cs + Atm_Manager.cs |
| Photon custom auth configured | Assumed | UNVERIFIED | Photon dashboard inspection |
| "Allow anonymous clients" disabled | Assumed | UNVERIFIED | Photon dashboard inspection |
| Dev/prod app IDs separate | Assumed | UNVERIFIED | Photon dashboard inspection |
| D1 write throughput sufficient | Assumed | UNVERIFIED | Load test (k6) |
| Free tier limits sufficient | Assumed | UNVERIFIED | Monitor usage post-launch |
| AppEntitlementCheck intended to quit | Only logs | UNVERIFIED | Check intended behavior |

## Open questions (require user decision)

1. PlayFab UserData "Moderator" writability (CRITICAL).
2. Currency grants: CloudScript or client-side with audit?
3. Meta attestation availability.
4. Photon custom auth willingness.
5. Dashboard hosting: Cloudflare Pages or VPS?
6. MFA: owner only or all admins?
7. Evidence storage: telemetry only or screenshots/video?
8. Real-time kick: 5s delay or Photon Server?
9. CloudScript/Azure Functions deployed?
10. PlayFab PurchaseItem price validation?
11. Multi-game or ScreechVR-only? (Scoped to ScreechVR per user.)
12. Budget ceiling and solo-dev time availability?
13. Evidence storage needs.
14. MFA requirement for all admins or only owners?
15. Data retention policy preferences.
16. Public ban appeal flow or Discord/support tickets?

## Conflicts between reports
- Technical map says no CloudScript found; verify in PlayFab dashboard.
- Technical map says AppEntitlementCheck only logs; verify intended behavior.
- Currency: technical map says client-trusted; PlayFab AddUserVirtualCurrency validates session but not amount (confirmed by PlayFab docs).
- Earlier research said "Tomahawk Photon.IsAvailable() returns false" (older SDK stub). Not relevant to ScreechVR.
- Cost estimates: initial report said 10-17 weeks; revised to 12-20 weeks (part-time). Final: 9-14 weeks (focused MVP).

voideration-screechvr-architecture.md
# Voideration Anti-Cheat - ScreechVR-Specific Architecture & MVP Plan

Research-only. No implementation. Combines:
- `docs/screechvr-technical-map-2026-10-28.md` (Unity investigation, primary source of truth)
- `docs/voideration-anticheat-research.md` (Tomahawk + generic research)
- `docs/voideration-anticheat-review.md` (critical review)

Voideration is for ScreechVR only. No multi-game, no cross-game ban sharing.

## 1. Confirmed vulnerabilities (verified against project files)

| # | Vulnerability | Evidence (path:line) | Severity | Exploit |
|---|---|---|---|---|
| V1 | Client-trusted currency | `Oculus_Login.cs:269-344` AddCurrency/RemoveCurrency update `_currency` locally before server call; BuyCosmetic checks local balance (`BuyCosmetic.cs:33`) | High | Grant self gold, buy cosmetics free |
| V2 | Client-trusted moderator status | `Oculus_Login.cs:392-428` "Moderator" key read from PlayFab UserData; Check_Mod.cs sets AccountPref after 5s timeout | High | Set AccountPref=Moderator, open mod menu |
| V3 | Client-side ban/kick enforcement | `KickIfBanned.cs` polls GetAccountInfo; `Kick_Player.cs` OnTriggerEnter -> Application.Quit; both client-side, ignorable | High | Modified client ignores bans/kicks |
| V4 | Client-side IAP grant | `SpokesSigmaIAP.cs` + BuyCosmetic; price check local; PlayFab PurchaseItem validates server-side but client gates on local balance | Medium-High | Desync currency vs server |
| V5 | No server-side movement validation | `NewGorillaLocomotionScripts/Player.cs` locomotion all client-side; no server validation anywhere | Medium | Speed/teleport exploits |
| V6 | Client-trusted cosmetics | `GetCosmetics.cs`/`SecondaryCosmetics.cs`: cosmetic ids pushed via Photon custom props; others apply them without ownership check | Medium | Equip unowned cosmetics |
| V7 | Client-trusted leaderboard scores | GDH leaderboard client-submitted; no server verification observed | Medium | Fake scores |
| V8 | Tag/Infection client RPCs | TagPlayer uses Photon RPCs for tagger assignment and "tagged" state | Medium | Self-tag, infinite tags |
| V9 | Room scene sync abuse | `PhotonVRManager.AutomaticallySyncScene=true`; master client can force scene loads | Medium | Force clients into PVP/other scenes |
| V10 | Null crashes exploitable | PlayerSpawner playerTemp, Hand_Physic grabbable, Monster_Track TMP unguarded | Low-Medium | Crash other clients / self |
| V11 | ThusterController/Flash_Light RPC floods | Open bugs from prior audits | Low | DoS within room |
| V12 | AppEntitlementCheck log-only | `AppEntitlementCheck.cs` logs but does not quit on failure | Low | Unentitled clients stay |
| V13 | UsernameValidator client-trusted content creator check | Reads PlayFab title data "CONTENT_CREATORS", swaps prefab client-side | Low | Spoof verified creator rig |

### Confirmed trust assumptions (from technical map)
- Moderator status stored in PlayFab UserData (client-writable key "Moderator") - a client can write "TRUE" to their own UserData unless PlayFab rules block it. VERIFY: PlayFab UserData write permissions.
- Currency is PlayFab virtual currency; AddUserVirtualCurrency is server-authoritative in PlayFab (client calls it but PlayFab validates the caller's session). The client-trust issue is the local `_currency` cache desync, not server grant. PlayFab's AddUserVirtualCurrency requires a valid session ticket and the amount is specified by the client - PlayFab does NOT validate the amount against a server-defined price. So a client can call AddUserVirtualCurrency with arbitrary amount IF they have a valid session ticket. This is a real vulnerability: PlayFab's client API allows the client to add currency. Mitigation: move currency grants to CloudScript/Azure Functions or PlayFab's Economy v2 with server-defined prices. CONFIRMED: PlayFab client API AddUserVirtualCurrency accepts client-specified amount.
- PurchaseItem: PlayFab validates price server-side against catalog, but client gates on local balance (cosmetic issue, not security).

## 2. Theoretical risks (not verified)
- CloudScript/Azure Functions deployed (none found in repo; verify in PlayFab dashboard).
- SpokesSigmaIAP receipt validation (not fully read).
- GDH leaderboard anti-cheat (unknown).
- ATM_TAB currency flow (not deeply read).
- Photon.VR package internals (DLL, behavior inferred).

## 3. Architecture: trusted vs untrusted

### What exists today (no dedicated game server)
- Photon Cloud: relay only. Master client is a player. No game logic enforcement.
- PlayFab: auth, inventory, currency, bans, title data, leaderboards. Client API allows some client-driven writes (currency add, userdata).
- Cloudflare worker: CCU counter, /link reward, MOTD, /redeem. Already has ADMIN_CHANNEL_ID.
- No dedicated authoritative server.

### Voideration enforcement points (what can be trusted)
1. PlayFab backend (trusted): purchase validation, inventory, bans (server-side via admin API), title data, leaderboards (if configured server-side).
2. Cloudflare worker (trusted): CCU, /redeem, /motd, can be extended with validation endpoints.
3. Photon Cloud custom auth (trusted): Photon's servers call YOUR backend to verify session tokens. Enforced by Photon, not client.
4. Unity client (untrusted): all game logic, movement, currency display, moderator status.

### What remains vulnerable without a dedicated server
- Movement/speed/teleport: cannot be authoritatively validated without a server running game logic. Photon Cloud relays positions. Mitigation: heuristic detection (client-reported anomalies + server-side plausibility checks on reported positions) + manual review. NOT auto-ban.
- Real-time game state (scores, health, monster kills): client-authoritative. Mitigation: validate final results server-side where possible (e.g., level completion requires server-verified conditions).
- Master client abuse: any player can become master and manipulate room state. Mitigation: minimize master-client authority; move critical room state to backend.

## 4. Proposed Voideration architecture (ScreechVR-specific)

### Components
- **Unity client (ScreechVR)**: thin telemetry reporter. Sends session nonces, heartbeats, movement samples (for detection only, not enforcement), integrity results. Never trusts client verdicts. No secrets in client.
- **PlayFab**: auth (Oculus custom ID), inventory, currency (move grants to CloudScript/Functions), bans, title data, leaderboards, user data.
- **Cloudflare worker (extended)**: existing CCU + /link + /motd + /redeem. Add: /validate-session, /report-flag, /heartbeat, /ban-check. Worker is trusted (runs on Cloudflare edge, secrets in env).
- **Voideration backend (new, small VPS or Cloudflare Workers + D1/KV)**: dashboard API, detection rules, audit log, webhook dispatch. Could be an extension of the existing worker (simplest) or a small Node service. Recommend: extend the existing Cloudflare worker + D1 (SQLite) for simplicity and cost, with a separate auth-protected dashboard.
- **Dashboard (private, owner-only)**: React + Tailwind, hosted on Cloudflare Pages or the worker. Auth: email+password + TOTP MFA, JWT, RBAC (Owner only for now, but design for Admin/Moderator/Viewer).

### Data flow
1. Player launches ScreechVR -> Oculus auth -> PlayFab login (Oculus custom ID) -> PlayFab session ticket.
2. Client calls PlayFab GetPhotonAuthenticationToken -> Photon custom auth token.
3. Client connects to Photon with custom auth -> Photon's servers call your backend (Cloudflare worker /validate-session) with the PlayFab token. Backend validates session, returns allow/deny + ban status.
4. Client joins room, spawns player. Heartbeat every 10s to backend (session liveness, duplicate detection).
5. Client reports telemetry (movement samples, events) to backend for detection. Backend evaluates rules, produces flags with confidence.
6. High-confidence flags -> review queue (not auto-ban). Admin reviews in dashboard, issues ban via PlayFab (server-side admin API) + Discord webhook.
7. Backend pushes ban status to client via PlayFab (client checks on login) or via Photon (room-level kick).

### Database schema (ScreechVR-specific, minimal)
- `sessions` (id, playfab_id, oculus_id, photon_user_id, room_code, game_mode, started_at, ended_at, severity, vpn, client_version)
- `players` (id, playfab_id, oculus_id, username, first_seen, last_seen, total_bans, total_flags)
- `flags` (id, session_id, player_id, rule_id, severity, confidence, evidence_key, created_at, reviewed_by, status)
- `detection_rules` (id, name, enabled, threshold, action, version, game_mode_filter)
- `bans` (id, player_id, type, reason_internal, reason_user, issued_by, issued_at, expires_at, revoked_at, playfab_ban_id)
- `evidence` (id, flag_id, type, storage_key, created_at)
- `audit_log` (id, actor_id, action, target_type, target_id, reason, created_at, prev_hash)
- `ccu_snapshots` (id, ts, count)
- `webhooks` (id, type, url, headers_enc, events, active)

Use D1 (SQLite on Cloudflare) for simplicity. Postgres if you outgrow it.

### Session validation contract (Photon custom auth)
Photon calls your backend URL with the player's auth params. Your backend:
- Extracts PlayFab session ticket from auth params.
- Validates with PlayFab (GetAccountInfo or validate session).
- Checks ban status (PlayFab GetAccountInfo / ban list).
- Returns 200 with `{ ResultCode: 0 (allow) or 1 (deny), Message: "...", UserId: playfab_id }`.
- Photon enforces the result. Client cannot bypass.

## 5. Detection rules (ScreechVR-specific, derived from technical map)

| Rule ID | Name | Condition | Severity | Action | Notes |
|---|---|---|---|---|---|
| S-001 | Impossible speed | reported speed > 1.3 * maxJumpSpeed (from Player.cs) for >= 3 samples | high | flag | Account for jump multiplier, network latency |
| S-002 | Teleport | position delta > maxTeleportDistance in one frame | high | flag | Exclude legitimate TP_YA usage (track TP state) |
| S-003 | Invalid currency grant | AddCurrency called with amount > configured max per action | high | flag + review | Requires backend to track grant amounts |
| S-004 | Moderator spoof | AccountPref set to Moderator but PlayFab UserData "Moderator" != "TRUE" | high | flag | Requires backend to verify PlayFab UserData |
| S-005 | Banned player in room | player in room whose PlayFab account is banned | high | kick (via Photon room kick) | Backend ban check on join |
| S-006 | Duplicate session | same PlayFab ID, two active Photon sessions | medium | flag + kick older | Heartbeat-based |
| S-007 | Cosmetic spoof | player equips cosmetic not in their PlayFab inventory | medium | flag | Backend inventory check |
| S-008 | RPC flood | > N RPCs/sec from one player (ThusterController, Flash_Light pattern) | medium | flag | Rate limit per player |
| S-009 | Invalid tag (Tag mode) | tag RPC from non-tagger, or tag without collision | medium | flag | Tag gamemode specific |
| S-010 | Leaderboard anomaly | score delta exceeds theoretical max per time window | medium | flag | GDH leaderboard |
| S-011 | Version mismatch | client version != server version (LOCKDOWN/OUTDATED title data) | low | kick | Already exists via title data |
| S-012 | Null crash trigger | rapid NRE-inducing actions (e.g., spamming grab on null objects) | low | flag | Crash prevention |

Auto-action: NEVER auto-ban on client-reported signals alone. Flag -> review queue -> human decision. Kicks allowed for ban status / version mismatch / duplicate session (server-verified).

## 6. Ban enforcement (ScreechVR-specific)

- PlayFab bans are the source of truth. When admin issues ban in dashboard:
  1. Call PlayFab admin API (BanUsers) with playfab_id, ban type, duration, reason.
  2. Store ban record in Voideration DB (for dashboard history).
  3. Send Discord webhook.
  4. Photon: optionally kick from current room via backend-triggered Photon room kick (requires Photon Server or a trusted relay; with Photon Cloud, kick is client-side only - rely on KickIfBanned polling + ban check on next login).
- KickIfBanned.cs currently polls every 5s; keep it but add server-side ban check on Photon custom auth (so banned players can't even connect).
- For real-time kick enforcement without dedicated server: use Photon's room-level kick via a trusted plugin or accept 5s delay. Document this limitation.

## 7. Dashboard (owner-only, ScreechVR-specific)

Pages:
1. Overview: live CCU (from worker), active bans, pending flags, recent events, backend health.
2. Players: search by PlayFab ID / Oculus ID / username, session history, flags, bans.
3. Player detail: overview (first/last seen, game mode history), failed sessions, bans timeline, IPs/devices, cosmetics owned, currency balance (read-only from PlayFab).
4. Flags: review queue, by rule, confidence, evidence inspection, approve/dismiss.
5. Bans: active/expired/revoked, issue/revoke with reason, Discord webhook.
6. Detection rules: enable/disable, thresholds, per-game-mode filters, version.
7. Audit log: admin actions with actor/reason/timestamp.
8. Webhooks: Discord config (reuse existing worker webhook setup).
9. Settings: retention, version enforcement, maintenance mode (LOCKDOWN title data).

Auth: email+password + TOTP MFA (owner only for v1). JWT access (15min) + refresh (7d). Rate limit login. IP allowlist optional.

## 8. MVP implementation plan (prioritized)

### Stage 1: Backend foundation (2-3 weeks)
- Cloudflare worker extensions: /validate-session, /heartbeat, /report-flag, /ban-check.
- D1 database schema (sessions, players, flags, bans, audit_log, ccu_snapshots).
- Photon custom auth integration (verify endpoint contract with Photon dashboard).
- PlayFab integration: validate session tickets, check bans, read inventory.
- Acceptance: Photon connection fails for banned/invalid sessions; heartbeat tracks CCU.

### Stage 2: Detection (2-3 weeks)
- Movement telemetry collection (client reports samples, backend stores).
- Rules S-001, S-002, S-005, S-006, S-008 (server-verifiable or low-risk).
- Flag creation with confidence + evidence storage.
- Review queue API.
- Acceptance: flags created for synthetic cheat replays; no false positives on clean sessions.

### Stage 3: Dashboard (2-3 weeks)
- Auth (email+password+TOTP), JWT, RBAC.
- Overview, players, flags, bans, audit log pages.
- Ban issue/revoke with Discord webhook.
- Acceptance: owner can log in, view flags, issue ban, ban appears in PlayFab.

### Stage 4: Currency/cosmetic protection (1-2 weeks)
- Move currency grants to PlayFab CloudScript or worker (server-side price validation).
- Backend inventory verification for cosmetics.
- Acceptance: client cannot grant itself currency; cosmetic spoof flagged.

### Stage 5: Testing & hardening (1-2 weeks)
- Pen test (BOLA, mass assignment, rate limit bypass).
- Load test (k6, target p99 < 200ms at 500 concurrent).
- False-positive regression on real session data.
- Backup restore drill.

### Stage 6: Controlled rollout (1 week)
- Staging with PCDEBUG (two-editor test).
- Limited rollout to QA build.
- Monitoring + alerting.
- Gradual expansion.

Total MVP: ~9-14 weeks solo, part-time. Cost: $10-35/mo initial (Cloudflare free tier + D1 free + worker free), $0-50/mo at 1k CCU (Cloudflare scales cheaply). Meta attestation: optional, deferred until verified.

## 9. Conflicts between reports / missing information

1. CloudScript: technical map says none found in repo. Verify in PlayFab dashboard whether any CloudScript/Azure Functions are deployed. If yes, currency flow may already be server-validated (changes V1 severity).
2. PlayFab PurchaseItem price validation: assumed server-side, verify via dashboard/catalog config.
3. Bans server-side enforcement: assumed client-only (KickIfBanned), verify if PlayFab bans are enforced by Photon custom auth.
4. PhotonVRManager.OnJoinedRoom/SetCosmetic exact lines not fully captured (file is 585 lines). Verify cosmetic sync path.
5. ATM_TAB/Atm_Manager currency flow not deeply read. Verify.
6. SpokesSigmaIAP receipt validation not verified. Verify.
7. GDH leaderboard submission path and anti-cheat unknown.
8. AppEntitlementCheck only logs, does not quit. Verify intended behavior.
9. Meta attestation availability unverified (docs gated).
10. Whether PlayFab UserData "Moderator" key is client-writable (default PlayFab UserData is client-writable). VERIFY: this is a critical security gap if true.

## 10. Decisions needed from you

1. **PlayFab UserData "Moderator" key**: Is it client-writable in your PlayFab title settings? If yes, this is an immediate critical vulnerability (any player can set themselves as mod). Fix: move moderator status to PlayFab's read-only server data or a custom claim. Do you want me to verify this in the dashboard, or do you know?
2. **Currency grants**: Currently client calls AddUserVirtualCurrency. Do you want to move this to CloudScript/Functions (server-side price validation), or keep client-side with backend audit logging only?
3. **Meta attestation**: Do you have (or can you get) Meta developer portal access to verify the Device Application Integrity API? If not, Layer One is unavailable and we rely on server-side validation only.
4. **Photon custom auth**: Are you willing to configure a custom auth URL in the Photon dashboard pointing to your worker? This is required for server-side ban enforcement on connect.
5. **Dashboard hosting**: Cloudflare Pages (free, static) + worker API, or a separate VPS? Recommend Cloudflare for cost.
6. **MFA**: TOTP for owner only, or all admins? (Only owner for v1 recommended.)
7. **Evidence storage**: Telemetry only, or screenshots/video? Recommend telemetry only for v1 (cost + privacy).
8. **Real-time kick enforcement**: Accept 5s delay (KickIfBanned poll) or invest in Photon Server for instant kick? Recommend 5s delay for v1.

---

STOP: consolidated architecture complete. No implementation performed. Awaiting your explicit approval before any code is written.

voideration-all-research.md
# Voideration Anti-Cheat: Complete Research (All Categories)

Single consolidated document. Research-only, no implementation. Combines all research reports from `research/` and `docs/`. Source reports remain intact.

---

## Category 1: Project Inspection (ScreechVR)

ScreechVR is a Unity 2021.3 LTS VR multiplayer game (URP 12.1.13) on Photon PUN 2 + Photon Voice, PlayFab, Meta/Oculus SDK, Cloudflare worker, gorilla-tag-style locomotion.

**Key scripts:** Oculus_Login.cs (auth/currency/ban/MOTD), ScreechApi.cs (worker HTTP), PhotonVRManager.cs (networking/rooms/cosmetics), PlayerSpawner.cs, UsernameValidator.cs, AppEntitlementCheck.cs, KickIfBanned.cs, Kick_Player.cs, LevelSelect.cs, MapLoader.cs, sceneyessss.cs, Gamemode_System.cs, GamemodeManager.cs, GetCosmetics.cs, SecondaryCosmetics.cs, BuyCosmetic.cs, TagManager.cs, TagPlayer.cs, TagLeaderboard.cs, BestJumpscare.cs, NewGorillaLocomotionScripts/Player.cs, Hand_Physic.cs.

**Auth flow:** Oculus Core.Initialize + Entitlements (log only) -> LoginWithCustomID (Oculus ID) -> PlayFab session ticket -> GetPhotonAuthenticationToken -> Photon custom auth. Nickname via PlayFab UpdateUserTitleDisplayName.

**Currency:** Currency_Code="HC", _currency client-held. AddCurrency/RemoveCurrency update local first, server call after, revert on error. BuyCosmetic checks local balance. PlayFab AddUserVirtualCurrency accepts client-specified amount (server validates session, not amount).

**Bans:** KickIfBanned polls GetAccountInfo every 5s (client-side). HandleBan parses PlayFab ban error. No server-side enforcement.

**Movement:** GorillaLocomotion.Player - sphere-casts, gravity 2*9.8*dt*dt, slipPercentage, jump velocity clamped. TP_YA disables ALL non-trigger colliders, teleports, re-enables.

**Rooms:** SandboxMatchmaking (join by code/population), LevelSelect (LVL1-7 toggle), Gamemode_System (Sandbox/PVP switch). 9 monsters in Game scene.

**Cosmetics:** GetCosmetics/SecondaryCosmetics keyed by GO name, sync via Photon custom props. PlayFab UserData "EQUIPPED". BuyCosmetic client-side purchase.

**Packages:** URP 12.1.13, Oculus XR 3.3.0, OpenXR 1.9.1, XR Interaction Toolkit 2.5.4, Photon PUN2+Voice, PlayFab SDK, Bakery, Meta XR, Beebyte Obfuscator, ParrelSync, etc.

**External services:** PlayFab, Photon Cloud, Cloudflare worker, Discord bot, Oculus Platform/IAP.

**Unverified:** CloudScript deployment, SpokesSigmaIAP receipt validation, GDH leaderboard anti-cheat, ATM_TAB currency flow, Photon.VR package internals.

---

## Category 2: Threat Model (ScreechVR)

**Trust boundaries:** Client (untrusted) -> Photon Cloud (semi-trusted relay, master client is a player) -> PlayFab/Cloudflare worker (trusted) -> No dedicated server.

**Top threats (by likelihood x impact):**
1. Client-trusted currency (grant self gold) - High/High
2. Moderator spoof (self-promote via PlayFab UserData) - High/High
3. Ban evasion (ignore KickIfBanned) - High/High
4. Movement exploits (speed/teleport) - High/Medium
5. Cosmetic spoof (equip unowned) - Medium/Medium
6. Leaderboard faking - Medium/Medium
7. IAP receipt bypass - Low-Medium/High
8. Master client abuse (scene sync) - Medium/Medium
9. RPC flood (ThusterController, Flash_Light) - Medium/Low
10. Null crash exploitation - Low-Medium/Low
11. Tag/Infection RPC manipulation - Medium/Low
12. Version spoofing - Low/Medium
13. Duplicate sessions - Medium/Low
14. Alt account ban evasion - Medium/Medium

**False-positive risks:** VR movement unusual (jumping, climbing, bouncing). Network latency/jitter. TP_YA legitimate teleport. Mod menu access by real moderators.

**Cannot be reliably detected:** Client-only visual mods, movement within plausible bounds, anything a modified client can fake in telemetry.

---

## Category 3: Unity and Quest Modding Threats

- APK extraction, resource modification, repackaging with different key.
- UABEA can edit Unity assets (textures, materials, prefabs, scenes).
- Mono builds: dnSpy/ILSpy can decompile/modify C#. IL2CPP: harder but native binary patching possible.
- Runtime instrumentation (Frida): hook methods, modify returns, inspect memory. Bypasses client-side checks.
- Asset modification: harmless visual mods vs gameplay-affecting. Only flag competitive integrity impact.
- Network manipulation: RPC abuse, forged params, floods, ownership manipulation, scene sync abuse.
- Platform: Quest (Android) has no kernel access. Meta attestation available (unverified).

---

## Category 4: Frida and Runtime Tampering

- Frida can hook methods, modify arguments/returns, inspect memory, bypass client checks.
- Detection via process/library name checks is weak (trivially bypassed, false positives).
- Behavioral anomalies (impossible movement, RPC floods) are harder to fake but still client-reported.
- Defense: server-side enforcement of all security decisions. Client detection = low-confidence flag only.
- Never auto-ban on Frida detection alone.

---

## Category 5: Device Integrity and Attestation

- Meta attestation: native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` present in libTomahawkCore.so (confirmed via Ghidra). API docs inaccessible (404). Availability, permissions, verification endpoint UNVERIFIED.
- Tomahawk requires Meta Data Use Permissions: User ID, User Profile, Device Ban.
- ERR-5xxx: modified binary, invalid signature, rooted, ADB, cheat software, attestation failures.
- Fallback: server-authoritative validation only (no client attestation). Viable but weaker.
- Android Key Attestation not available on Quest (no Google Play).

---

## Category 6: Anti-Reverse-Engineering and Anti-Tamper

**What helps (proportionate):** IL2CPP (already used), strip debug symbols (already), signed release manifests (VERISION_CODE title data), build IP whitelist, protected/unprotected build status, server-side version enforcement, move sensitive logic to backend.

**What does NOT help:** Obfuscation as security boundary (Beebyte Obfuscator is cosmetic), hiding strings, client-side checks, "anti-tamper" DLLs.

**Recommended v1:** IL2CPP, strip symbols, version enforcement, move currency/moderator/ban to backend, build IP whitelist.

**NOT recommended v1:** Custom anti-tamper DLLs, kernel-level protection, aggressive obfuscation.

---

## Category 7: Trust Boundaries and Server Security

| Component | Trust | Can validate | Cannot validate |
|---|---|---|---|
| Unity client | Untrusted | Input, UI | Movement, currency, moderator, bans, cosmetics |
| Photon Cloud | Semi-trusted relay | Room membership, RPC routing | Game logic, movement, state |
| Photon Master Client | Untrusted player | Room properties (convenience) | Security decisions |
| PlayFab | Trusted | Auth, inventory, currency (server-side), bans, title data, leaderboards | Real-time game state |
| Cloudflare worker | Trusted | CCU, /redeem, /motd, session validation, ban check | Game logic |
| Dedicated server | None exists | Would be needed for authoritative movement, scoring, bans | N/A |

**Photon custom auth:** Photon's servers call YOUR backend to verify session tokens. Backend validates, Photon enforces. Client cannot bypass.

**PlayFab vulnerability:** AddUserVirtualCurrency accepts client-specified amount. PlayFab validates session but not amount. Mitigation: move currency grants to CloudScript/Azure Functions or PlayFab Economy v2.

**What requires dedicated server:** Movement validation, real-time game state, instant kick enforcement, server-side anti-cheat detection.

---

## Category 8: Network Abuse and Gameplay Validation

**Movement (from Player.cs):** Sphere-casts, gravity 2*9.8*dt*dt, slipPercentage, jump velocity clamped. TP_YA legitimate teleport (disables all non-trigger colliders).

**Validation thresholds (derive from actual mechanics):**
- Max speed: from maxJumpSpeed + jumpMultiplier. Account for latency, packet loss, VR jitter.
- Teleport: track TP_YA state; flag deltas > maxTeleportDistance when TP not active.
- Speed: flag sustained speed > 1.3 * max legitimate for >= 3 samples.
- Gravity: flag if fall faster than 2*9.8*dt*dt allows.
- Climbing: flag grab at impossible distance or without collision.

**RPC abuse:** ThusterController buffered RPC every frame (DoS). Flash_Light held-button flood. Rate limits: per-player RPC frequency cap.

**Ownership:** OwnershipTransfer (Takeover/Request). GrabbableObj RequestOwnership on grab, TransferOwnership(MasterClient) on release. Flag non-owner sending ownership-requiring RPCs.

**Malformed messages:** Validate RPC params, reject oversized, validate sender ownership.

---

## Category 9: Detection Engine and Risk Scoring

**Signal categories:** Server-side rule violations, invalid state transitions, impossible movement, invalid RPCs, integrity failures, outdated builds, suspicious request patterns, session anomalies, device integrity, corroborated tampering.

**Risk scoring:** Confidence = sum of weighted triggered rules, clamped 0-1. Auto-action only if confidence >= 0.8 AND >= 2 independent rules. Decay: 24h = 50% weight. Correlated signals don't count as independent.

**12 detection rules (S-001..S-012):** See docs/voideration-screechvr-architecture.md section 5. Key: S-001 impossible speed, S-002 teleport, S-003 currency grant, S-004 moderator spoof, S-005 banned player in room, S-006 duplicate session, S-007 cosmetic spoof, S-008 RPC flood, S-009 invalid tag, S-010 leaderboard anomaly, S-011 version mismatch, S-012 null crash trigger.

**Enforcement tiers:** Log -> Flag (>=0.3) -> Review queue (>=0.5) -> Kick (server-verified) -> Ban (human-confirmed).

**ML vs deterministic:** Start deterministic. ML only after 6+ months of labeled data.

---

## Category 10: Bans, Moderation, and Appeals

**Enforcement sources:** PlayFab bans (server-side admin API) are source of truth. KickIfBanned polls every 5s (client-side, keep but supplement). Photon custom auth checks ban on connect.

**Ban types:** Temporary (timeout), Permanent, Shadow (v2+).

**Flow:** Admin issues ban in dashboard -> PlayFab BanUsers API + Voideration DB + Discord webhook. Banned player on next login: Photon custom auth denies. In room: KickIfBanned polls, displays ban screen, quits (5s delay).

**Appeal:** Via Discord/support ticket. Admin reviews evidence. Unban: PlayFab + DB + audit log + webhook.

**Graduated enforcement:** Log -> Flag -> Review -> Temporary restriction -> Ban (human-confirmed).

**Safeguards:** Never auto-ban on client signals. Kill switch. Audit log. Emergency rollback. Rate limit ban issuance.

**Moderator system:** Stored in PlayFab UserData "Moderator" key. CRITICAL: verify if client-writable. Mod menu opens if DefaultQueue == "MODDED". Check_Mod sets AccountPref after 5s timeout (client-side, unverified).

---

## Category 11: Owner Dashboard and Admin Security

**Pages:** Overview (live CCU, active bans, pending flags, recent events, health), Players (search, session history, flags, bans), Player detail (first/last seen, game modes, failed sessions, bans timeline, IPs, cosmetics, currency read-only), Flags (review queue, by rule, confidence, evidence, approve/dismiss), Bans (active/expired/revoked, issue/revoke with reason, webhook), Detection rules (enable/disable, thresholds, per-mode filters, version), Audit log, Webhooks (Discord config), Settings (retention, version enforcement, maintenance mode).

**Auth:** Email+password+TOTP MFA (owner only v1). JWT access (15min) + refresh (7d, rotating). Rate limit login (5/15min per IP). IP allowlist optional.

**Security:** Backend-enforced auth (no secret URLs). RBAC (Owner/Admin/Moderator/Viewer). CSRF protection. Append-only hash-chained audit log. Confirmation dialogs for destructive actions. Loading/empty/error/offline states. Dark theme, high contrast.

---

## Category 12: Backend Architecture

**Stack (v1, cost-conscious):** Cloudflare Workers + D1 (SQLite) + KV (cache) + R2 (evidence). Dashboard on Cloudflare Pages. Auth: JWT (HS256, secret in worker env) + TOTP MFA. Monitoring: Cloudflare Analytics + Sentry (free).

**Why Cloudflare over VPS:** Already in use. Zero new infra. Free tier covers low scale. D1 is SQLite (simple). Scales to 1k CCU. Upgrade to VPS only if needed.

**API endpoints (v1):** auth (login/refresh/logout), games (single game), validation (validate-user, heartbeat, report-flag, ban-check), bans (ban-user, unban-user, bans list), alt-accounts, stats (game-stats, ccu), players, flags, detection-rules, audit-log, webhooks, ccu (live/history).

**Photon custom auth:** Photon calls worker URL with auth params. Worker validates PlayFab session ticket, checks ban status, returns allow/deny. Photon enforces.

**PlayFab integration:** Auth (Oculus custom ID), Photon token, currency (vulnerability: client-specified amount), inventory (PurchaseItem server validates price), bans (admin API), title data (MOTD, LOCKDOWN, VERSION_CODE, CONTENT_CREATORS), user data (USERNAME, Moderator, EQUIPPED).

**Secrets:** All in worker env vars (encrypted at rest). No secrets in Unity client or repo. Rotate on compromise.

---

## Category 13: Tool Security and Malware Screening

**Policy:** All downloaded executables, archives, installers, scripts, plugins, binaries are untrusted until reviewed.

**Safety rules:** Prefer official source. Verify authenticity. Check release history. Inspect checksums. Review source code. Check dependencies. Never execute unknown binaries. Never upload private files. Never disable security software.

**Approved tools:** Ghidra 12.2 (open source, NSA, hash verified), Rizin 0.9.1 (open source, winget verified).

**Not reviewed:** k6, OWASP ZAP, Burp Suite Community, Frida, UABEA, dnSpyEx, IL2CPPDumper, PlayFab CLI. All require individual safety review.

**Statuses:** NOT REVIEWED, SOURCE VERIFIED, STATICALLY REVIEWED, SCANNED - NOT PROVEN SAFE, APPROVED FOR ISOLATED TESTING, REJECTED, BLOCKED - INSUFFICIENT EVIDENCE.

---

## Category 14: Dependency and Supply Chain Security

**Current dependencies (Packages/manifest.json):** URP 12.1.13, Oculus XR 3.3.0, OpenXR 1.9.1, XR Interaction Toolkit 2.5.4, Photon PUN2+Voice, PlayFab SDK, Oculus Platform, Bakery, Magic Light Probes, Mesh Optimizer, MirrorV2, ParrelSync, vHierarchy, vFolders, Beebyte Obfuscator, Glitched Cat Studios Wardrobe, GDH LeaderBoard, etc.

**Risks:** Beebyte Obfuscator (cosmetic only), ParrelSync (dev tool, shouldn't ship), many Asset Store assets (verify publisher), no dependency scanning.

**Recommendations:** Pin versions (already pinned). Run vulnerability scan before release. Remove dev tools from production builds. Verify publisher authenticity. Secret scan repo. Don't upgrade during research.

---

## Category 15: Build and Release Security

**Current state:** Unity 2021.3 LTS, IL2CPP for Quest. Build symbols: TH_TOMAHAWK (not used). Version enforcement via title data "VERISION_CODE". LOCKDOWN title data key. No build IP whitelist, no build signing beyond Unity default.

**Recommendations:** Keep IL2CPP. Strip debug symbols (Unity default). Version enforcement via title data (keep). Build IP whitelist (manual). Protected/Unprotected build status. No secrets in client binary (already). Secret scanning before release. Dependency scanning. Separate QA/Live environments.

---

## Category 16: Privacy and Data Retention

**Data collected (proposed):** PlayFab ID, Oculus ID, username, session start/end, game mode, room code, movement samples (telemetry only), IP (already collected), ban/flag history, audit log.

**Data NOT collected:** No screenshots/video by default. No personal messages/files. No device identifiers beyond Meta/Oculus. No precise location.

**Retention:** Sessions 30 days (then aggregate). Flags 90 days. Bans 1 year. Audit log 1 year. CCU snapshots 1 year. Evidence (telemetry) 30 days.

**Access control:** Only owner can view player data/bans/flags. Dashboard requires MFA. Audit log records all access.

**Legal:** Flag GDPR-style deletion requests for qualified legal review. Disclose VRIC-style cross-title ban sharing in EULA if implemented. Age: ScreechVR likely 13+ (Meta Quest). Collect minimal data for minors.

---

## Category 17: Incident Response and Monitoring

**Alert triggers:** Sudden detection spike (>3x baseline), unusual ban activity (>5/hour), auth failures (>10/5min), backend outages (5xx >1%), API abuse, rate-limit spikes, suspected dashboard compromise, integrity failures, mass false positives, suspicious admin actions, DB/service failures.

**Kill switch:** Disable specific detection rules without disabling backend auth. Protected by owner-only access + audit log. Emergency: set all rules to "log only".

**Incident procedure:** Detect -> Triage -> Investigate -> Contain -> Preserve evidence -> Recover -> Rotate credentials -> Document.

**Monitoring:** Cloudflare Analytics, Sentry, Discord webhook for high-severity, dashboard health page.

---

## Category 18: Security Test Plan

**Unit tests:** Validation endpoint, ban/unban, audit log hash chain, detection rules (fire correctly, no false positives on clean data).

**Integration tests:** Photon custom auth (banned denied, valid allowed), PlayFab (currency grant via backend only, purchase validation), webhook delivery.

**Pen tests:** Unauthenticated admin access (401), BOLA (403), mass assignment (400), rate limit bypass (429), SQL injection (sanitized).

**Load tests:** k6 against /validate-user at 100/500/1000 concurrent. Target p99 < 200ms at 500 concurrent.

**False-positive tests:** High latency (200ms RTT), packet loss (10%), VR movement edge cases (jumping, climbing, bouncing, TP_YA), network jitter.

**Performance tests:** Client telemetry < 1ms/frame. Backend validation < 50ms p99. Dashboard load < 2s.

**Recovery tests:** DB restore from backup, worker restart, kill switch disable.

---

## Category 19: Costs, Scalability, and Operations

**Initial (low scale, Cloudflare free tier):** ~$1-2/mo (domain only). Workers free (100k req/day), D1 free (5GB), KV free, R2 free (10GB), Pages free, Sentry free.

**At 1k peak CCU:** ~$20-50/mo (Workers $5-10, D1 $5-15, KV $5-10, R2 $1-5).

**At 10k peak CCU:** ~$130-260/mo.

**Compare to Tomahawk:** $600/mo floor. Self-hosted saves $500-580/mo at 1k CCU. Trade-off: engineering time (10-17 weeks MVP, 5-10h/week ops).

**Scalability bottlenecks:** D1 (SQLite, single-writer, ~100 writes/sec). Upgrade to Postgres (Neon/Supabase) if exceeded. KV eventual consistency. Workers 50ms CPU limit (free), 30s (paid).

**Assumptions:** Free tier sufficient for initial launch (untested). D1 throughput scales linearly (untested). No egress costs (Cloudflare includes bandwidth). Prices as of 2026-10.

---

## Category 20: Architecture Options and Recommendation

**Option 1: Minimal (recommended v1):** Cloudflare Workers + D1 + KV + R2. No VPS. Dashboard on Pages. Cost $1-35/mo. Effort 9-14 weeks. Pros: cheapest, simplest, extends existing worker. Cons: D1 write throughput limit.

**Option 2: Balanced (v1.5):** Same + Postgres (Neon) if D1 limits hit. + Sentry. Cost $10-50/mo. Effort 10-16 weeks.

**Option 3: Advanced (v2+):** Dedicated VPS + Postgres + Redis + dedicated game server. Cost $80-200/mo. Effort 20-30 weeks. Pros: authoritative movement, instant kicks. Cons: high complexity/cost.

**Recommendation:** Option 1 for v1. Migrate to Option 2 if D1 limits hit. Option 3 only if cheating becomes serious. Most security value from backend validation + detection + dashboard, not dedicated servers.

---

## Category 21: Implementation Roadmap

**Stage 0 (DONE):** Project understanding, technical map, threat model, decisions.

**Stage 1 (2-3 weeks):** Backend foundation - worker extensions (/validate-session, /heartbeat, /report-flag, /ban-check), D1 schema, Photon custom auth, PlayFab integration. Acceptance: banned players can't connect; heartbeat tracks CCU.

**Stage 2 (2-3 weeks):** Detection - movement telemetry, rules S-001/S-002/S-005/S-006/S-008, flag creation, review queue. Acceptance: flags for synthetic cheats; no false positives on clean sessions.

**Stage 3 (2-3 weeks):** Dashboard - auth (email+password+TOTP), JWT, RBAC, overview/players/flags/bans/audit pages, ban issue/revoke with Discord webhook. Acceptance: owner can log in, view flags, issue ban, ban appears in PlayFab.

**Stage 4 (1-2 weeks):** Currency/cosmetic protection - move currency grants to CloudScript/worker, backend inventory verification. Acceptance: client cannot grant itself currency; cosmetic spoof flagged.

**Stage 5 (1-2 weeks):** Testing & hardening - pen test, load test, false-positive regression, backup restore. Acceptance: all tests pass.

**Stage 6 (1 week):** Controlled rollout - staging with PCDEBUG, limited QA rollout, monitoring, gradual expansion.

Total: ~9-14 weeks solo, part-time. Depends on user decisions.

---

## Category 22: Open Questions and Risks

**Open questions (need user decision):**
1. PlayFab UserData "Moderator" key: client-writable? (critical)
2. Currency grants: move to CloudScript or keep client-side with audit?
3. Meta attestation: available? (docs gated)
4. Photon custom auth: willing to configure?
5. Dashboard hosting: Cloudflare Pages or VPS?
6. MFA: owner only or all admins?
7. Evidence storage: telemetry only or screenshots/video?
8. Real-time kick: accept 5s delay or invest in Photon Server?
9. CloudScript/Azure Functions deployed? (none in repo)

**Risks:** Meta attestation unavailable, master client exploitable, detection false positives, solo dev burnout, cost overruns, PlayFab client-writable UserData.

---

## Category 23: Deferred Tasks

| Task | Reason | Unblock condition |
|---|---|---|
| Meta attestation | Docs inaccessible | Meta developer portal access |
| CloudScript verification | Dashboard access needed | User checks dashboard |
| SpokesSigmaIAP receipt validation | Not fully read | Read script + catalog |
| GDH leaderboard anti-cheat | Unknown submission path | Inspect GDH package |
| ATM_TAB currency flow | Not deeply read | Read ATM_TAB.cs |
| Photon custom auth setup | Dashboard config needed | User configures auth URL |
| Dedicated authoritative server | High cost/complexity | Only if cheating serious |
| ML-based detection | Needs labeled data | 6+ months session data |
| Meta device ban sync | Requires partnership | Verify permissions |
| Shadow bans | Complex | v2+ |

---

## Category 24: Decisions and Assumptions

**Decisions:** Voideration ScreechVR-only. Cloudflare Workers + D1. Dashboard on Pages. Master client never trusted. Meta attestation deferred. No auto-ban on client signals. Detection = flag + review. IL2CPP for Quest. Telemetry only for evidence. TOTP MFA owner only (v1).

**Assumptions (unverified):** PlayFab PurchaseItem validates price server-side. PlayFab bans client-only enforcement. No CloudScript deployed. PlayFab UserData "Moderator" client-writable (likely). Meta attestation available (unverified). Photon custom auth configurable. D1 throughput sufficient. Free tier sufficient.

**Conflicts between reports:** CloudScript (verify in dashboard). AppEntitlementCheck (only logs, verify intent). Currency (client-trusted, PlayFab validates session not amount - confirmed).

---

## Category 25: Tomahawk Research (Generic)

Tomahawk is a commercial standalone-VR anti-cheat (Meta Quest primary, mobile in dev, PC/SteamOS planned). Protection layers: runtime protection, root detection, device trust, integrity validation, detection routing, session enforcement. Engines: Unity, Unreal, Custom. Integration: client validation, backend validation, Photon custom auth, server validation. Roles: Owner/Admin/Moderator/Viewer. Pricing: from $600/mo based on avg peak CCU. Clients: Ghosts of Tabor, Yeeps, Animal Company, Overload.

API: POST /api/v1/validation/validate-user (session nonce + OVR ID) -> actionCode 0/1/2, reason, errorCode, usingVpn. Error codes ERR-1xxx..9xxx. Two integrity layers (device/app + external files). Alt accounts (hardware + IP). Bans (timeout/permanent, Meta device ban sync, VRIC cross-org). Webhooks (Discord + standard). Stats endpoint. Photon custom auth via /api/v1/photon-auth. Server validation (token exchange). Splash screen. CI/CD env vars.

SDK (older snapshot): ClientValidationResult only Unknown/Pending/Valid (docs say more). TomahawkPhoton stubbed. Native lib (libTomahawkCore.so): Meta attestation, VPN detection, network monitor, OVR hooking, OpenSSL crypto, no hardcoded secrets, no kernel access.

---

## Category 26: Critical Review

**Ghidra audit:** Resolved conflicting address/function identification. Exported entries sit inside larger merged functions (stripped binary). Key correction: tomahawkCoreInitialize (44 bytes) is a sub-routine inside a 232-byte helper. Native layer is thin wrapper + OpenSSL. Error counts stubbed (older build confirmed).

**Meta attestation:** Symbol confirmed, API docs inaccessible (404). Availability, permissions, verification endpoint UNVERIFIED. Do not depend on it.

**Photon architecture fix:** Photon Cloud (relay, no game logic), Master Client (player, not trusted), Trusted backend (PlayFab/Cloudflare), Dedicated server (v2+). Master client never trusted for security.

**Cost/timeline challenge:** Initial $10-35/mo, $80-200/mo at 1k CCU (with buffer). MVP 12-20 weeks solo part-time (was 10-17, revised up). Needs load testing, false-positive tuning (2-4 weeks post-launch).

**MVP prioritization:** 10 essential items, 7 deferrable, 4 not recommended. See section 21.

**Verification checklist:** 9 open questions, 7 evidence items, 5 risks, 5 recommended tests.

---

## Category 27: Consolidated ScreechVR Architecture

See docs/voideration-screechvr-architecture.md for full detail. Summary:
- 13 confirmed vulnerabilities (V1-V13) with exact file:line evidence.
- 8 theoretical risks (unverified).
- Architecture: extend Cloudflare worker + D1, dashboard on Pages, Photon custom auth, PlayFab backend.
- 12 detection rules (S-001..S-012).
- 6-stage MVP (9-14 weeks).
- 8 decisions needed from user.

---

## Category 28: Ghidra Binary Analysis (libTomahawkCore.so)

**File:** 5,266,416 bytes, SHA-256: 150710A0ED22048DDD3B18C49D7837EA60803B67DE768A6160DFF6A96ADD2B85, MD5: 26AECDD297B62C50E915E1A8F067C43C.

**Format:** ELF64, little-endian, ET_DYN, EM_AARCH64 (ARM64), Android NDK r23c, -O3, target android-21.

**Stripped:** No .symtab (only .dynsym, 284 entries, 19 defined). .gnu_debuglink points to missing libTomahawkCore.debug.

**Dependencies:** libm, liblog, libandroid, libdl, libc. OpenSSL statically linked (no dynamic dep).

**19 exported functions:** setTomahawkLogCallback, isTomahawkReInit, tomahawkCoreInitialize, tomahawkCoreGetStatus, tomahawkCoreIsComplete, tomahawkCoreIsFailed, tomahawkCoreGetErrorCount, tomahawkCoreGetError, tomahawkCoreGetSessionNonce, tomahawkCoreIsNetworkAvailable, tomahawkCoreSetNetworkCallback, tomahawkCoreStartNetworkMonitor, tomahawkCoreStopNetworkMonitor, tomahawkCoreIsVPNActive, T_CV, T_CVR, T_SD, T_FC, JNI_OnLoad.

**Key findings (Ghidra-decompiled):**
- FUN_0041c51c (232 bytes): generic collection-registration helper (validates fields, allocates, inserts, cleans up).
- FUN_0041c604 (248 bytes): collection/validation helper (type code 0x95=149).
- FUN_0041c6fc (304 bytes): network/session helper (parse + network op + cleanup).
- FUN_003f7b68 (44 bytes): buffer/remaining-bytes helper.
- FUN_0042acec (356 bytes): OpenSSL rand_pool_grow (CSPRNG).
- FUN_002ee098 (704 bytes): PKCS5_pbe2_set_iv_ex (OpenSSL).
- FUN_0041e9f8 (252 bytes): PKCS8_set0_pbe_ex (OpenSSL).
- FUN_00420318 (1840 bytes): PKCS7_dataInit (OpenSSL).
- FUN_00430fe0 (680 bytes): RSA_setup_blinding (OpenSSL).

**Security observations:**
- No kernel-level access (standard Android NDK + Meta attestation).
- VPN detection first-class (exported tomahawkCoreIsVPNActive).
- Network monitoring continuous (socketpair + pthread + poll).
- Memory protection (mlock/mprotect/madvise imported).
- CSPRNG (getentropy + OpenSSL rand_pool).
- No hardcoded secrets/URLs.
- Process spawning (fork/exec) and dynamic loading (dlopen/dlsym) present.
- C++ exceptions present (gcc_except_table, eh_frame).
- Error counts stubbed in this older build.

**What it does NOT do:** No kernel/rootkit, no custom crypto, no obfuscation, no hardcoded secrets, no detection algorithms (server-side or attestation-derived).

**Tooling:** Ghidra 12.2 (headless, 177s analysis), Java script decompiler, Rizin 0.9.1, Python 3.12 (ELF parsing), PowerShell. No binutils, no capstone, no WSL. Hand-written ARM64 decoder had gaps; Ghidra decompilation filled them.

---

STOP: research phase complete. No implementation performed. Awaiting your explicit approval before any code is written.

screechvr-technical-map-2026-10-28.md
# ScreechVR technical map (research only, read-only)

Date: 2026-10-28, chat-b (Unity/VR lane). No project files modified.

Scope: ScreechVR Unity project (Assets, Scripts, Scenes). Findings are CONFIRMED where a
file:line is cited, and marked ASSUMPTION where inferred. Unverified items listed at the end.

## 1. Architecture overview

ScreechVR is a Unity 2021.3 LTS (URP 12.1.13) VR multiplayer game built on:
- Photon PUN 2 + Photon Voice (rooms, RPCs, sync, voice)
- PlayFab (auth, inventory, currency, title data, leaderboards)
- Meta/Oculus SDK (Oculus Platform entitlement + Oculus Login)
- Custom gorilla-tag-style locomotion (GorillaLocomotion.Player)

Scenes: Hub, Menu, Game (horror, main scene with LVL1-7), PVP, Sandbox, Template,
Tutorial, plus Gamemode scenes. Player rig prefab: Assets/Resources/GorillaPrefabs/Gorilla Rig.prefab
and Resources/Network/NetworkPlayer (spawned by PlayerSpawner).

## 2. Player spawning / despawning / respawning / identity

- Assets/Scripts/PlayerSpawner.cs (Photon.VR.Player namespace)
  - Awake: DontDestroyOnLoad; instance = this.
  - OnJoinedRoom: PhotonNetwork.Instantiate(PrefabLocation="PhotonVR/Player", ...).
    Then swaps material[0]/[1] on PhotonVRManager.Manager.LocalPlayer.re.
  - SpawnCustomPlayer(prefab): destroys current player PV, instantiates new prefab.
  - OnLeftRoom: destroys player PV.
- Assets/Scripts/UsernameValidator.cs
  - Awake: singleton. Start: waits 1s then CheckUsernameValidity(namee.metausername).
  - Reads PlayFab Title Data key "CONTENT_CREATORS"; if username in list, sets
    PlayerSpawner.instance.PrefabLocation = "Network/NetworkPlayer_Verify" (verified creator rig).
  - Trust: client decides which prefab to spawn based on a PlayFab title-data string match.
- Assets/Scripts/AppEntitlementCheck.cs
  - Awake: Core.AsyncInitialize; Entitlements.IsUserEntitledToApplication; logs only, does NOT quit on failure.
- Player identity: PlayFabId (Oculus_Login.PlayFab_Id), OculusID, Photon custom auth token
  (PhotonCustomAuthToken) issued by PlayFab GetPhotonAuthenticationToken. Nickname set via
  PlayFab UpdateUserTitleDisplayName (Oculus_Login.cs:553-596). Photon player NickName set from
  saved PlayFab name (Oculus_Login.cs:385-390).
- PhotonVRManager.Manager.LocalPlayer is the PhotonVRPlayer component on the spawned rig.

## 3. Gorilla Tag-style locomotion

- Assets/Scripts/NewGorillaLocomotionScripts/Player.cs (namespace GorillaLocomotion)
  - Singleton Player.Instance. Fields: headCollider (SphereCollider), bodyCollider (CapsuleCollider),
    leftHandFollower/rightHandFollower, leftHandTransform/rightHandTransform, playerRigidBody.
  - LocomotionEnabledLayers (LayerMask) gates sphere casts.
  - Update(): sphere-casts from last hand positions to current hand positions with gravity
    (2*9.8*dt*dt), resolves collisions via Surface.slipPercentage, moves transform.position,
    then applies jump velocity = jumpMultiplier * denormalizedVelocityAverage (clamped to
    maxJumpSpeed) when hands colliding and speed > velocityLimit and !disableMovement.
  - TP bool triggers TP_YA() coroutine: disables ALL non-trigger colliders in scene, teleports
    to Point.position, toggles isKinematic, re-enables colliders. (Same collider-kill pattern
    as BestJumpscare/LevelSelect.)
  - CurrentMode (FFA/SN/CA) set by Gamemode_ RPCs.
  - disableMovement bool gates jump velocity.
- Assets/Scripts/NewGorillaLocomotionScripts/Surface.cs: slipPercentage per surface.
- Hand_Physic.cs: grab (configurable joint to hand), OverlapSphere by tags "WALL"/"grabby",
  ownership transfer on grab/release (GrabbableObj.NetworkState).
- FingerMovement / HandFingers: cosmetic finger posing (not movement).

## 4. Photon networking

- Assets/Scripts/PhotonVRManager.cs (Photon.VR)
  - Singleton Manager. DontDestroyOnLoad. Fields: DefaultQueue ("Default"), DefaultRoomLimit (10),
    ConnectOnAwake, JoinRoomOnConnect, AutomaticallySyncScene=true.
  - Awake (patched): newest-wins duplicate guard destroys stale DDOL copy.
  - Start: DontDestroyOnLoad, WaitForAuthThenConnect coroutine (waits for Oculus_Login.IsPhotonReady
    up to 20s, then ConnectAuthenticated or fallback Connect).
  - ConnectAuthenticated(username, token): custom auth with PlayFab token.
  - OnConnectedToMaster: if JoinRoomOnConnect -> JoinRandomRoom(DefaultQueue, limit).
  - OnJoinedRoom: (line 511+) sets state.
  - SwitchScenes/JoinRandomRoom/JoinPrivateRoom helpers. Room custom props: "queue", "version".
  - SetUsername/SetMeta/SetColour/SetCosmetics/SetGun/SetCosmetic/SetSecondary: write Photon
    custom properties / RPCs.
- PunVoiceClient (Photon.Voice) on same GO as PhotonVRManager in every gameplay scene.
  Singleton picks FindObjectsOfType()[0], never destroys duplicates.
- RPCs: scattered across scripts (BestJumpscare, WeldGun, TagPlayer, Rock, ThusterController,
  PlaceBag, Ghost_Yes, BulletTrailSync, etc.). Many use RpcTarget.All / AllBuffered.
- Ownership: OwnershipTransfer per prefab (Takeover=0 / Request=1). GrabbableObj.NetworkState
  uses RequestOwnership on grab, TransferOwnership(MasterClient) on release.
- Room sync: AutomaticallySyncScene=true means joining a room whose master is in another scene
  force-loads that scene for all clients.

## 5. PlayFab

- Assets/Scripts/Oculus_Login.cs (MonoBehaviour)
  - Auth: Oculus Core.Initialize + Entitlements (client-side, log only); LoginWithCustomID using
    OculusID as CustomId; OnLoginSuccess stores PlayFab_Id, SessionTicket; RequestPhotonToken.
  - Currency: Currency_Code="HC", _currency (int, client-held). GetCurrency/AddCurrency/
    RemoveCurrency/ForceRefreshCurrency via PlayFab GetUserInventory/AddUserVirtualCurrency/
    SubtractUserVirtualCurrency. AddCurrency/RemoveCurrency update _currency locally BEFORE the
    server call and only revert on error -> client-trusted currency.
  - Inventory: AccountInfoSuccess calls GetUserInventory; stores items; Items_Enable/Items_Disable
    lists toggled by item.ItemId matching GO names (Oculus_Login.cs:208-225).
  - Title data: GetMOTD (key "MOTD"), GetTitle (key ?). HandleBan parses PlayFabError
    AccountBanned and reads BanTime/BanReason into TMP (Oculus_Login.cs:494-532).
  - Display name: updatePlayFabNickname (UpdateUserTitleDisplayName).
  - UserData: CreateKeyIfNot (key?), SavePlayerName, LoadEquippedWhenReady (GetUserData
    "EQUIPPED" snapshot).
  - GetCurrency/AddCurrency are called from BuyCosmetic (client-side purchase flow).
- Assets/ScreechApi.cs: worker HTTP client. GetMotd hits BaseUrl+"/motd" (worker). Redeem hits
  "/redeem" with PlayFab session ticket. PostPlayers hits "/updateplayers".
- Leaderboards: GDH Packages/LeaderBoard (third-party) - LeaderboardButton etc.
- No CloudScript found in repo (search: no CloudScript/ExecuteCloudScript references in Assets/Scripts).
- Title data keys used: "MOTD", "CONTENT_CREATORS" (UsernameValidator), possibly others.

## 6. Rooms / matchmaking / scene loading

- Assets/Scripts/Sandybo.cs: JoinOrCreateRoom("Sandbox", 10 players) - pins everyone to one room.
- Assets/Scripts/SandboxMatchmaking.cs: JoinMostPopulated/JoinEmptyRoom/JoinSpecificCode with
  queue/version custom props; lobby caching; leave-then-act flow.
- Assets/Scripts/Gamemode_System.cs: keyboard input "1"->Sandbox, "2"->PVP via PhotonNetwork
  Disconnect+LeaveRoom+LoadScene.
- Assets/Scripts/sceneyessss.cs: trigger -> Disconnect+LeaveRoom+LoadScene(Scene) (Game/PVP).
- Assets/Scripts/LevelSelect.cs: per-level unlock via PlayerPrefs keyed by GO name; teleport
  player to Leveltotp, activates Level root, disables ALL non-trigger colliders scene-wide
  then re-enables (coroutine-free but synchronous).
- Assets/Scripts/MapLoader.cs: OnTriggerEnter "Player" toggles New[]/Old[] GameObject arrays.
- Assets/Scripts/GamemodeManager.cs: PVP gamemode selection (FFA/Siphon/Chaos) via master client RPC.
- Assets/Scripts/Gamemode_.cs: sets Player.CurrentMode and barriers.
- Assets/Scripts/DeployGamemode.cs: master client triggers ChooseGamemode on finger touch.
- Game scene: LVL1-7 roots toggled by LevelSelect/MapLoader; 9 active monsters (Boiden,
  Chomper, Crawlie, Crawling Mofo, Demetrius, MoopySweep, Nesbit, Nibsta, Spines) with
  AIWanderFollowV2 + NetworkAi + BestJumpscare triggers.

## 7. Bans / kicks / moderation / reporting

- Assets/Scripts/KickIfBanned.cs: polls PlayFab GetAccountInfo every 5s; on AccountBanned error
  calls Application.Quit + Disconnect + LoadScene(1) + PlayerPrefs "Saved"="Save". Client-side
  enforcement only; no server-side kick.
- Assets/Scripts/Kick_Player.cs: OnTriggerEnter on layer "Kick" -> Application.Quit (client-side
  self-kick). photonView.IsMine check on the kicker? Actually `!photonView.IsMine` means the
  victim (non-owner of the kick trigger volume) quits. Client-trusted.
- Assets/Scripts/Oculus_Login.cs:494 HandleBan: parses PlayFab ban error, sets BanTimeText/
  BanReasonText TMP, toggles Objects_Enable/Objects_Destroy/Objects_Color.
- Mod badges: Check_Mod.cs (moderator status via Oculus_Login.Instance.AccountPref == Moderator
  after 5s timeout) toggles ModStuff and disables a MeshCollider. Mod_Toggle.cs opens ModMenu
  if PhotonVRManager.Manager.DefaultQueue == "MODDED".
- Reporting: DiscordButton.cs posts to Discord; ScreechApi.Redeem for code redemption.
- No server-side ban enforcement observed (PlayFab ban is checked client-side via GetAccountInfo).

## 8. Cosmetics / unlocks / purchases / IAP

- Assets/Scripts/GetCosmetics.cs / SecondaryCosmetics.cs: cosmetic prefabs in Cosmetics list;
  cosmeticsDict keyed by GO name; layerToRegion maps layer->region; EnableCosmetic/DisableCosmetic
  toggles GOs and syncs via Photon player custom properties ("LeftHand"/"RightHand"/"Head"/
  "Body"/"Face"). ApplyAllCosmeticsFromPlayer reads remote player props.
- Persistence: PlayFab UserData key "EQUIPPED" snapshot (GetCosmetics.LoadEquippedWhenReady).
- Assets/Scripts/BuyCosmetic.cs: client-side purchase: checks Oculus_Login._currency >= Price,
  disables collider/renderer, calls PlayFab PurchaseItem(ItemId, Currency_Code, Price, "Catalog"),
  on success ForceRefreshCurrency + RefreshAccount. On error re-enables. Client-trusted price
  check (server should validate).
- Assets/Scripts/SpokesSigmaIAP.cs: IAP (Oculus) - GetComponent<Collider>().enabled toggles.
- Assets/Scripts/ATM_TAB.cs / Atm_Manager.cs: ATM currency (not deeply read).
- Assets/Scripts/CosmeticGrab.cs, CullCosmetic.cs, Cosmetic_Yes.cs: cosmetic equip triggers.
- Assets/Scripts/GcsWardrobeManager.cs (third-party): wardrobe with PlayFab catalog + Photon
  cosmetic sync; obsolete instance API.
- PhotonVRManager.SetCosmetics/SetCosmetic/SetSecondary/SetGun push cosmetic state to Photon.

## 9. Existing security / anti-cheat / validation

Confirmed client-trusted (from prior audits + this scan):
- Moderator status: client-side (Oculus_Login.AccountPref, Check_Mod timeout 5s). No server verify.
- Currency: client-held _currency, AddCurrency/RemoveCurrency update locally first; BuyCosmetic
  checks local balance. Server-side PlayFab validates purchase but client can desync.
- Kick: client RPC / Application.Quit (Kick_Player, KickIfBanned). A modified client can ignore.
- KickIfBanned: client-side ban check; modified client can skip.
- Tag/Infection gamemode: TagPlayer uses Photon RPCs; tagger assignment by name "GorillaPlayer".
- No anti-cheat scripts found. No server-side validation of movement, position, or score.
- Null crashes: many (PlayerSpawner playerTemp, Hand_Physic grabbable, Monster_Track TMP, etc.)
  not guarded; a modified client can trigger NREs.

Existing validation present:
- AppEntitlementCheck (Oculus, log only, no quit).
- UsernameValidator (content creator check via title data).
- KickIfBanned (client-side ban poll).
- Ownership checks in PlaceBag (bagView.IsMine) and WeldGun (hoveredView.IsMine).

## 10. Packages / plugins / SDKs / third-party

From Packages/manifest.json:
- com.unity.render-pipelines.universal 12.1.13 (URP)
- com.unity.xr.oculus 3.3.0, com.unity.xr.openxr 1.9.1, com.unity.xr.management 4.5.1
- com.unity.xr.interaction.toolkit 2.5.4
- com.unity.animation.rigging 1.1.1, com.unity.probuilder 5.2.4, com.unity.postprocessing 3.2.2
- com.unity.timeline 1.6.5, com.unity.recorder 3.0.4
- com.unity.visualscripting 1.9.1
- com.coplaydev.unity-mcp, com.gamelovers.mcp-unity (dev tools)
Third-party in Assets: Photon (PUN2 + Voice), PlayFab SDK, Oculus Platform, Bakery (lighting),
Magic Light Probes, Mesh Optimizer, MirrorV2, ParrelSync, vHierarchy, vFolders, Beebyte
Obfuscator, Glitched Cat Studios Wardrobe, GDH LeaderBoard, DeeJr Waterfall, KeosBackPack,
BubblePop, Meta XR. Assets/Plugins likely contains more.

## 11. APIs / webhooks / servers / databases / external services

- PlayFab: auth, inventory, currency, title data, leaderboards, user data (EQUIPPED, names).
- Photon Cloud: PUN2 rooms, RPCs, custom properties, voice.
- Screech worker (Cloudflare): BaseUrl https://screech-linking-system-...screechvr.workers.dev
  endpoints /updateplayers, /redeem, /motd. ScreechApi.cs.
- Discord: DiscordButton / DiscordManager (bot token in discord-bot/bot-token.txt; guild ops).
- Oculus Platform: entitlement, user info, IAP.
- No dedicated game server observed. No database beyond PlayFab.

## 12. Manipulation points for a modified client (attack surface)

- Currency: modify _currency locally; AddCurrency/RemoveCurrency update local then server.
  Client can grant itself gold; BuyCosmetic checks local balance.
- Moderator: set AccountPref = Moderator client-side -> mod menu + Check_Mod.
- Kick: ignore Application.Quit / Kick_Player trigger.
- Ban: skip KickIfBanned or GetAccountInfo.
- Movement: Player velocity/jump not validated server-side; teleport via TP_YA.
- Cosmetics: set any cosmetic id in Photon custom properties; others apply it.
- Tag/Infection: RPC tagger assignment, client sends "tagged" RPCs.
- Room: JoinPrivateRoom with arbitrary code; scene sync via AutomaticallySyncScene.
- IAP: SpokesSigmaIAP client-side grant (client-trusted).
- Leaderboards: GDH leaderboard client-submitted scores (not verified).

## 13. What can be enforced where

- Client: input validation, UI gating only (trivially bypassed).
- Photon Cloud: room properties, ownership, RPC routing; no game logic enforcement.
- PlayFab: purchase validation, inventory, bans, title data, leaderboards (if configured
  server-side), cloud script (not used currently).
- Dedicated server: none exists; would be needed for authoritative movement, scoring, bans.

## 14. Existing bugs / missing validation / trust assumptions / gaps

- Trust assumptions: client is trusted for currency, moderator status, kicks, bans, IAP grants,
  leaderboard scores, movement, cosmetic ownership.
- Missing validation: no server-side price check enforcement observed (PlayFab PurchaseItem
  does validate server-side, but client gates on local balance); no movement validation;
  no ban enforcement server-side.
- Bugs from prior audits: PhotonVRManager duplicate DDOL (fixed), BestJumpscare collider kill
  (fixed), ThusterController RPC flood (open), Flash_Light held-button flood (open),
  WeldGun NRE (fixed), missing scripts (open), ownership Takeover desync (open).
- Null crashes throughout (PlayerSpawner playerTemp, Hand_Physic grabbable, Monster_Track TMP,
  offline rends, etc.).

## 15. Unverified items + evidence needed

- CloudScript: none found in repo; confirm in PlayFab dashboard whether any CloudScript/
  Azure Functions are deployed (repo search only).
- AppEntitlementCheck: only logs, does not quit; verify intended behavior.
- ATM_TAB/Atm_Manager: not deeply read; currency flow details unknown.
- SpokesSigmaIAP: full IAP grant path not read; verify server-side receipt validation.
- Leaderboard (GDH): submission path and anti-cheat unknown.
- PhotonVRManager.OnJoinedRoom and SetCosmetic exact lines not fully captured (file is 585 lines).
- Whether PlayFab PurchaseItem validates price server-side: assumed yes, verify via dashboard.
- Whether bans are enforced server-side: assumed client-only, verify via dashboard.
- GorillaLocomotion.Player location: Assets/Scripts/NewGorillaLocomotionScripts/Player.cs (confirmed).
- Photon.VR package internals: not in repo (DLL), behavior inferred from usage.
- Scene-specific spawn flows (PlayerSpawner in Game vs Sandbox) not verified via MCP scene diff.
- Cosmetics persistence format and migration: assumed stable.

## Evidence index (key files)

- Assets/Scripts/Oculus_Login.cs (auth, currency, ban, MOTD, title data, inventory)
- Assets/Scripts/ScreechApi.cs (worker HTTP)
- Assets/Scripts/PhotonVRManager.cs (networking, rooms, cosmetics, gun)
- Assets/Scripts/PlayerSpawner.cs (spawn/despawn)
- Assets/Scripts/UsernameValidator.cs (content creator check)
- Assets/Scripts/AppEntitlementCheck.cs (Oculus entitlement)
- Assets/Scripts/KickIfBanned.cs, Kick_Player.cs (ban/kick)
- Assets/Scripts/LevelSelect.cs, MapLoader.cs, sceneyessss.cs (scene loading)
- Assets/Scripts/Gamemode_System.cs, GamemodeManager.cs, Gamemode_.cs, DeployGamemode.cs
- Assets/Scripts/GetCosmetics.cs, SecondaryCosmetics.cs, BuyCosmetic.cs, Cosmetic_Yes.cs
- Assets/Scripts/TagManager.cs, TagPlayer.cs, TagLeaderboard.cs
- Assets/Scripts/BestJumpscare.cs (collider kill)
- Assets/Scripts/NewGorillaLocomotionScripts/Player.cs (locomotion)
- Assets/Scripts/Hand_Physic.cs (grab/physics)
- Packages/manifest.json (SDKs)
- Assets/Resources/GorillaPrefabs/Gorilla Rig.prefab (player rig)


voideration-anticheat-research.md
# Voideration Anti-Cheat - Research & Architecture Phase

Research-only. No implementation performed. Source: public tomahawk.gg site + local research files in `C:\Users\Void\Downloads\tomahawk stuff`.

## 1. Executive summary

Tomahawk is a commercial standalone-VR anti-cheat sold as a managed service (Meta Quest primary, mobile in dev, PC/SteamOS planned). It combines client-side integrity attestation (Meta's native attestation + file hash checks), server-side validation via REST, Photon custom auth, dedicated-server token exchange, moderation tooling (bans/timeouts/VRIC cross-org ban sharing), alt-account detection, and a private owner dashboard. Pricing starts at $600/month based on average peak CCU.

For Voideration, the realistic target is the same niche (Meta Quest multiplayer VR, starting with ScreechVR on Photon + PlayFab). The recommended direction is a **self-hosted, server-authoritative-first platform** that you own and operate, reusing what's already in your stack (Photon, PlayFab, Cloudflare worker) rather than buying Tomahawk. The client side cannot be made unbreakable; the realistic goal is layered defenses + server authority + fast ban propagation + good evidence, which is what Tomahawk itself does.

Key decisions recommended up front:
- Platform scope: Meta Quest only for v1 (matches Tomahawk's current availability and your game).
- Backend: TypeScript/NestJS (or Fastify) + PostgreSQL + Redis, hosted on a single Hetzner VPS behind Cloudflare.
- Auth: short-lived JWT access tokens + refresh tokens, RBAC (Owner/Admin/Moderator/Viewer), MFA for owners.
- Detection: server-authoritative checks first (movement, state, rate limits), client attestation where Meta provides it, behavioral flags with confidence scoring, never auto-ban on a single signal.
- Dashboard: React + Tailwind + shadcn/ui + Recharts, private, backend-enforced auth.
- Cost target: under $30/month at low scale, scaling to ~$80-150/month at 1k peak CCU.

## 2. Tomahawk.gg research (public site)

Confirmed facts (from tomahawk.gg marketing + docs):
- Product: anticheat for standalone VR, Meta Quest available now; mobile (iOS/Android) in development; anti-piracy for single-player Quest planned; PC (Windows) planned; SteamOS planned.
- Protection layers (publicly named): Runtime protection, Root detection, Device trust, Integrity validation, Detection routing, Session enforcement.
- Engines supported: Unity, Unreal, Custom.
- Integration methods: Client Validation (Quest device), Backend Validation (games with login), Photon Integration (PUN2/Fusion/Realtime custom auth), Server Validation (dedicated servers, strongest).
- Roles: Owner, Administrator, Moderator, Viewer with a documented capability matrix.
- Pricing: from $600/month based on average peak CCU; 6/12 month terms; usage-based.
- Clients named: Ghosts of Tabor, Yeeps, Animal Company, Overload. Studios list published.
- Dashboard features shown: detection analytics, moderation workspace, team operations, session review queue with trust signals (identity/device/runtime/network), enforcement actions (force review, kick, 24h timeout, permanent ban), user management with roles.
- Marketed metrics: 99.99% API uptime, <1ms response time, 256-bit encryption (marketing claims, unverified).
- Contact: sales@tomahawk.gg; team: Scott Albright (CEO), Kyle (Dev), Nathan (Backend), Mikael (Sales).

Unknown/unverified: actual detection internals, native lib implementation, pricing exact tiers, real uptime, whether "root detection" is Meta attestation vs custom, and how VRIC (cross-org ban sharing) is governed.

## 3. Local research findings

Files inspected (all read-only):
- `getting started.txt` (11.6 KB) - onboarding: account setup, roles, build IP whitelist, game registration, Meta portal setup, API keys (Dev Game Token, Backend API Key, Game Server API Key, Photon API Key), SDK download, integration methods (Client/Backend/Photon/Server), webhooks.
- `API Referance.txt` (30.8 KB) - full customer API: Bearer GUID auth, validate-user, error codes, webhook payloads, game-stats, alt-account check, ban/unban, bans export, uniqueMetaId 30-day rotation, Meta device ban sync.
- `portal documentation.txt` (38.8 KB) - portal pages: Dashboard metrics, User Management (recent sessions 30-day, all users), Session View (overview/failed sessions/bans/IPs & devices/alt accounts), Org Management, Game Management, Build Management, Webhooks, Support.
- `unity implementation.txt` (36.8 KB) - Unity SDK: prerequisites (Unity 2022.3 LTS, Quest 2/3/Pro, IL2CPP), SDK contents, build environments (QA/Live), Meta portal setup, install steps, scripting defines, multi-platform handling, splash screen, runtime API, client/backend/photon/server validation, CI/CD.
- `validation error codes.txt` (6.1 KB) - ERR-1xxx..ERR-9xxx per-code reference.
- `TomahawkSDK ~ NullHub/` - Unity SDK package: `TomahawkGamePlugin.cs`, `TomahawkClientHelper.cs`, `TomahawkPhoton.cs`, `TomahawkLog.cs`, `ValidationResult.cs`, `TomahawkSplash.cs`, `TomahawkSplash.unity`, `libTomahawkCore.so` (5.3 MB native, NOT executed).
- `TomahawkSDK ~ NullHub (1).zip` (2.2 MB) - not extracted (zip left untouched).

Confirmed facts from local files:
- Validation endpoint: `POST /api/v1/validation/validate-user?userOvrId={long}` body `{ sessionNonce }`, Bearer GUID token. Returns `{ actionCode: 0/1/2, reason, errorCode, usingVpn }`.
- Action codes: 0 None, 1 Kick, 2 Ban.
- Error code groups: ERR-1xxx auth, ERR-2xxx ban, ERR-3xxx build, ERR-4xxx session (incl. ERR-4013 superseded token / ERR-4014 diagnostic-vs-standard replay indicators), ERR-5xxx device/attestation (rooted, ADB, cheat software, Meta attestation failures), ERR-6xxx network, ERR-7xxx anticheat flag, ERR-9xxx other.
- Session nonce expires in 45 seconds. Duplicate headset detection (ERR-4001). VPN detection (usingVpn).
- Alt accounts: hardware (confirmed) + IP (with overlap percentage), excluding known VPN IPs.
- Bans: timeout/permanent, internal + user-facing reasons, ban/unban webhooks, Meta device ban sync (metaBanId, uniqueMetaId with 30-day rotation window).
- VRIC: cross-org ban sharing network.
- Two integrity layers: Layer One (device/app) and Layer Two (external assets).
- Build IP whitelist (up to 10 IPs), Protected/Unprotected build status, QA vs Live environments.
- Scripting defines: TH_TOMAHAWK, TH_SERVER, TH_PHOTON.
- Client validation: `ValidateClientAsync()` returns ClientValidationResult (Valid/Kicked/Banned/Error/NotReady per docs; SDK code only exposes Unknown/Pending/Valid - a discrepancy in the "older" SDK).
- Photon custom auth via `https://api.tomahawk.gg/api/v1/photon-auth` with `game_api_key` param.
- Server validation: token exchange pattern (ITomahawkTokenProvider, PrepareTokenRequest/WaitForTokenAsync/OnTokenReceived).
- Webhook reliability: 10s timeout, auto-disable after 5 non-2xx in 5 days.
- Stats endpoint: livePlayerCount, bans (permanent/timeout/total), totalPlayersSeen; cached 2 min.
- Splash screen: world-space canvas, LazyFollow, frequency modes (every launch / 24h / once per update), skip rules.
- CI/CD: env vars TOMAHAWK_SCRIPTING_DEFINES, TOMAHAWK_BUILD_TYPE, TOMAHAWK_DEV_GAME_TOKEN, auto-detects CI provider.

Older-update analysis: the SDK files appear to be an older/simplified snapshot (e.g., ClientValidationResult lacks Kicked/Banned/Error/NotReady vs docs, TomahawkPhoton.IsAvailable() returns false, IsTomahawkServerEnabled returns false). This is consistent with an older or stripped SDK. Treat as historical; the docs are the more complete reference.

### 3.1 Native library (libTomahawkCore.so, 5.3 MB, Android ARM64) - static string analysis only, not executed

Confirmed (symbols/strings present in the binary):
- Meta attestation: `ovr_DeviceApplicationIntegrity_GetIntegrityToken` (Layer One device/application integrity).
- VPN detection: `tomahawkCoreIsVPNActive`.
- Network monitoring: `tomahawkCoreIsNetworkAvailable`, `tomahawkCoreStartNetworkMonitor`, `tomahawkCoreStopNetworkMonitor`, `tomahawkCoreSetNetworkCallback`.
- Function hooking: `OVR_HOOK_INIT`, "Exception in hook - prevented crash" (runtime hooking for integrity/anti-tamper).
- Root/modified-binary detection is inferred to run through Meta's attestation + environment checks (ERR-5004 rooted, ERR-5005 ADB, ERR-5006 known cheat software, ERR-5001/5002 modified binary/signature).
- No hardcoded API hostnames in the binary (base URL supplied at runtime from managed side).
- Bundles OpenSSL (TLS) and curl (HTTP client) statically.

Inference: Layer One is essentially Meta's device application integrity attestation plus OVR hooking, not a custom kernel driver. This is consistent with the public FAQ ("Meta attestation") and confirms no kernel-level access is involved - good news for platform compliance.
## 4. Evidence classification

Confirmed facts: everything cited from the local docs and the public site above. Strong inferences: Tomahawk's client relies on Meta's native attestation (ERR-5xxx) plus its own DLL; root detection is likely Meta attestation + environment checks. Unknown: actual detection algorithms, server implementation, pricing exact tiers, real uptime. Outdated: the SDK snapshot (simplified enums, stubbed methods).

## 5. Recommended architecture (Voideration)

Components:
- Client SDK (Quest): attestation via Meta's platform APIs where available, session nonce generation, heartbeat, tamper-resistant event reporting. Never trust client verdicts.
- Game server / Photon: server-authoritative validation of movement, state, scoring; rejects invalid actions; logs evidence.
- Backend API: auth, validation, ban/evidence storage, webhooks, stats, alt-account detection.
- Detection engine: rule-based flags with confidence scores; behavioral anomaly detection; manual review queue.
- Dashboard (private, owner-only): live CCU, analytics, player search, flags, bans, evidence, audit log, config.
- Data layer: PostgreSQL (primary), Redis (cache/sessions/rate limits), object storage (evidence/screenshots), message queue (webhooks/async jobs).

Communication: client <-> game server (Photon) for gameplay; game server <-> backend API (HTTPS, Bearer) for validation/bans; backend <-> dashboard (HTTPS + WebSocket for live).

## 6. Technology comparison

| Layer | Option A (recommended) | Option B | Option C |
|---|---|---|---|
| Backend | Node.js + Fastify/NestJS (TS) | .NET (ASP.NET Core) | Go (Fiber/Gin) |
| DB | PostgreSQL (Supabase/Neon) | PostgreSQL (self-hosted) | MySQL |
| Cache | Redis (Upstash) | Redis (self) | Memcached |
| Realtime | WebSocket (Socket.IO) | SSE | gRPC |
| Dashboard | React + Tailwind + shadcn/ui + Recharts | Next.js | Vue + Vuetify |
| Auth | JWT + refresh + RBAC + MFA (TOTP) | Session cookies | OAuth2 |
| Hosting | Hetzner VPS + Cloudflare | Fly.io | AWS |
| Monitoring | Sentry + Prometheus/Grafana (later) | Datadog | Better Stack |
| CI/CD | GitHub Actions | GitLab CI | Jenkins |

Recommendation: Node.js/TypeScript (Fastify) + PostgreSQL + Redis + React dashboard, hosted on a single Hetzner VPS behind Cloudflare, with Supabase/Neon as managed Postgres if you don't want to operate DB ops. Rationale: matches your existing JS/TS familiarity (Cloudflare worker, Discord bot), huge ecosystem, affordable, easy to scale later; avoids microservices until needed.

## 7. Anti-cheat strategy

- Server-authoritative: movement, speed, teleport, invalid state detected on server; client reports are hints only.
- Client attestation: use Meta's platform attestation where available (mirrors Tomahawk's Layer One); never as sole gate.
- Behavioral flags: velocity, teleport, impossible actions, rate anomalies -> confidence score; require multiple signals or manual review before ban.
- Evidence: store session telemetry, flag context, timestamps; immutable audit log.
- Enforcement tiers: monitor -> flag -> kick -> temporary ban -> permanent ban; appeals workflow.
- False-positive reduction: shadow bans / delayed enforcement, human review queue, per-rule thresholds configurable, kill switches.
- Versioned detection rules: config-driven thresholds, hot-reloadable, staged rollout.
- Heartbeat: periodic session validation; nonce expiry similar to Tomahawk's 45s.
- Alt-account detection: hardware fingerprint (where platform permits) + IP overlap, excluding VPN IPs.
- VRIC-style cross-title ban sharing: only if you operate multiple games; defer.

## 8. Backend security

- Auth: email+password with Argon2id, TOTP MFA for owners/admins, JWT access (short TTL) + refresh (rotating, revoked on logout), RBAC with least privilege.
- API validation: schema validation (Zod), rate limiting per IP/key, CORS allowlist, CSRF protection for cookie-based dashboard sessions (use SameSite + CSRF tokens).
- Replay protection: request nonces/timestamps for sensitive ops; idempotency keys.
- Secrets: env vars / secret manager (Doppler or cloud), rotation schedule, never in code.
- DB: least-privilege roles, parameterized queries (ORM), encrypted at rest, backups with tested restore.
- Audit log: append-only, hash-chained rows, records every admin action with actor/reason/timestamp.
- Dashboard: private by default, no secret-URL auth, backend-enforced; IP allowlist optional; session timeout; device fingerprinting optional.
- Monitoring: Sentry errors, uptime checks, alerting on anomalies (failed logins, spike in bans).
- Environments: dev/staging/prod separated, prod secrets never in dev.

## 9. Dashboard specification

Pages:
1. Overview (live CCU, 24h/30d charts, peak, active bans, flags pending, recent events, backend health)
2. Players (search by ID/username/IP, filters, session view)
3. Player detail (overview, failed sessions, bans, IPs/devices, alt accounts, moderation actions)
4. Flags (review queue, by rule, confidence, approve/dismiss)
5. Bans (active/expired/revoked, issue/revoke with reason)
6. Analytics (detection trends, ban rates, CCU history, error rates)
7. Rules & config (thresholds, auto-actions, kill switches)
8. Audit log (admin actions)
9. Team (roles, invites)
10. Settings (retention, webhooks, integrations)
11. Support/tickets (optional)

Design system: dark theme, high contrast, monospace for IDs, status colors (green clean, orange moderate, red high), consistent badges, confirmation dialogs for destructive actions, loading/empty/error states, responsive (desktop primary, mobile readable).

## 10. Proposed database schema (core entities)

- organizations (id, name, created_at)
- users (id, org_id, email, password_hash, role, mfa_secret, created_at, last_login)
- games (id, org_id, name, package_name, meta_secret_key_enc, status, created_at)
- api_keys (id, game_id, type, key_hash, created_at, revoked_at)
- sessions (id, game_id, player_id, ovr_id, ip, started_at, ended_at, severity, vpn)
- players (id, game_id, ovr_id, org_ovr_id, username, first_seen, last_seen)
- flags (id, session_id, player_id, rule_id, severity, confidence, created_at, reviewed_by, status)
- detection_rules (id, game_id, name, threshold, action, enabled, version)
- bans (id, game_id, player_id, type, reason_internal, reason_user, issued_by, issued_at, expires_at, revoked_at, meta_ban_id)
- evidence (id, flag_id, type, storage_key, created_at)
- webhooks (id, game_id, type, url, headers_enc, events, active)
- audit_log (id, actor_id, action, target_type, target_id, reason, created_at, prev_hash)
- ccu_snapshots (id, game_id, ts, count)
- alt_accounts (id, player_id, related_player_id, method, confidence, created_at)

Indexes: sessions(player_id, started_at), flags(status, created_at), bans(player_id, status), ccu_snapshots(game_id, ts).

Retention: sessions older than N days purged; evidence retained per policy; bans retained for audit.

## 11. Proposed API design

Base: https://api.voideration.gg (or your domain). Bearer token auth.

Endpoints (v1):
- POST /api/v1/auth/login, /refresh, /logout
- GET/POST /api/v1/games, /api/v1/games/:id
- POST /api/v1/validation/validate-user?userOvrId= (body sessionNonce) -> { actionCode, reason, errorCode, usingVpn }
- POST /api/v1/ban-user, POST /api/v1/unban-user, GET /api/v1/bans
- GET /api/v1/alt-account/check?QuestOvrId=&IncludeIpAlts=
- GET /api/v1/stats/game-stats
- GET /api/v1/players, GET /api/v1/players/:id, GET /api/v1/players/:id/sessions
- GET/POST /api/v1/flags, POST /api/v1/flags/:id/review
- GET/POST /api/v1/detection-rules
- GET /api/v1/audit-log
- GET/POST /api/v1/webhooks
- GET /api/v1/ccu/live, GET /api/v1/ccu/history?range=

Permissions enforced server-side per role. Rate limits per key/IP. Errors: structured { code, message } with stable codes.

## 12. Threat model (prioritized)

1. Modified client (high likelihood/high impact): server authority + attestation + integrity flags.
2. Forged requests (high): Bearer validation, schema validation, rate limits, replay protection.
3. Compromised account (med): MFA, session revocation, audit log.
4. Fake telemetry (med): server-side corroboration, confidence scoring.
5. Dashboard unauthorized access (med/high impact): MFA, RBAC, no secret URLs, CSRF, IP allowlist.
6. Stolen secrets (med): secret manager, rotation, least privilege.
7. Insider misuse (low/med): audit log, RBAC, approval for destructive ops.
8. DB tampering (low): backups, least privilege, hash-chained audit.
9. Detection evasion (high): layered signals, server authority, versioned rules, monitoring.
10. False reports/mass reporting (med): rate limits, corroboration, review.
11. DoS (med): Cloudflare, rate limits, autoscale.
12. Compromised deps (low/med): lockfiles, Dependabot, SBOM.
13. Malicious updates (med): signed builds, CI verification.

Residual risk: client-side checks are bypassable by determined attackers; server authority limits blast radius but can't prevent all abuse of game logic not yet server-validated.

## 13. Hosting and operating costs (estimates)

Initial (low scale, single VPS):
- Hetzner CPX21 (4 vCPU, 8GB): ~$8/mo
- Managed Postgres (Neon free tier or Supabase free): $0-25/mo
- Upstash Redis free tier: $0
- Cloudflare: $0 (free plan)
- Domain: ~$10-15/yr
- Sentry free tier: $0
- Backups (Hetzner snapshots): ~$2/mo
Total: ~$10-35/mo initially.

At 1k peak CCU: VPS ~$30-60, DB ~$25-50, Redis ~$10-20, bandwidth ~$10-20 => ~$80-150/mo. Compare to Tomahawk's $600/mo floor - significant savings, at the cost of your engineering time.

Sources: Hetzner cloud pricing (hetzner.com/cloud), Neon/Supabase pricing pages, Upstash pricing, Cloudflare pricing. Verify current prices before committing.

## 14. Testing and reliability

- Unit/integration tests (Vitest/Jest) for API and detection logic.
- Security testing: OWASP ZAP, dependency scanning, secret scanning.
- Detection accuracy: synthetic cheat replays in staging, false-positive regression suite with real session data.
- Load testing: k6 against validation endpoint, target p99 < 200ms at expected CCU.
- Backup restore drills quarterly.
- Acceptance criteria: 99.9% uptime target (not promise), p99 validation < 200ms, zero unauthenticated admin access in pen test, audit log tamper-evident.

## 15. Development roadmap

Phase 1 (1-2 weeks): requirements, threat model finalization, API/data model spec.
Phase 2 (2-3 weeks): backend foundation - auth, RBAC, DB migrations, audit log, monitoring.
Phase 3 (2-3 weeks): validation endpoint, session/ban/alt-account APIs, webhooks.
Phase 4 (2-4 weeks): detection rules engine + flag review + evidence storage.
Phase 5 (2-3 weeks): dashboard (overview, players, flags, bans, audit).
Phase 6 (1-2 weeks): testing, hardening, staging, limited rollout.
Phase 7 (ongoing): advanced behavioral detection, analytics, scaling.

Total MVP estimate: ~10-17 weeks solo. Risks: Meta attestation availability/limits, scope creep, operational burden.

## 16. Open questions

1. Target platform confirmation: Quest only for v1, or also PC/mobile?
2. Do you want to integrate with ScreechVR's existing PlayFab user IDs or use Meta OVR IDs as primary?
3. Will Voideration serve only ScreechVR or be a multi-game platform (like Tomahawk)?
4. Budget ceiling for hosting and your tolerance for operating infra yourself vs managed services?
5. Do you need Meta device ban sync (requires Meta Device Ban permission + Meta partnership)?
6. Evidence storage needs: screenshots/video or just telemetry?
7. MFA requirement for all admins or only owners?
8. Data retention policy preferences (GDPR-style deletion requests)?

## 17. Recommended starting point

Once approved: Phase 1 only - write a spec doc (API contract + data model + threat model + security boundaries) before any code. Then Phase 2 backend skeleton. Do not start coding until the spec is reviewed.

## 18. Research limitations

- Tomahawk's actual detection algorithms, server implementation, and pricing tiers are not public; treated as unknown.
- The SDK file is an older/simplified snapshot; discrepancies noted (ClientValidationResult enums, stubbed methods).
- The native libTomahawkCore.so was not executed or reverse-engineered (safety).
- The zip archive was not extracted.
- Public site claims (99.99% uptime, <1ms) are marketing and unverified.
- No hands-on access to the Tomahawk portal/dashboard beyond docs.

## 19. Source list

Local files:
- `C:\Users\Void\Downloads\tomahawk stuff\getting started.txt`
- `C:\Users\Void\Downloads\tomahawk stuff\API Referance.txt`
- `C:\Users\Void\Downloads\tomahawk stuff\portal documentation.txt`
- `C:\Users\Void\Downloads\tomahawk stuff\unity implementation.txt`
- `C:\Users\Void\Downloads\tomahawk stuff\validation error codes.txt`
- `C:\Users\Void\Downloads\tomahawk stuff\TomahawkSDK ~ NullHub\Scripts\*.cs`
- `C:\Users\Void\Downloads\tomahawk stuff\TomahawkSDK ~ NullHub\Scenes\TomahawkSplash.unity`

Web:
- https://tomahawk.gg/ (marketing + FAQ)
- Meta Developer Portal docs (developers.meta.com) - referenced for data use permissions
- Photon Dashboard docs - referenced for custom auth
- Hetzner Cloud pricing, Neon/Supabase/Upstash/Cloudflare pricing pages (for cost estimates)

---

## 20. Deep dive: detection pipeline and telemetry schema

Goal: make detection explainable and auditable, not a black box.

Event flow:
1. Client emits telemetry events (session start, heartbeat, movement samples, integrity result) over an authenticated WebSocket to the game server (not directly to backend).
2. Game server (Photon room host or dedicated) validates gameplay state authoritatively and forwards a compact event stream to the backend over HTTPS (batched, every 5-10s or on flag).
3. Backend detection engine evaluates rules against the event stream, produces flags with confidence scores and evidence references.
4. Flags enter a review queue; high-confidence flags can auto-kick/ban per game config; everything is logged.

Telemetry event schema (minimal):
- session_id, player_id, game_id, ts (server-received, not client clock)
- type: session_start | heartbeat | movement_sample | action | integrity_result | disconnect
- payload: typed per type (movement: pos, vel, dt; integrity: layer, result, token)
- client_reported_ts (for skew detection only, never trusted for timing)

Detection rule shape (config-driven, versioned):
- rule_id, name, game_id, enabled, version
- condition: DSL or small expression over recent events (e.g. "speed > 1.3 * maxSpeed for 3 consecutive samples")
- severity: low/medium/high
- confidence_weight: 0-1
- action: none/flag/kick/ban
- cooldown_seconds, min_samples
- thresholds adjustable per game in dashboard

Confidence scoring: sum of weighted triggered rules, clamped 0-1. Auto-action only if confidence >= configured threshold AND at least 2 independent rules triggered (reduces single-signal false positives). Everything below threshold goes to review queue.

Evidence: store the triggering event window (last N samples) as JSON in object storage, referenced by flag row. Never store raw screenshots/video by default (privacy + cost); add only if needed.

Heartbeat: client sends heartbeat every 10s with session nonce; backend checks nonce freshness (like Tomahawk's 45s window) and detects duplicate sessions (same player, two active sessions -> kick ERR-4001 equivalent).

## 21. Deep dive: Meta attestation integration notes

From the native lib and docs, Layer One = Meta's `ovr_DeviceApplicationIntegrity_GetIntegrityToken` plus OVR hooking. Practical implications for Voideration:
- You can call Meta's attestation API from a Quest client to get an integrity token, send it to your backend, and verify it server-side via Meta's verification endpoint. This is the same primitive Tomahawk uses; no kernel driver needed.
- This is platform-compliant and matches Meta's Data Use Permissions (User ID, User Profile, Device Ban).
- Limitations: attestation proves the app binary wasn't tampered at install time and the device isn't rooted in the ways Meta checks; it does NOT detect runtime memory manipulation, speed hacks, or logic exploits. Those must be caught server-side.
- Meta device bans (Device Ban permission) let you push a ban to Meta's platform, blocking the device across apps - powerful but requires careful policy and user disclosure (VRIC-style). Defer until you have multiple titles or a clear abuse problem.
- Unique ID rotation: Meta rotates the app-scoped unique_id every 30 days. Track first-seen and treat the window as an upper bound (Tomahawk's approach). Don't rely on it for long-term identity; use OVR ID + your own account linking.

## 22. Deep dive: cost model with sources

Initial (low scale, single VPS, solo dev):
- Hetzner CPX21 (4 vCPU, 8GB RAM): ~$8.50/mo (hetzner.com/cloud)
- Neon Postgres free tier (0.5GB, auto-suspend): $0; upgrade to Launch ~$19/mo when needed
- Upstash Redis free tier (10k commands/day): $0
- Cloudflare free plan (DNS, WAF, rate limiting, DDoS): $0
- Domain: ~$10-15/yr
- Sentry developer plan: $0
- Backups (Hetzner snapshots, ~20% of disk): ~$1-2/mo
- Total initial: ~$10-12/mo

At ~1k peak CCU:
- Hetzner CPX41 (8 vCPU, 16GB) or two CPX21: ~$30-45/mo
- Neon Launch or Pro Postgres: ~$19-69/mo
- Upstash pay-as-you-go Redis: ~$10-20/mo
- Cloudflare Pro (optional, better WAF): $20/mo
- Bandwidth (Hetzner 20TB included, overage ~$1/TB): ~$0-10/mo
- Total: ~$80-170/mo

Compare to Tomahawk: $600/mo floor + usage-based. At 1k peak CCU you'd likely pay $600-1500/mo with Tomahawk. Self-hosting saves ~$500-1300/mo but costs your engineering time (estimated 10-17 weeks MVP, then ongoing ops ~5-10h/week).

Honest framing: the savings are real only if you maintain the system. If you'd rather ship game features, Tomahawk's $600/mo buys you their team's time. Decide based on your time value, not just the bill.

## 23. Deep dive: dashboard data flow and live updates

- Live CCU: Redis counter incremented on session start, decremented on disconnect/heartbeat timeout; dashboard polls or subscribes via WebSocket (Socket.IO room per org).
- Historical CCU: background job aggregates Redis counters into ccu_snapshots every 1-5 min (configurable). Never store per-second rows.
- Peak: computed from ccu_snapshots (max over range) with timestamp; clearly labeled as "peak in last 24h/7d/30d".
- Ban/flag counts: cached in Redis with TTL, invalidated on write; dashboard reads cache first, DB on miss.
- Live events: WebSocket push for new flags/bans only (not full table refresh); dashboard merges into list.
- Offline/degraded: dashboard shows "stale data" badge if last update > threshold; never silently shows stale as live.

---

## 24. Local file inventory (verified)

| Path (relative to `C:\Users\Void\Downloads\tomahawk stuff`) | Size | Type | Inspected? |
|---|---|---|---|
| `getting started.txt` | 11.7 KB | Markdown-ish text | Yes - full read |
| `API Referance.txt` | 30.8 KB | Markdown-ish text | Yes - full read |
| `portal documentation.txt` | 38.8 KB | Markdown-ish text | Yes - full read |
| `unity implementation.txt` | 36.8 KB | Markdown-ish text | Yes - full read |
| `validation error codes.txt` | 6.1 KB | Text | Yes - full read |
| `TomahawkSDK ~ NullHub/Scripts/TomahawkGamePlugin.cs` | 9.2 KB | C# | Yes - full read |
| `TomahawkSDK ~ NullHub/Scripts/TomahawkClientHelper.cs` | 0.5 KB | C# | Yes |
| `TomahawkSDK ~ NullHub/Scripts/TomahawkPhoton.cs` | 1.9 KB | C# | Yes |
| `TomahawkSDK ~ NullHub/Scripts/TomahawkLog.cs` | 2.1 KB | C# | Yes |
| `TomahawkSDK ~ NullHub/Scripts/ValidationResult.cs` | 0.8 KB | C# | Yes |
| `TomahawkSDK ~ NullHub/Scripts/TomahawkSplash.cs` | 11.8 KB | C# | Yes - full read |
| `TomahawkSDK ~ NullHub/Scenes/TomahawkSplash.unity` | 16.1 KB | Unity YAML | Yes - full read |
| `TomahawkSDK ~ NullHub/TomahawkCore/libTomahawkCore.so` | 5.3 MB | ELF (Android ARM64 native) | Static strings only (read-only, not executed) |
| `TomahawkSDK ~ NullHub (1).zip` | 2.2 MB | Zip archive | Listed entries only (12 entries, identical to extracted folder) |

Nothing was modified, executed, or uploaded. The zip was opened read-only via System.IO.Compression.ZipFile to list entries only.

## 25. Version comparison: extracted folder vs zip

The extracted folder `TomahawkSDK ~ NullHub` and the zip `TomahawkSDK ~ NullHub (1).zip` contain the same 12 entries with identical file sizes and timestamps. Conclusion: they are the same snapshot, not two versions. No historical version diff is available from these files alone.

Inference (medium confidence): the SDK snapshot is OLDER than the documented API because:
- `ClientValidationResult` in the SDK only defines Unknown/Pending/Valid, while the API docs describe Kicked/Banned/Error/NotReady.
- `TomahawkPhoton.IsAvailable()` returns `false` and `IsTomahawkServerEnabled()` returns `false`, while docs describe full Photon and server validation flows.
- `TomahawkPhoton.InjectTokenAsync()` does not actually call Photon APIs (returns Success with the token as Message) - a stub.
- `ValidationResult` lacks an `errorCode` field that the API docs emphasize.

So the docs represent a newer/more complete version; the SDK is a stripped/older snapshot. Treat SDK code as "how the client surface looks", docs as "intended behavior".

## 26. Concrete detection rule catalog (proposed v1)

Each rule is config-driven, versioned, hot-reloadable, with cooldown and min-samples.

| Rule ID | Name | Condition | Severity | Action default | Notes |
|---|---|---|---|---|---|
| R-001 | Impossible speed | speed > 1.25 * maxSpeed for >= 3 consecutive samples | high | flag | Server-authoritative movement |
| R-002 | Teleport | position delta > maxTeleportDistance in one frame | high | flag | |
| R-003 | Invalid state | player reports state server considers impossible (e.g. dead but moving) | high | flag | |
| R-004 | Rate abuse | > N actions/sec for M seconds | medium | flag | |
| R-005 | Replay | duplicate session nonce (ERR-4013/4014 equivalent) | high | kick | |
| R-006 | Duplicate session | same player, two active sessions | high | kick | |
| R-007 | Attestation fail | Meta attestation returns non-success | high | kick | |
| R-008 | Rooted/ADB/cheat software | attestation reports rooted/ADB/known cheat (ERR-5004/5005/5006) | high | ban candidate | Manual review first |
| R-009 | Modified binary | attestation reports modified binary/signature (ERR-5001/5002) | high | ban candidate | |
| R-010 | VPN usage | usingVpn == true | low | log only | Configurable per game |
| R-011 | Alt account | hardware or IP overlap >= 80% | medium | flag | Review, not auto-ban |
| R-012 | Impossible score | score delta exceeds theoretical max per time window | medium | flag | |
| R-013 | Heartbeat gap | no heartbeat for > 2x expected interval | low | flag | Could be network, not cheat |

Auto-action policy: kick/ban only if confidence >= 0.8 AND >= 2 independent rules triggered. Everything else -> review queue. Bans always require human confirmation unless explicitly configured otherwise (default: human confirmation required).

## 27. Backend module breakdown (proposed)

- `auth` - login, refresh, MFA, RBAC, session revocation
- `games` - game CRUD, approval workflow, API key issuance/rotation
- `validation` - validate-user endpoint, session nonce handling, attestation verification
- `sessions` - session lifecycle, heartbeat, duplicate detection
- `players` - player identity, history, search
- `flags` - flag creation, review, disposition
- `bans` - ban/unban, expiry, Meta device ban sync (deferred)
- `detection` - rule engine, confidence scoring, evidence capture
- `altaccounts` - hardware + IP overlap detection
- `webhooks` - Discord + standard, retry, auto-disable
- `stats` - CCU live/historical, ban counts, trends
- `audit` - append-only hash-chained audit log
- `admin` - user/team management, roles
- `config` - per-game security rules, thresholds, kill switches
- `monitoring` - health, latency, error rates, alerting

Each module: controller -> service -> repository -> DB. Validation at controller boundary (Zod). All admin mutations write to audit log.

## 28. Threat model matrix (prioritized)

| # | Threat | Likelihood | Impact | Mitigation | Detection | Residual risk |
|---|---|---|---|---|---|
| 1 | Modified client (speed/teleport) | High | High | Server authority + movement validation | R-001, R-002 | New exploit variants |
| 2 | Forged API requests | High | High | Bearer validation, schema validation, rate limits, replay protection | Auth failures, anomaly alerts | Stolen valid tokens |
| 3 | Detection evasion | High | Medium | Layered signals, server authority, versioned rules, monitoring | Rule hit-rate drops, anomaly | Unknown techniques |
| 4 | Compromised admin account | Medium | Critical | MFA, RBAC, audit log, session timeout | Failed logins, new IPs | Phishing, MFA fatigue |
| 5 | Stolen secrets (API keys) | Medium | High | Secret manager, rotation, least privilege, IP allowlist | Usage from new IP | Slow detection |
| 6 | Fake telemetry | Medium | Medium | Server-corroborated events, confidence scoring | Inconsistent state | Sophisticated fakes |
| 7 | False reports / mass reporting | Medium | Medium | Rate limits, corroboration, review queue | Spike in reports | Harassment campaigns |
| 8 | DoS on validation endpoint | Medium | Medium | Cloudflare, rate limits, caching | Traffic spikes, latency | Distributed attacks |
| 9 | Compromised dependency | Low | High | Lockfiles, Dependabot, SBOM, minimal deps | CVE alerts | Zero-days |
| 10 | Insider misuse | Low | High | RBAC, audit log, approval for destructive ops | Audit review | Trusted insider |
| 11 | DB tampering | Low | Critical | Least privilege, backups, hash-chained audit | Integrity checks | Backup compromise |
| 12 | Malicious update distribution | Low | Critical | Signed builds, CI verification, pinning | Build verification | Supply chain |
| 13 | Alt account ban evasion | Medium | Medium | Hardware + IP overlap detection | Alt account flags | VPN/proxy, new hardware |

## 29. Research ledger (selected)

| Topic | Source | Type | Key finding | Confidence | Relevance | Open question |
|---|---|---|---|---|---|---|
| Tomahawk public features | tomahawk.gg | Marketing | Quest-only now; mobile/PC/SteamOS planned; $600/mo floor | High (public) | High | Real pricing tiers unknown |
| Validation API | local `API Referance.txt` | Docs | actionCode 0/1/2, errorCode, usingVpn, 45s nonce | High | High | Rate limits not documented |
| Error codes | local `validation error codes.txt` | Docs | ERR-1xxx..9xxx grouped by category | High | High | Full per-code handling |
| SDK client | local SDK .cs | Source | ClientValidationResult only Unknown/Pending/Valid (older) | High | Medium | Newer SDK differs |
| Native lib | libTomahawkCore.so strings | Binary (static) | Meta attestation, VPN detect, network monitor, OVR hooking | Medium (inference) | High | Detection algos unknown |
| OWASP API Top 10 2023 | owasp.org | Standard | BOLA, broken auth, mass assignment, SSRF, etc. | High | High | Apply to Voideration API |
| IL2CPP | Unity docs | Docs | AOT, no JIT, platform-required on Quest | High | High | Obfuscation interaction |
| Meta attestation | (not found online) | - | Docs gated/404 | Low | High | Need Meta dev portal access |

## 30. Unresolved technical questions (expanded)

1. Meta attestation: exact API name, verification endpoint, and whether it requires a special partnership (Device Ban permission). Need Meta developer portal access to confirm.
2. Whether Voideration should be multi-game from v1 or single-game (ScreechVR only). Affects data model (org/game scoping) and cost.
3. Whether to integrate with PlayFab user IDs or Meta OVR IDs as primary identity. PlayFab is already in the stack; Meta OVR ID is what Tomahawk keys on.
4. Meta device ban sync: requires Meta Device Ban permission + policy disclosure in EULA. Decide if worth it for v1.
5. Evidence storage needs: telemetry only vs screenshots/video. Huge cost/privacy implications.
6. MFA: TOTP for all admins or only owners? Recommend TOTP for all admins.
7. Data retention: GDPR-style deletion requests, ban record retention for appeals.
8. Whether to expose a public ban appeal flow or handle via Discord/support tickets.
9. Hosting: self-operated VPS vs managed (Fly.io/Render) - trade-off of cost vs ops burden for a solo dev.
10. Real-time transport: WebSocket (Socket.IO) vs SSE vs polling. SSE is simpler and sufficient for dashboard-only live updates.

## 31. Research limitations (expanded)

- Tomahawk's actual detection algorithms, server implementation, exact pricing tiers, and real uptime are not public.
- The SDK snapshot is older/simplified; discrepancies documented.
- The native .so was analyzed via static strings only (read-only, not executed, not disassembled). No reverse engineering of logic.
- The zip archive was listed but not extracted (entries identical to extracted folder anyway).
- Meta attestation docs could not be fetched (404 on tried URLs); inferred from native symbols + Tomahawk docs.
- Web search tool returned 404; research relied on direct webfetch of known URLs and local files.
- No hands-on access to Tomahawk portal/dashboard.
- Cost estimates are from public pricing pages and may be outdated; verify before committing.
- No peer-reviewed papers or conference talks were accessible in this environment.

---

## 32. Unity asset integrity findings (from Unity docs)

Key facts relevant to anti-cheat design:
- AssetBundles cannot contain assemblies (C# classes). They can contain serialized ScriptableObject instances and other assets. Unity matches objects by assembly/namespace/class name and uses type trees to adjust field mappings across Unity versions.
- AssetBundles are platform-specific and not forward-compatible (newer Unity can't load bundles built by older... actually older bundles load into newer Unity; not the reverse).
- Safe binary read uses type trees; if bundles are built with `DisableWriteTypeTree`, serialization changes break loading (crash risk). Rebuilding is required on Unity upgrades.
- AssetBundle integrity verification: Unity supports verifying downloaded AssetBundles (hash/checksum) - see "Verifying downloaded AssetBundles".
- Implication for Voideration: client asset integrity checks are feasible (hash manifests) but must be version-aware (build ID + Unity version + asset manifest hash). Treat any mismatch as a flag, not an auto-ban, because legitimate updates and platform differences cause mismatches. Server-side enforcement of "allowed build versions" (Tomahawk's ERR-3001/3002) is the reliable gate; client asset hashing is a supporting signal.

## 33. Cryptography guidance (OWASP Cryptographic Storage Cheat Sheet)

Confirmed best practices to apply:
- Symmetric: AES-256 in authenticated mode (GCM or CCM). Never ECB. CTR/CBC only with separate MAC (Encrypt-then-MAC). Never custom algorithms.
- Asymmetric/public-key encryption: HPKE (RFC 9180) with X25519; RSA only if required, >= 2048-bit with OAEP (RFC 8017).
- Post-quantum: ML-KEM (FIPS 203) in hybrid construction for long-lived secrets; AES remains fine for symmetric.
- Randomness: CSPRNG only (Node `crypto.randomBytes`/`randomUUID`) for keys, IVs, session IDs, tokens. Never `Math.random()`.
- Key management: formal processes, random key generation, rotation on compromise/schedule/algorithm change, cryptoperiod per NIST SP 800-57.
- Key storage: prefer HSM/KMS (AWS KMS, Azure Key Vault, HashiCorp Vault, or cloud provider KMS). Separate keys from data (different systems). Envelope encryption (DEK/KEK). Never hardcode, never commit, avoid env vars where possible (exposure risk), restrictive file perms.
- Defense in depth: encryption is not a substitute for access control; assume encrypted params can be manipulated.
- Client-side: no secret keys in client code ever. Client integrity checks are signals, not security boundaries.

## 34. Deep research limitations (final)

- Meta attestation docs could not be fetched (all tried URLs 404). Inferred from native lib symbols + Tomahawk docs. Needs Meta developer portal access to confirm exact API and verification endpoint.
- Web search tool returned 404 throughout; research relied on direct webfetch of known URLs plus local files. This limits discovery of additional sources.
- No hands-on portal access, no reverse engineering of the native .so beyond strings.
- Cost estimates from public pricing pages; verify before committing.
- No peer-reviewed papers accessible in this environment.

---

## 35. Binary reverse-engineering: libTomahawkCore.so

### 35.1 File identity
- Path: `C:\Users\Void\Downloads\tomahawk stuff\TomahawkSDK ~ NullHub\TomahawkCore\libTomahawkCore.so`
- Size: 5,266,416 bytes (5.02 MiB)
- SHA-256: `150710A0ED22048DDD3B18C49D7837EA60803B67DE768A6160DFF6A96ADD2B85`
- MD5: `26AECDD297B62C50E915E1A8F067C43C`
- Format: ELF64, little-endian, ET_DYN (shared object), EM_AARCH64 (ARM64), e_flags 0
- Build: Android NDK r23c (clang 9/11/12), target android-21 (arm64-v8a), built with `-O3`
- .note.android.ident names the build; no SONAME version beyond `libTomahawkCore.so`
- Stripped: no `.symtab` (only `.dynsym` with 284 entries, 19 defined/exported functions). `.gnu_debuglink` points to `libTomahawkCore.debug` (CRC b86c765e) which is NOT present in the research folder -> debug symbols unavailable. All analysis is from machine code; treat as inferred.
- No packing/obfuscation indicators: standard section layout, no UPX, no encrypted sections. Standard ELF.

### 35.2 Sections and segments
- 4 LOAD segments: RX code (0x132000, 3.4MB .text), RW data (0x498a70), RO data (0x0, 1.2MB), BSS.
- Key sections: `.text` (3.56MB), `.rodata` (494KB), `.data.rel.ro` (414KB), `.data` (31KB), `.bss` (25KB), `.rela.dyn` (593KB, 24714 relative relocs applied during analysis), `.rela.plt` (6.3KB), `.gcc_except_table`, `.eh_frame` (81KB, C++ exceptions present), `.init_array`/`.fini_array` (8 constructors).
- Dependencies (NEEDED): libm, liblog, libandroid, libdl, libc. No libcrypto/libssl dynamic dep (OpenSSL statically linked, visible in .comment/strings). No JNI beyond JNI_OnLoad.

### 35.3 Exported public API (19 functions)
setTomahawkLogCallback, isTomahawkReInit, tomahawkCoreInitialize, tomahawkCoreGetStatus, tomahawkCoreIsComplete, tomahawkCoreIsFailed, tomahawkCoreGetErrorCount, tomahawkCoreGetError, tomahawkCoreGetSessionNonce, tomahawkCoreIsNetworkAvailable, tomahawkCoreSetNetworkCallback, tomahawkCoreStartNetworkMonitor, tomahawkCoreStopNetworkMonitor, tomahawkCoreIsVPNActive, T_CV, T_CVR, T_SD, T_FC, JNI_OnLoad.

### 35.4 Imported functions (selected, by category)
- Meta/Oculus: `ovr_DeviceApplicationIntegrity_GetIntegrityToken`, `AAssetManager_open/close/getLength/read`, `AAssetManager_fromJava`, `__android_log_print`, `__system_property_get`.
- Networking: socket, connect, bind, listen, accept, send/recv/sendto/recvfrom, getaddrinfo, inet_pton/ntop, poll/select, setsockopt, getsockopt, socketpair, shutdown.
- Process/threads: pthread_create/detach/join, mutex/rwlock/cond, fork, exec, waitpid, kill, dlopen/dlsym/dladdr, sigaction, sigprocmask.
- Crypto (static OpenSSL): AES/SHA/RSA primitives (strings indicate OpenSSL 1.1.x).
- File I/O: fopen/fread/fwrite/fseek/fstat/open/read/write/close/mkdir/rename/unlink.
- System: getentropy, madvise, mlock, mmap, mprotect, munmap, sysconf, clock_gettime, gettimeofday.
- libc: malloc/calloc/realloc/free, memcpy/memmove/memset, strlen/strcmp/strncmp/snprintf/sprintf/sscanf, qsort, getenv, gethostname, geteuid, getpwuid_r.

Notable: `dlopen`/`dlsym`/`dladdr` present -> dynamic loading of other libs at runtime (plugin-style). `fork`/`exec`/`kill`/`waitpid` present -> the library can spawn child processes (likely for integrity checks or network monitor helpers). `mlock`/`mprotect`/`madvise` -> memory protection of sensitive buffers (keys/nonces). `getentropy` -> CSPRNG for nonces/keys.

### 35.5 JNI_OnLoad
Reconstructed: calls a function at 0x420478 (constructor-ish) then sets return value to JNI_VERSION_1_6 (0x00010006). Standard JNI registration entry. No unusual behavior visible.

### 35.6 Constructors (INIT_ARRAY, 8 entries, via RELATIVE relocs)
0x2ee0a0, 0x3e1f48, 0x3f05c0, 0x3f7b28, 0x3f96c4, 0x41ea04, 0x420478, 0x431098.
Disassembly shows these initialize global state (mutexes, condition variables, function pointers in .data.rel.ro), register atexit handlers, and set up logging callback tables. Several reference OpenSSL/RSA constants (movz/movk sequences producing large immediates consistent with RSA moduli or IV seeds) and call into large internal functions (likely crypto init or network init). Exact purpose of each requires deeper analysis; the .gnu_debuglink debug file would resolve this.

### 35.7 Reconstructed pseudocode (key exported functions)

tomahawkCoreInitialize (va 0x41c51c, 44 bytes):
```
// args: appId (x0), enableAttestation (x1), enableOBB (x2), useGameOVR (x3), maxRetries (x4, on stack)
global.appId = appId;
global.enableAttestation = (enableAttestation != 0);
global.enableOBB = (enableOBB != 0);
global.useGameOVR = (useGameOVR != 0);
global.maxRetries = maxRetries;
rc = internal_init(...);          // bl to 0x413bb? (offset -121460)
return (rc == 0 ? 0 : rc);        // and w0,w0,#... (mapped)
```
Calls an internal init routine; returns 0 on success. Sets global config from args. Confirms managed-side config flows into native state.

tomahawkCoreGetStatus (0x41c548): reads a global status byte at [global+0xee2828+0x282? -> resolved via adrp] and returns it. Effectively `return g_status;`.

tomahawkCoreIsComplete (0x41c558): reads same global, compares to 1 (0xd1? actually `cmp ... #0x0d`? the `71000d1f` = cmp w? , #0x0d? no, `subs wzr, w?, #0x0d`) then returns (x == 0x0d ? 1 : 0) via cset. So "complete" means status == 13 (0x0d). Interesting: status enum likely 13 = complete.

tomahawkCoreIsFailed (0x41c570): same global, status == 17 (0x11) -> failed.

tomahawkCoreGetErrorCount (0x41c588): returns 0 (hardcoded) in this build - stubbed in this older snapshot. Consistent with SDK being older/simplified.

tomahawkCoreGetError (0x41c590): if outBuffer (x1) is null or size (x2?) < ... writes 0 to *x1 and returns 0. Stub-ish: always returns empty error. Consistent with older snapshot.

tomahawkCoreGetSessionNonce (0x41c5a8): complex. Allocates 80-byte stack frame. If buf (x0) is null -> return 0 (w20=0). Otherwise calls an internal routine at 0x413? (bl -18744) that fills a struct, reads a status byte, branches; on success copies up to 512 bytes into the output buffer via a helper (bl #501904, likely memcpy/strncpy), null-terminates, and if the nonce changed since last call, invokes the registered log callback (OnSessionNonceRefreshed path). Returns 0 on success, writes length. So: nonce is generated/stored in native global state, refreshed on change, max 512 bytes, null-terminated, with a refresh callback. Matches docs: "session nonce", "expires after 45s" (expiry likely enforced server-side; client just fetches current).

T_CV (0x41c6cc): client validation entry. Sets up, calls internal routines (0x413? and 0x414?), reads a status byte, branches; on the success path calls more helpers; returns a mapped int. The managed wrapper `ValidateClientAsync` maps native results: 23 -> Pending, 32 -> Valid, -2..1 -> direct, else Unknown. So native T_CV returns one of these magic numbers. The disassembly shows calls into network/attestation helpers and status polling. Inference: T_CV triggers attestation + server validation and returns a result code.

T_CVR (0x41c6d0): get last CV reason. Similar structure to T_CV's error path: fills a 512-byte buffer, returns bytes written. Reads error string from global. Matches docs: GetLastCVReason().

T_SD (0x41c674): "set ..."? Possibly "set device" or "send data". Calls internal, writes globals. Inference: configures a device/identity field. Low confidence; needs debug symbols.

T_FC (0x41c7f4): "force close/terminate". Loads a struct, conditionally calls cleanup (0x414a44, 0x4149f7), iterates a list (cleanup of resources), calls free. Matches `ForceTerminate()` in managed code (T_FC + Application.Quit). So T_FC tears down native state (sockets, threads, mutexes).

isTomahawkReInit (0x41c660): reads a global flag (byte at global+0xee2828+0x286?) and returns it (and w0, w8, #imm). Effectively `return g_reinitFlag;`.

tomahawkCoreIsNetworkAvailable (0x41c7c0): calls an internal func (bl #55932) then `and w0,w0,#?` -> returns bool. Network availability check.

tomahawkCoreIsVPNActive (0x41c7e0): calls internal (bl #56704) then masks result -> returns bool. VPN detection. Confirmed symbol present in earlier strings; now confirmed it's a real exported function calling a helper.

tomahawkCoreStart/Stop/SetNetworkMonitor/Callback (0x41c7d4/d8/dc): these are trampolines (b #58608 etc.) jumping into a shared implementation at 0x41c??. They set up a network monitor (thread + socketpair + pthread). Inference: monitors network connectivity and invokes a callback on change (for heartbeat/retry logic).

setTomahawkLogCallback (0x3f7b78): stores the callback function pointer into a global (str x0, [x8, #2416]), and if non-null, calls an internal routine with level=1 (w0=1), level=4 (w1=4), and a format string at adrp+3181. So: registers a managed log callback into native code, and immediately logs a message ("Tomahawk..."?). This is the bridge for native -> managed logging (TomahawkLog).

JNI_OnLoad (0x42ad58): standard, sets JNI version 1_6, calls init helper. No custom registration visible (RegisterNatives not in imports list - interesting: no RegisterNatives import). So native methods are likely resolved by name mangling or the managed side uses DllImport by name (which matches the C# `DllImport("TomahawkCore")` declarations). Consistent.

### 35.8 Security-relevant observations (defensive, inferred)

1. No kernel-level access: only standard Android NDK APIs + Meta's `ovr_DeviceApplicationIntegrity_GetIntegrityToken`. Confirms platform-compliant approach; no rootkit/driver. Good for Voideration's platform compliance.
2. VPN detection is a first-class feature (exported `tomahawkCoreIsVPNActive`), consistent with API `usingVpn` field and ERR-6xxx network codes.
3. Network monitoring is continuous (start/stop/callback), feeding heartbeat/retry logic. Matches "heartbeat failed after retrying" (ERR-6024/6025).
4. Memory protection: mlock/mprotect/madvise imported -> sensitive buffers (nonces, keys) are locked/pinned. Good practice for Voideration.
5. Process spawning: fork/exec/waitpid/kill imported -> likely used for sandboxed integrity checks or helper processes. Risk: if misused, could be an attack surface; for Voideration, avoid spawning processes; do checks in-process.
6. Dynamic loading: dlopen/dlsym/dladdr -> plugin-style loading of additional native modules. For Voideration, prefer statically linked or verified-loaded modules only.
7. Cryptography: OpenSSL statically linked (AES/SHA/RSA). Keys protected via mlock; KDF/nonce generation via getentropy (CSPRNG). Aligns with OWASP guidance (AES-256-GCM, CSPRNG, no custom crypto).
8. Error reporting: GetError/GetErrorCount are stubbed in this older build (always 0/empty) - consistent with "older snapshot" conclusion. Newer builds presumably populate errors.
9. Session nonce: generated in native, max 512 bytes, null-terminated, refresh callback when changed. Expiry (45s) enforced server-side.
10. Attestation: Meta's device application integrity token is the Layer One primitive. Tomahawk sends it to its backend for verification. Voideration can replicate via Meta's API (needs partnership/permissions).
11. No hardcoded URLs/API keys in the binary: all endpoints configured at runtime from managed side. Good (no secret leakage in binary). Voideration should follow this: no secrets in client binary.
12. C++ exceptions present (gcc_except_table, eh_frame) -> code is C++ with try/catch; error paths exist.

### 35.9 What cannot be determined (limitations)

- Exact detection algorithms (the .text beyond the 19 exported stubs is large, ~3.5MB, mostly internal + OpenSSL; full disassembly not feasible without a real disassembler).
- The .gnu_debuglink debug file (`libTomahawkCore.debug`) is not in the research folder, so symbol names for internal functions are unavailable.
- Whether `tomahawkCoreInitialize` actually verifies attestation synchronously or kicks off async polling (managed side polls via `tomahawkCoreIsComplete/IsFailed`).
- The exact global state layout (status codes, reinit flag offsets) - inferred from adrp offsets, not confirmed.
- No runtime execution was performed (safety), so no dynamic behavior observed.
- The zip and extracted folder are identical; no second version for diffing.

### 35.10 Relevance to Voideration

- Replicate the pattern: thin native client (attestation + nonce + heartbeat + VPN detection) + managed wrapper + server-side verification. Don't put secrets in the client.
- Use Meta's attestation as Layer One; treat as a signal, not a gate. Server authority is the real gate.
- Include VPN detection and network monitoring as first-class signals (useful for abuse detection).
- Protect sensitive buffers with mlock/mprotect; use CSPRNG (getentropy) for nonces.
- Avoid process spawning and dynamic loading in the client unless necessary (attack surface).
- Keep the client binary free of hardcoded endpoints/keys.
- Version enforcement (ERR-3001/3002) and build IP whitelist are good operational controls to adopt.
- Webhook auto-disable on repeated failures is a good reliability pattern.

### 35.11 Tooling used and limitations

- Tools available: Python 3.12 (standard library only), PowerShell. No binutils (readelf/objdump/nm/strings), no disassemblers (Ghidra/IDA/radare2/capstone), no WSL.
- Analysis performed: ELF header/section/segment parsing, dynamic section, dynsym import/export extraction, relocation application, string extraction (14k+ lines), and a hand-written minimal ARM64 decoder applied to the 19 exported functions + 8 constructors.
- Not performed: full disassembly of 3.5MB .text, decompilation, control-flow graph recovery beyond small functions, dynamic analysis.
- The hand-written decoder has gaps (many instructions rendered as `dc 0x...`), so pseudocode is approximate. A real disassembler (Ghidra/IDA/radare2) would significantly improve fidelity; installing one requires your approval.

---

## 36. Ghidra deep reverse-engineering findings (libTomahawkCore.so)

Tooling: Ghidra 12.2 (headless, `analyzeHeadless`), Java script via `-scriptPath`/`-postScript`. Analysis completed in 177s. Decompiler output: 44.9 KB, 1715 lines. Function list: see `ghidra-funclist.txt` (hundreds of auto-named functions, mostly OpenSSL internals).

### 36.1 Confirmed: heavy OpenSSL usage (not custom crypto)
The decompiled constructors and helpers are identifiable OpenSSL code:
- `FUN_002ee098` = `PKCS5_pbe2_set_iv_ex` (crypto/asn1/p5_pbev2.c) - password-based encryption v2 (PBES2) IV setup.
- `FUN_0041e9f8` = `PKCS8_set0_pbe_ex` (crypto/pkcs12/p12_p8e.c) - PKCS#8 encrypted private key handling.
- `FUN_00420318` = `PKCS7_dataInit` (crypto/pkcs7/pk7_doit.c) - PKCS#7/CMS data init (signed/encrypted containers).
- `FUN_00430fe0` = `RSA_setup_blinding` (crypto/rsa/rsa_crpt.c) - RSA blinding for side-channel protection.
- `FUN_0042acec` = `rand_pool_grow` (crypto/rand/rand_pool.c) - CSPRNG pool growth (uses `getentropy`-backed pool, crypto/rand).
- `FUN_003f0548` = a typed value parser (int/long/double) used for config/ASN.1 fields.
- `FUN_003f9608` = typed value container (type 1/2/3 = int64/double/...).
- `FUN_0041c6fc` = a network/session helper (calls FUN_003d1764 to parse, FUN_0041effc for network op, FUN_002eeca0 cleanup).
- `FUN_0041c604` = collection/validation helper (alloc via FUN_0044da58, insert via FUN_0044e344, type code 0x95=149).
- `FUN_0041c51c` = generic "register parsed object into collection" helper (validates two fields, allocates collection, inserts, cleans up on failure).

Conclusion: Tomahawk's native crypto is OpenSSL (AES/RSA/PKCS#5/7/8, CSPRNG), not custom. Defensive lesson for Voideration: use established crypto libs (libsodium/OpenSSL), never hand-rolled crypto. Confirms the OWASP guidance.

### 36.2 Key architectural findings

- The exported `tomahawkCore*` functions are thin entry points (4-240 bytes) that delegate to internal helpers in the merged blocks. Ghidra merged them because the binary is stripped (no symbol boundaries), so each "function" spans multiple exports.
- `tomahawkCoreInitialize` (0x41c51c region): validates input (two int fields via FUN_00487bd0/FUN_0041bdd4 and FUN_00487bfc/FUN_0041bd44), parses via FUN_0041ed4c, optionally allocates a collection (FUN_0044da58) and inserts (FUN_0044e344), cleans up on failure. Returns 0 on success.
- `tomahawkCoreGetSessionNonce` (in the same block): fills a buffer (max 512 bytes, null-terminated) via internal helpers, tracks a "changed" flag, invokes a refresh callback when the nonce changes. Matches docs: 45s expiry enforced server-side; client fetches current nonce.
- `tomahawkCoreGetError`/`GetErrorCount`: in this older build, `GetErrorCount` returns 0 and `GetError` always writes 0/empty - stubbed. Consistent with "older snapshot" conclusion.
- `setTomahawkLogCallback` (0x3f7b78): stores the callback pointer in a global (`str x0, [x8, #2416]`), and if non-null immediately logs a message (level=1, then level=4) via an internal routine. Bridge for native->managed logging.
- `T_FC` (0x41c7f4): teardown - iterates a list (cleanup of resources/sockets/threads), calls free. Matches `ForceTerminate()`.
- `JNI_OnLoad` (0x42acec region): standard JNI version 1_6; the surrounding code is OpenSSL's rand_pool_grow (CSPRNG). No custom JNI registration (RegisterNatives not imported) - methods resolved by name via DllImport.

### 36.3 Security-relevant confirmed findings

1. Meta attestation is Layer One: `ovr_DeviceApplicationIntegrity_GetIntegrityToken` (imported) is the device/application integrity primitive. No kernel driver, no rootkit. Platform-compliant.
2. VPN detection is first-class: `tomahawkCoreIsVPNActive` exported, backed by an internal helper. Matches API `usingVpn` field.
3. Network monitoring is continuous: start/stop/callback exported, backed by socketpair + pthread + poll. Feeds heartbeat/retry (ERR-6024/6025).
4. Memory protection: mlock/mprotect/madvise imported -> sensitive buffers (nonces, keys) locked/pinned. Good practice.
5. CSPRNG: getentropy + OpenSSL rand_pool (confirmed by decompiled `rand_pool_grow` with source path "crypto/rand/rand_pool.c"). Never custom RNG.
6. No hardcoded secrets/URLs in the binary: endpoints configured at runtime from managed side (verified by string search + decomp). Good.
7. OpenSSL TLS with certificate handling (PKCS#7/8, RSA blinding) -> transport security uses established TLS, not custom.
8. Process spawning (fork/exec/waitpid/kill) and dynamic loading (dlopen/dlsym) are imported -> present in the codebase (likely for sandboxed checks/helpers). Attack surface to avoid in Voideration's client.
9. C++ exceptions present (gcc_except_table, eh_frame) -> error paths exist; error handling is structured.

### 36.4 What the native layer does NOT do (important for threat model)

- No kernel-level/rootkit anti-tamper.
- No custom cryptography.
- No obfuscation/packing (standard ELF, no UPX, no encrypted sections).
- No hardcoded API keys or endpoints.
- Detection logic (root detection, cheat software detection) is not in this library in a recoverable form - it's either in the managed/attestation layer or server-side. The native lib is a thin transport/attestation/heartbeat wrapper.

### 36.5 Remaining unanalyzed

- The bulk of .text (~3.5MB) is OpenSSL + internal helpers; full function-level decompilation would require more time but the security-relevant entry points above are covered.
- The .gnu_debuglink debug file (`libTomahawkCore.debug`) is absent, so internal symbol names remain unavailable (Ghidra auto-named them FUN_*).
- No runtime/dynamic analysis performed (safety).

---

STOP: extended research phase complete. No implementation performed. Awaiting your explicit approval before any code is written.


voideration-anticheat-review.md
# Voideration Anti-Cheat - Critical Review of Research

Review of `docs/voideration-anticheat-research.md` and the Ghidra analysis. Research-only, no implementation.

## 1. Ghidra findings audit

The research report and the binary notes disagree on several points. Resolved below.

### Conflicting address/function identification (RESOLVED)

The earlier `dynsym` sizes (e.g. tomahawkCoreInitialize = 44 bytes at 0x41c51c) are NOT individual functions. Ghidra's analysis shows each export sits inside a larger merged function because the binary is stripped (no symbol boundaries). Mapping:

| Exported entry | Ghidra function (entry) | Ghidra size | What it actually is |
|---|---|---|---|
| 0x41c51c tomahawkCoreInitialize | FUN_0041c51c | 232 | Generic "register parsed object into collection" helper (validates 2 fields, allocates, inserts, cleans up) |
| 0x41c548 tomahawkCoreGetStatus | (same FUN_0041c51c) | 232 | sub-routine inside the helper |
| 0x41c558 tomahawkCoreIsComplete | (same) | 232 | sub-routine |
| 0x41c570 tomahawkCoreIsFailed | (same) | 232 | sub-routine |
| 0x41c588 tomahawkCoreGetErrorCount | (same) | 232 | sub-routine (returns 0 in this build) |
| 0x41c590 tomahawkCoreGetError | (same) | 232 | sub-routine (writes empty) |
| 0x41c5a8 tomahawkCoreGetSessionNonce | (same) | 232 | sub-routine (buffer fill, refresh callback) |
| 0x41c660 isTomahawkReInit | FUN_0041c604 | 248 | Collection/validation helper (type code 0x95=149) |
| 0x41c674 T_SD | (same FUN_0041c604) | 248 | sub-routine |
| 0x41c6cc T_CV | (same FUN_0041c604) | 248 | sub-routine |
| 0x41c6d0 T_CVR | (same FUN_0041c604) | 248 | sub-routine |
| 0x41c7c0 tomahawkCoreIsNetworkAvailable | FUN_0041c6fc | 304 | Network/session helper (parse + network op + cleanup) |
| 0x41c7d4 StartNetworkMonitor | (same FUN_0041c6fc) | 304 | sub-routine (trampoline to shared impl) |
| 0x41c7d8 StopNetworkMonitor | (same) | 304 | sub-routine |
| 0x41c7dc SetNetworkCallback | (same) | 304 | sub-routine |
| 0x41c7e0 IsVPNActive | (same) | 304 | sub-routine |
| 0x41c7f4 T_FC | (same) | 304 | teardown sub-routine |
| 0x3f7b78 setTomahawkLogCallback | FUN_003f7b68 | 44 | buffer/remaining-bytes helper (NOT the log callback store) |
| 0x42ad58 JNI_OnLoad | FUN_0042acec | 356 | OpenSSL rand_pool_grow (CSPRNG) - merged region |
| 0x2ee0a0 (ctor) | FUN_002ee098 | 704 | PKCS5_pbe2_set_iv_ex (OpenSSL) |
| 0x3e1f48 (ctor) | FUN_003e1f20 | 132 | list/enumeration helper |
| 0x3f05c0 (ctor) | FUN_003f0548 | 160 | typed value parser (string lookup) |
| 0x3f7b28 (ctor) | FUN_003f7ad4 | 120 | registration/validation helper |
| 0x3f96c4 (ctor) | FUN_003f9608 | 592 | typed value container (int/long/double) |
| 0x41ea04 (ctor) | FUN_0041e9f8 | 252 | PKCS8_set0_pbe_ex (OpenSSL) |
| 0x420478 (ctor) | FUN_00420318 | 1840 | PKCS7_dataInit (OpenSSL) |
| 0x431098 (ctor) | FUN_00430fe0 | 680 | RSA_setup_blinding (OpenSSL) |

### Confirmed vs inferred (security claims)

| Claim in research | Evidence | Confidence |
|---|---|---|
| Meta attestation is Layer One | Imported symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` + docs (ERR-5xxx) | High (symbol confirmed, exact API docs unverified) |
| VPN detection first-class | Exported `tomahawkCoreIsVPNActive` + `usingVpn` API field | High |
| Network monitoring continuous | Exported start/stop/callback + socket/pthread imports | High (mechanism inferred from imports) |
| CSPRNG via getentropy/OpenSSL | `getentropy` import + decompiled `rand_pool_grow` with source path "crypto/rand/rand_pool.c" | High |
| Memory protection (mlock/mprotect) | Imported symbols | Medium (imported, usage inferred) |
| No hardcoded secrets/URLs | String search found no tomahawk.gg/api URLs | Medium (could be constructed at runtime) |
| Process spawning (fork/exec) | Imported symbols | Medium (present, purpose inferred) |
| Dynamic loading (dlopen/dlsym) | Imported symbols | Medium |
| Error counts stubbed in this build | Decompiled GetErrorCount returns 0, GetError writes empty | High |
| Detection algorithms in native lib | NOT found; only transport/attestation/heartbeat wrapper | High (absence of evidence) |
| Root/cheat-software detection | Not in this lib; likely server-side or attestation-derived | Medium inference |

### Critical correction

The earlier claim "tomahawkCoreInitialize sets globals and calls internal init" was based on my ARM64 disasm of 44 bytes. Ghidra shows the function at 0x41c51c is actually a 232-byte generic collection-registration helper, and the real `tomahawkCoreInitialize` (the 44-byte export) is the first sub-routine inside it. The managed C# code calls `tomahawkCoreInitialize(appId, ...)` which maps to this helper. So the "init" is really "register/validate an object into a collection" - the actual Tomahawk init happens in the managed layer (TomahawkGamePlugin.Awake/Start) + the native helper. This does NOT change the architectural conclusion (thin native wrapper + managed logic), but the earlier pseudocode was slightly off. Confidence in the corrected version: medium-high.

### Evidence limits

- No `.symtab` (stripped). All function names are Ghidra auto-names (FUN_*) or dynsym exports.
- The `.gnu_debuglink` debug file is missing, so internal names are unavailable.
- No runtime/dynamic analysis performed (safety).
- Ghidra's decompiler output for merged functions cannot distinguish the exact boundaries of exported sub-routines; the ARM64 disasm provides those boundaries.

## 2. Meta attestation verification

### What I could verify
- The native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` is present in libTomahawkCore.so (confirmed via strings + Ghidra imports). This is Meta's Device Application Integrity API.
- Tomahawk's API error codes ERR-5001 (modified binary), ERR-5002 (invalid signature), ERR-5003 (missing Meta security update), ERR-5004 (rooted), ERR-5005 (ADB enabled), ERR-5006 (known cheat software), ERR-5101-5108 (attestation failures) are documented in the local `validation error codes.txt` and `API Referance.txt`.
- Meta Data Use Permissions required: User ID, User Profile, Device Ban (from `getting started.txt`).

### What I could NOT verify (docs gated/404)
- The exact Meta API endpoint, request/response schema, token verification process, and eligibility requirements for `ovr_DeviceApplicationIntegrity_GetIntegrityToken`. All tried URLs (developer.oculus.com, developers.meta.com) returned 404.
- Whether Device Ban sync requires a separate Meta partnership or is self-service.
- The 30-day unique_id rotation policy details beyond Tomahawk's docs.
- Whether attestation is available to all developers or gated behind approval.

### Marked as unverified in the report
- Section 21 (Meta attestation integration notes) and the "Meta attestation is Layer One" claim should be tagged: "symbol confirmed; API docs not accessible; treat as unverified until Meta developer portal is consulted."

### Implication for Voideration
- Do NOT build the anti-cheat assuming Meta attestation is freely available. Confirm eligibility, permissions, and token verification endpoint with Meta before depending on it. Fallback: server-authoritative validation only (no client attestation), which is still viable but weaker.

## 3. Photon architecture correction

The research report conflated "Photon" as a single thing. It is not. Distinct components with different trust properties:

### Photon Cloud (managed, SaaS)
- Photon hosts the servers. You do not control them.
- Provides matchmaking, room management, message relay.
- Supports Custom Authentication: Photon's servers call YOUR backend URL to verify a token during connect. This is server-to-server; your backend validates, Photon enforces the result.
- Does NOT validate game logic, movement, or state. It relays messages.
- Cannot run authoritative game logic. The "master client" is just a player with a flag.

### Master Client (a player, NOT a server)
- One player in the room is designated master client.
- Has authority over room properties, spawning, and scene loading (AutomaticallySyncScene).
- Is a CLIENT. If the master client cheats, they can manipulate room state, kick players (KickIfBanned pattern in Screech), load scenes. This is a known attack vector (the PVP-return bug root cause was related to this).
- Cannot be trusted for security decisions. Use it for convenience (spawn coordination) only, never for anti-cheat enforcement.

### Trusted backend service (your server)
- Your backend (Node/PlayFab/Cloudflare) validates session nonces, bans, alt accounts.
- Connected to Photon via Custom Authentication (server-to-server REST).
- This is where real security lives. Photon Cloud delegates auth to it.

### Dedicated authoritative server (Photon Server / self-hosted)
- Photon Server (self-hosted) or a dedicated game server you run.
- Can run authoritative game logic, validate movement/state, reject invalid actions.
- Strongest protection (Tomahawk's "Server Validation" method).
- Cost/complexity: requires server infrastructure, matchmaking, and ops. Not realistic for v1 of a solo-dev Quest game.

### Implication for Voideration MVP
- v1: Photon Cloud + backend validation (Custom Auth) + server-authoritative checks where feasible (movement validation in a Photon plugin or via a trusted relay). Master client used only for convenience, never for security.
- v2 (if needed): migrate to Photon Server or add a dedicated validation service for high-value operations (currency, scores).
- The research report's "Photon Integration" section must distinguish these. Update: Backend Validation (trusted) is the realistic v1; Server Validation (dedicated) is v2+.

## 4. Cost and timeline challenge

### Assumptions in the report
- Initial cost ~$10-35/mo assumes: single Hetzner VPS, free tiers for DB/Redis/Cloudflare, no egress overage, no monitoring beyond free Sentry.
- 1k CCU cost ~$80-170/mo assumes: linear scaling, no DB query optimization issues, no Redis memory pressure.
- Timeline 10-17 weeks solo assumes: full-time availability, no scope creep, no debugging of detection false positives, no Meta attestation integration delays.

### What needs validation before trusting
- Load testing the validation endpoint under realistic CCU (k6). The 2-min cache claim and p99 < 200ms are untested assumptions.
- DB query performance under concurrent session writes (sessions, heartbeats, flags). Indexing strategy untested.
- Redis memory usage for session state at scale (key-per-session vs. sorted sets).
- Meta attestation latency and availability (unknown; docs inaccessible).
- Detection false-positive rate: cannot be estimated without real session data. Budget 2-4 weeks of tuning after launch.
- Solo dev availability: 10-17 weeks assumes full-time. Realistic is 20-30 weeks part-time.

### Revised honest estimates
- MVP (backend + validation + basic dashboard + 3 detection rules): 12-20 weeks solo, part-time.
- Cost: $10-35/mo initial, $80-200/mo at 1k CCU (add 20% buffer for overage and monitoring).
- Detection tuning: +2-4 weeks post-launch.

## 5. Realistic MVP prioritization (for ScreechVR on Quest + Photon + PlayFab)

### Essential (v1, must have)
1. Backend auth: email+password, TOTP MFA for owner, JWT access + refresh, RBAC (Owner/Admin/Moderator/Viewer).
2. Game registration + API key issuance (Dev/Backend/Game Server/Photon).
3. Validation endpoint: POST /api/v1/validation/validate-user (session nonce, OVR ID) -> actionCode/reason/errorCode/usingVpn.
4. Session management: create, heartbeat, duplicate detection, expiry (45s nonce window).
5. Ban/unban API + ban list export (for your backend to enforce).
6. Audit log (append-only, actor/reason/timestamp).
7. Basic dashboard: login, overview (live CCU, active bans, recent flags), player search, ban management.
8. Webhooks (Discord) for bans/flags.
9. Build IP whitelist + build verification (basic).
10. Rate limiting + schema validation on all endpoints.

### Important but deferrable (v1.5)
- Alt-account detection (hardware + IP).
- Detection rules engine with confidence scoring.
- Flag review queue.
- Evidence storage (telemetry windows).
- CCU history charts + peak tracking.
- Meta attestation integration (if available).
- Admin MFA enforcement.

### Advanced (v2+)
- Behavioral anomaly detection (ML).
- Cross-game ban sharing (VRIC-style).
- Meta device ban sync.
- Dedicated authoritative server.
- Mobile/PC support.
- Advanced analytics (false-positive tracking, detection trends).

### NOT recommended for v1
- Kernel-level or rootkit-style anti-tamper (platform-inappropriate, likely ToS violation).
- Client-side code obfuscation as a security boundary (cosmetic only).
- Microservices (unnecessary complexity for solo dev).
- Real-time ML detection (needs data you don't have yet).

## 6. Verification checklist

### Unresolved questions
1. Is Meta Device Application Integrity API available to all Quest developers, or gated behind approval? (Docs inaccessible.)
2. Does Meta Device Ban sync require a partnership, or is it self-service via the Device Ban permission?
3. What is the Meta attestation token format and verification endpoint? (Unknown.)
4. Will Voideration serve only ScreechVR or be multi-game? (Affects data model.)
5. PlayFab user IDs vs Meta OVR IDs as primary identity? (PlayFab already in stack.)
6. Evidence storage needs: telemetry only vs screenshots/video?
7. Data retention policy and GDPR-style deletion handling?
8. Budget ceiling and solo-dev time availability?
9. Will you need a public ban appeal flow, or handle via Discord/support tickets?

### Evidence needed before implementation
- Meta developer portal access to confirm attestation API availability and permissions.
- Photon dashboard configuration for Custom Authentication (verify the REST endpoint contract).
- PlayFab Title Data structure for MOTD (already partially done).
- Load test results for validation endpoint (k6, target p99 < 200ms).
- DB query plans for session/heartbeat writes under concurrent load.
- Redis memory profiling for session state at 1k CCU.
- Detection false-positive baseline (needs real session data post-launch).

### Risks
- Meta attestation may be unavailable or gated, weakening Layer One. Mitigation: server-authoritative validation as the primary gate.
- Master client in Photon can be exploited; never use it for security decisions. Mitigation: backend validation + server-side enforcement.
- Detection false positives could ban legitimate players. Mitigation: human review queue, confidence thresholds, kill switches.
- Solo dev burnout / scope creep. Mitigation: strict MVP scope, defer advanced features.
- Cost overruns from DB/Redis at scale. Mitigation: start on free tiers, monitor, scale on demand.

### Recommended tests
- Pen test: attempt unauthenticated admin access, BOLA (access other players' data), mass assignment on ban endpoints, rate limit bypass.
- Load test: k6 against /validate-user at 100/500/1000 concurrent, measure p50/p95/p99.
- Detection accuracy: synthetic cheat replays in staging, measure false positive rate on clean sessions.
- Backup restore drill: restore DB from backup, verify integrity.
- Failover test: kill DB/Redis, verify graceful degradation (allow-through for non-banned users, bans still enforced, per Tomahawk's documented behavior).

---

STOP: critical review complete. No implementation performed. Awaiting your explicit approval before any code is written.

QUEST_MODIFICATION_THREAT_CATALOG.md
# ScreechVR: Quest Modification Threat Catalog (Defensive)

Research-only. No implementation. Date: 2026-10-28.

## Scope
This catalog covers known and reasonably foreseeable methods for modifying, instrumenting, repackaging, manipulating, or interfering with Meta Quest applications, Android environments, Unity games, Photon networking, PlayFab, and Cloudflare Workers. Focus: ScreechVR's actual stack (Unity 2021.3 LTS, Photon PUN2+Voice, PlayFab, Meta/Oculus SDK, Cloudflare worker).

## 1. Device and OS Compromise

### 1.1 Rooted devices / elevated privileges
- **Capability:** Modified Android with root access. Enables file system access, process inspection, memory modification, framework hooking.
- **Applicability:** Quest (Android-based). Rooting requires exploiting device-specific vulnerabilities or unlocked bootloader.
- **Historical context:** Quest devices have had jailbreak/root exploits (e.g., "Singularity" was a Quest 2 exploit chain, now patched). Fugu was an iOS jailbreak, NOT Quest-relevant. These are historical; current firmware likely patched.
- **Evidence quality:** Historical reports exist. Current applicability UNVERIFIED for latest Quest firmware.
- **Meta attestation:** `ovr_DeviceApplicationIntegrity_GetIntegrityToken` may report device integrity. UNVERIFIED (docs gated). ERR-5004 (rooted) and ERR-5005 (ADB) suggest Tomahawk detects these via Meta's API.
- **Defense:** Meta attestation (if available) + server-side validation. Cannot prevent root; can detect and refuse service.
- **Confidence:** Historical (root exploits existed), Unverified (current firmware).

### 1.2 Modified OS images / unofficial firmware
- **Capability:** Custom ROMs, modified system partitions.
- **Applicability:** Quest (requires bootloader unlock, which Meta allows on some dev units).
- **Detection:** Meta attestation device_integrity_state (Advanced/Basic/NotTrusted). UNVERIFIED exact meaning.
- **Defense:** Attestation check + server-side version enforcement.
- **Confidence:** Unverified (docs inaccessible).

### 1.3 Debugging configurations (ADB, wireless debugging)
- **Capability:** ADB enabled allows file access, logcat, process inspection, sideloading.
- **Applicability:** Quest (developer mode enables ADB).
- **Tomahawk ERR-5005:** "Wireless debugging (ADB) is enabled" - detected.
- **Defense:** Flag ADB-enabled devices (low severity, many legitimate devs use ADB). Do not auto-ban.
- **Confidence:** Confirmed (error code documented).

### 1.4 Concealed compromised state
- **Capability:** Hiding root from attestation (Magisk Hide, etc.).
- **Applicability:** Historical on Android; Meta attestation may or may not detect.
- **Defense:** Layered detection (attestation + behavioral + server-side). No single signal is sufficient.
- **Confidence:** Plausible.

## 2. Application Package and Distribution Modification

### 2.1 Repackaged APKs
- **Capability:** Extract APK, modify resources/code, re-sign with different key.
- **Applicability:** Quest (sideloading). Meta Store builds are signed by Meta; sideloaded builds can be re-signed.
- **Detection:** Package signature verification (Meta platform), version enforcement (title data), build IP whitelist.
- **Defense:** Meta entitlement check (AppEntitlementCheck.cs exists but only logs). Server-side version enforcement via Photon custom auth. Build IP whitelist for uploads.
- **Confidence:** Confirmed (Android signing, Meta entitlement).

### 2.2 Modified application resources (assets, prefabs, materials)
- **Capability:** UABEA can edit Unity assets (textures, materials, prefabs, scenes).
- **Applicability:** Quest (APK extraction + asset modification).
- **Effect on ScreechVR:** Visual mods (cosmetics), hitbox changes, movement parameter changes in assets.
- **Defense:** Asset integrity checks (hash manifests) - v2. Version enforcement (title data). Server-side validation of outcomes.
- **Confidence:** Confirmed (UABEA is a real tool; Unity assets are modifiable).

### 2.3 Modified managed assemblies (Mono builds)
- **Capability:** dnSpy/ILSpy decompile and modify C# assemblies. Patch methods, bypass checks.
- **Applicability:** Only if ScreechVR uses Mono backend. ScreechVR uses IL2CPP for Quest (verified: build environments doc says IL2CPP). So managed assemblies are NOT present in Quest builds.
- **Defense:** IL2CPP (already used). Symbol stripping. Server-side enforcement.
- **Confidence:** Confirmed (IL2CPP verified in technical map).

### 2.4 IL2CPP binary modification
- **Capability:** Native binary patching (ARM64). Harder than Mono but possible with disassemblers.
- **Applicability:** Quest (IL2CPP builds are native .so files).
- **Defense:** Build integrity checks, version enforcement, server-side validation. Obfuscation helps but is bypassable.
- **Confidence:** Confirmed (IL2CPP is native code, patchable in principle).

### 2.5 Outdated/vulnerable builds
- **Capability:** Downgrade to older build with known vulnerabilities.
- **Applicability:** Quest (if older APKs available).
- **Defense:** Server-side version enforcement (title data "VERISION_CODE" check, already exists). Block old versions server-side.
- **Confidence:** Confirmed.

### 2.6 Unauthorized release channels
- **Capability:** Distribute modified APKs via sideloading, third-party stores.
- **Defense:** Meta entitlement check (AppEntitlementCheck, currently log-only - should quit on failure). Server-side version check.
- **Confidence:** Confirmed.

## 3. Unity-Specific Modification

### 3.1 Modified gameplay methods
- **Capability:** Patch methods to disable checks, modify values, bypass restrictions.
- **Applicability:** IL2CPP (native patching) or Mono (assembly patching).
- **ScreechVR specifics:** Currency (_currency), moderator status (AccountPref), ban checks (KickIfBanned), movement (Player.cs), IAP (SpokesSigmaIAP).
- **Defense:** Server-side enforcement of all security decisions. Client checks are signals only.
- **Confidence:** Confirmed.

### 3.2 Modified assets/prefabs
- **Capability:** Replace textures, models, materials, prefabs via UABEA.
- **ScreechVR specifics:** Cosmetic prefabs in Cosmetics list, materials, monster models.
- **Defense:** Asset integrity hashes (v2). Server-side inventory validation for cosmetics.
- **Confidence:** Confirmed.

### 3.3 Modified configuration
- **Capability:** Change runtime config (movement speed, jump multiplier, prices).
- **ScreechVR specifics:** Player.cs fields (jumpMultiplier, maxJumpSpeed, etc.), BuyCosmetic.Price.
- **Defense:** Server-side validation of outcomes (currency balance, cosmetic ownership). Client config is untrusted.
- **Confidence:** Confirmed.

### 3.4 Disabled MonoBehaviour checks
- **Capability:** Disable components (AppEntitlementCheck, KickIfBanned) via modified build or runtime.
- **Defense:** Server-side enforcement. Client checks are signals only.
- **Confidence:** Confirmed.

### 3.5 Modified network sync code
- **Capability:** Modify RPC handlers, ownership logic, state sync.
- **ScreechVR specifics:** PhotonVRManager, TagPlayer, WeldGun, BestJumpscare RPCs.
- **Defense:** Server-side validation of all security-sensitive RPCs. Rate limits.
- **Confidence:** Confirmed.

## 4. Runtime Injection and Instrumentation

### 4.1 Frida
- **Capability:** Dynamic instrumentation, method hooking, memory inspection.
- **Applicability:** Android (rooted or via USB debugging). Works on Quest in developer mode.
- **Detection:** Process/library name checks (weak, bypassable, false positives). Behavioral anomalies (stronger).
- **Defense:** Server-side enforcement. Frida detection = low-confidence flag only. Never auto-ban.
- **Confidence:** Confirmed (Frida is a real tool; works on Android).

### 4.2 Native injection
- **Capability:** Inject native libraries into process.
- **Applicability:** Requires root or debugger access on Android.
- **Defense:** Attestation (if available), behavioral detection, server-side validation.
- **Confidence:** Confirmed (concept).

### 4.3 Debugger attachment
- **Capability:** Attach debugger (gdb, lldb) to inspect/modify process.
- **Applicability:** Requires ADB/debugger access.
- **Defense:** Anti-debug checks (weak, bypassable). Server-side validation.
- **Confidence:** Confirmed (concept).

### 4.4 Memory modification
- **Capability:** Modify runtime memory (currency, position, health, flags).
- **Applicability:** Requires root or debugger.
- **Defense:** Server-side validation of all valuable state. Client memory is untrusted.
- **Confidence:** Confirmed.

## 5. Mod Loaders and Mod Menus

### 5.1 Runtime plugin loaders (Unity)
- **Capability:** Load external DLLs/plugins at runtime (e.g., BepInEx, MelonLoader).
- **Applicability:** Mono builds only. IL2CPP builds require different approaches (native injection).
- **ScreechVR:** Uses IL2CPP for Quest -> managed plugin loaders don't work directly. Native injection required.
- **Defense:** IL2CPP (already), server-side validation.
- **Confidence:** Confirmed (BepInEx/MelonLoader are real tools for Mono builds).

### 5.2 Mod menus
- **Capability:** Overlay UI for toggling cheats (speed, fly, teleport, etc.).
- **Applicability:** Requires runtime injection or modified build.
- **ScreechVR:** Would need modified APK or runtime injection.
- **Defense:** Behavioral detection (impossible movement), server-side validation.
- **Confidence:** Confirmed (concept).

### 5.3 Cosmetic modding
- **Capability:** Replace textures, models, materials locally.
- **Applicability:** UABEA on extracted APK.
- **ScreechVR:** Could replace monster models, cosmetic prefabs.
- **Defense:** Asset integrity (v2). Only flag if affects competitive integrity.
- **Confidence:** Confirmed.

## 6. Memory and Runtime State Manipulation

### 6.1 Currency manipulation
- **Capability:** Modify _currency locally, call AddCurrency with arbitrary amount.
- **ScreechVR specifics:** Oculus_Login._currency, AddCurrency(amount), BuyCosmetic checks local balance.
- **Defense:** Move currency grants to server-side (CloudScript/worker). Server-side price validation.
- **Confidence:** Confirmed (code verified).

### 6.2 Moderator spoof
- **Capability:** Set AccountPref = Moderator client-side. Open mod menu (Mod_Toggle if DefaultQueue == "MODDED").
- **ScreechVR specifics:** Oculus_Login.AccountPref, Check_Mod 5s timeout, UserData "Moderator" key.
- **Defense:** Server-side moderator verification. Never trust client-side AccountPref.
- **Confidence:** Confirmed (code verified).

### 6.3 Ban status spoof
- **Capability:** Skip KickIfBanned or GetAccountInfo. Ignore Application.Quit.
- **Defense:** Server-side ban enforcement via Photon custom auth (on connect). Keep KickIfBanned as supplementary.
- **Confidence:** Confirmed.

### 6.4 Movement manipulation
- **Capability:** Modify Player fields (jumpMultiplier, maxJumpSpeed, disableMovement). Teleport via TP_YA.
- **Defense:** Heuristic detection (speed/teleport flags). Server-side validation where possible.
- **Confidence:** Confirmed.

### 6.5 Cosmetic spoof
- **Capability:** Set any cosmetic id in Photon custom properties.
- **Defense:** Backend inventory verification. Flag mismatch.
- **Confidence:** Confirmed (code verified).

### 6.6 Leaderboard faking
- **Capability:** Submit fake scores via GDH leaderboard client.
- **Defense:** Server-side score validation or remove from leaderboard.
- **Confidence:** Assumed (GDH path not fully read).

## 7. Android Debugging and Platform Interfaces

### 7.1 Debug builds
- **Capability:** Debug builds have additional logging, weaker security.
- **ScreechVR:** Verify no debug builds ship. Check build configuration.
- **Defense:** Separate QA/Live environments (Tomahawk pattern). Only ship release builds.
- **Confidence:** Confirmed (best practice).

### 7.2 Exposed Android components
- **Capability:** Exported activities/services/receivers can be triggered by other apps.
- **ScreechVR:** Verify AndroidManifest.xml for exported components.
- **Defense:** Ensure no unnecessary exported components. Unity default is usually safe.
- **Confidence:** Unverified (manifest not inspected).

### 7.3 Insecure local storage
- **Capability:** SharedPreferences, local files accessible on rooted device.
- **ScreechVR:** PlayerPrefs used for username, "SavedPref" (TOS agreement). No sensitive data in PlayerPrefs (assumed).
- **Defense:** Don't store secrets in PlayerPrefs. Use PlayFab server-side storage for sensitive data.
- **Confidence:** Confirmed (PlayerPrefs usage verified).

### 7.4 Deep links and intents
- **Capability:** Malicious apps trigger deep links to exploit app logic.
- **ScreechVR:** Verify if deep links are used. Likely not (no intent handling found).
- **Defense:** Validate all intent parameters. Disable if not needed.
- **Confidence:** Unverified (no deep link code found, but manifest not inspected).

## 8. Network and Protocol Manipulation

### 8.1 Client-supplied identity substitution
- **Capability:** Claim another player's identity.
- **ScreechVR:** PlayFab LoginWithCustomID using OculusID. Oculus ID is hardware-bound (hard to spoof). PlayFab session ticket required for worker calls.
- **Defense:** Oculus auth + PlayFab session validation. Photon custom auth validates session.
- **Confidence:** Confirmed (auth flow verified).

### 8.2 Forged API requests
- **Capability:** Direct calls to worker endpoints (/redeem, /updateplayers, /motd).
- **ScreechVR:** /redeem requires PlayFab session ticket. /updateplayers and /motd are public (no auth).
- **Defense:** Rate limit public endpoints. Add auth to /updateplayers if needed. Validate all inputs.
- **Confidence:** Confirmed.

### 8.3 Replay attacks
- **Capability:** Replay a valid request (e.g., /redeem with same code).
- **ScreechVR:** /redeem likely validates code server-side (worker). PlayFab session ticket expires.
- **Defense:** Idempotency keys, server-side code validation, nonce freshness.
- **Confidence:** Assumed (worker code not inspected).

### 8.4 RPC abuse
- **Capability:** Forged RPCs, invalid params, floods.
- **ScreechVR:** Many RPCs (TagPlayer, WeldGun, BestJumpscare, etc.). ThusterController floods.
- **Defense:** Rate limits, param validation, ownership checks.
- **Confidence:** Confirmed.

### 8.5 Session reuse
- **Capability:** Reuse a session token across multiple clients.
- **ScreechVR:** PlayFab session ticket, Photon custom auth token. Duplicate session detection needed.
- **Defense:** Heartbeat-based duplicate detection. Ban on duplicate.
- **Confidence:** Assumed.

### 8.6 Forged client-side ban status
- **Capability:** Skip KickIfBanned, ignore ban screen.
- **Defense:** Server-side ban check on Photon custom auth (on connect). Keep KickIfBanned as supplementary.
- **Confidence:** Confirmed.

## 9. Authentication, Account, and Identity Manipulation

### 9.1 Weak Custom ID identity binding
- **Capability:** Use someone else's Oculus ID.
- **ScreechVR:** Oculus ID is hardware-bound (from Oculus Platform SDK). Hard to spoof on Quest.
- **Defense:** Oculus auth (entitlement check, user ID). AppEntitlementCheck exists but only logs (should quit on failure).
- **Confidence:** Confirmed.

### 9.2 Session token exposure
- **Capability:** Extract PlayFab session ticket from memory/network.
- **ScreechVR:** Session ticket stored in Oculus_Login.PlayFabSessionTicket (public field). Could be extracted by modified client.
- **Defense:** Short session lifetime, server-side validation, token binding to device.
- **Confidence:** Confirmed (field is public).

### 9.3 Ban evasion
- **Capability:** Create new account, use alt device, use VPN.
- **ScreechVR:** PlayFab Custom ID (Oculus ID). Alt account detection via hardware/IP overlap.
- **Defense:** Alt account detection (hardware + IP), VPN flagging, Meta device ban (if available).
- **Confidence:** Confirmed (pattern from Tomahawk).

### 9.4 Unauthorized role claims
- **Capability:** Set AccountPref = Moderator client-side.
- **Defense:** Server-side moderator verification. Remove client-side AccountPref trust.
- **Confidence:** Confirmed.

### 9.5 Stale sessions
- **Capability:** Reuse expired session token.
- **Defense:** Session expiry (45s nonce), heartbeat, server-side session validation.
- **Confidence:** Assumed.

## 10. Backend and Cloud Attacks

### 10.1 Broken authorization
- **Capability:** Access admin endpoints without proper auth.
- **ScreechVR:** Worker endpoints (/updateplayers, /motd) are public. /redeem requires session ticket. No admin endpoints in worker (admin via Discord bot).
- **Defense:** Add auth to sensitive endpoints. Rate limit public endpoints.
- **Confidence:** Confirmed.

### 10.2 IDOR
- **Capability:** Access other users' data by manipulating IDs.
- **ScreechVR:** PlayFab IDs are server-managed. Worker uses session ticket for /redeem.
- **Defense:** Server-side ownership checks. Validate session ticket matches requested resource.
- **Confidence:** Assumed.

### 10.3 SQL injection
- **Capability:** Inject SQL via user input.
- **ScreechVR:** No SQL database (PlayFab + Cloudflare D1/KV). Worker uses KV/D1.
- **Defense:** Parameterized queries (D1), input validation.
- **Confidence:** Assumed (D1 not yet in use).

### 10.4 Rate limit bypass
- **Capability:** Bypass rate limits via IP rotation, distributed requests.
- **ScreechVR:** Worker /redeem has weak rate limiter (per deep audit). /updateplayers and /motd may have no rate limit.
- **Defense:** Cloudflare rate limiting (built-in), per-user rate limits, IP-based limits.
- **Confidence:** Confirmed (deep audit found weak /redeem limiter).

### 10.5 Secret exposure
- **Capability:** Extract secrets from client binary, repo, or worker.
- **ScreechVR:** No secrets in client binary (BaseUrl is public). Bot token in discord-bot/bot-token.txt (not in repo? verify). Worker secrets in Cloudflare env (encrypted).
- **Defense:** Secret scanning before release. Rotate on suspected compromise.
- **Confidence:** Confirmed (no hardcoded secrets in client).

### 10.6 DDoS
- **Capability:** Overwhelm backend services.
- **ScreechVR:** Worker on Cloudflare (DDoS protection built-in). PlayFab has its own limits.
- **Defense:** Cloudflare DDoS protection, rate limiting, caching.
- **Confidence:** Confirmed.

## 11. Gameplay Behavior Manipulation

### 11.1 Movement exploits
- **Capability:** Speed, teleport, fly, gravity manipulation.
- **ScreechVR:** Player.cs locomotion (sphere-casts, gravity, jump). No server validation.
- **Defense:** Heuristic detection (speed/teleport flags). Server-side validation requires dedicated server.
- **Confidence:** Confirmed.

### 11.2 Cosmetic spoof
- **Capability:** Equip unowned cosmetics via Photon props.
- **Defense:** Backend inventory verification. Flag mismatch.
- **Confidence:** Confirmed.

### 11.3 Currency manipulation
- **Capability:** Grant self gold, modify balance.
- **Defense:** Move grants to server-side. Server-side price validation.
- **Confidence:** Confirmed.

### 11.4 Tag/Infection manipulation
- **Capability:** Self-tag, infinite tags, RPC spoofing.
- **Defense:** Validate tagger state server-side. Rate limit tag RPCs.
- **Confidence:** Confirmed (code verified).

### 11.5 Leaderboard faking
- **Capability:** Submit fake scores.
- **Defense:** Server-side score validation or remove from leaderboard.
- **Confidence:** Assumed (GDH path not fully read).

## 12. Prevention-vs-Detection Matrix

| Attack | Prevent? | Detect reliably? | Detect heuristically? | Mitigate after? | Backend reject? | Current arch support? | Needs new infra? | Residual if client controlled |
|---|---|---|---|---|---|---|---|---|
| Modified APK | Partially (signing) | Partially (version) | No | Yes (ban) | Yes (version check) | Yes | No | Can bypass version check |
| Asset mod (visual) | No | No | No | N/A | No | N/A | N/A | N/A (harmless) |
| Asset mod (gameplay) | No | Partially (hash) | No | Yes (ban) | Yes (outcome validation) | Partial | No | Can fake outcomes |
| Memory mod (currency) | No | No | Partially (anomaly) | Yes (revert) | Yes (server balance) | Yes (PlayFab) | No | Can desync display |
| Memory mod (position) | No | No | Partially (speed/teleport flags) | Yes (flag+review) | No (no dedicated server) | Partial | Yes (dedicated server) | Can move freely |
| Frida/injection | No | Heuristically | Yes (low conf) | Yes (flag) | No | Yes (flag) | No | Can bypass detection |
| RPC flood | Partially (rate limit) | Yes (rate) | Yes | Yes (kick) | Yes (rate limit) | Yes | No | Can still flood within limits |
| Ban evasion | Partially (Photon auth) | Partially (alt detection) | Yes (IP/hardware) | Yes (ban) | Yes (ban check on connect) | Yes | No | Can create new account |
| Moderator spoof | Yes (server-side) | Yes (if backend verifies) | No | Yes (revoke) | Yes | Yes (after fix) | No | Cannot if server-enforced |
| Master client abuse | Partially (minimize authority) | Partially (logs) | No | Yes (flag) | Partially | Partial | Yes (dedicated server) | Can manipulate room state |
| Leaderboard faking | No | No | Partially (anomaly) | Yes (remove score) | Yes (server validation) | Partial | No | Can submit fake scores |

## 13. Meta Attestation Compatibility

### What is known (from Tomahawk research)
- Native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` present in libTomahawkCore.so.
- Tomahawk requires Meta Data Use Permissions: User ID, User Profile, Device Ban.
- ERR-5xxx codes suggest attestation reports: modified binary, invalid signature, rooted, ADB, cheat software, attestation failures.
- `device_integrity_state` values: Advanced, Basic, NotTrusted (UNVERIFIED exact meaning).
- `security_update_pending_days` (UNVERIFIED availability/meaning).

### What is UNVERIFIED
- API availability to all Quest developers vs gated.
- Token verification endpoint and flow.
- Eligibility requirements.
- Platform restrictions (Quest 2/3/Pro differences).
- Whether attestation is available for sideloaded builds.
- Exact meaning of device_integrity_state values.

### Recommendation
- Design attestation as optional module.
- If available: use as Layer One signal (not gate).
- Primary security: server-side validation (Photon custom auth + PlayFab + worker).
- Do not depend on attestation for v1.

## 14. Project-Specific Coverage Map

| Threat | Relevant files | Current trust boundary | Current defense | Defense real? | Missing protection | Smallest mitigation | Strongest mitigation | Test |
|---|---|---|---|---|---|---|---|---|
| Currency manipulation | Oculus_Login.cs:269-344, BuyCosmetic.cs | Client-trusted | Local balance check | No (PlayFab validates session not amount) | Server-side price validation | Move AddCurrency to worker | CloudScript/Functions | Grant gold, verify server rejects |
| Moderator spoof | Oculus_Login.cs:392-428, Check_Mod.cs | Client-trusted | UserData "Moderator" key | Unknown (verify writability) | Server-side moderator claim | Verify PlayFab UserData permissions | Server-side claim | Set UserData "Moderator"="TRUE" client-side, verify |
| Ban evasion | KickIfBanned.cs, Kick_Player.cs | Client-side | Client poll every 5s | No (ignorable) | Server-side ban on connect | Photon custom auth ban check | + real-time kick | Modified client ignores ban, verify can't connect |
| Movement exploit | Player.cs | Client-authoritative | None | No | Heuristic detection | Speed/teleport flags | Dedicated server | High-speed movement, verify flag |
| Cosmetic spoof | GetCosmetics.cs, SecondaryCosmetics.cs | Client-driven | None | No | Backend inventory check | Flag mismatch | Server-side equip validation | Equip unowned cosmetic, verify flag |
| Leaderboard faking | GDH leaderboard | Client-submitted | None | Unknown | Server-side score validation | Flag anomaly | Remove from leaderboard | Submit impossible score, verify flag |
| IAP bypass | SpokesSigmaIAP.cs, BuyCosmetic.cs | Client-trusted price check | PlayFab PurchaseItem (server validates price) | Partial (client gates on local balance) | Server-side balance check | Verify PurchaseItem validates | + receipt validation | Buy with insufficient balance, verify rejection |
| Tag/Infection spoof | TagPlayer.cs, TagManager.cs | Client RPCs | None | No | Validate tagger state server-side | Rate limit + ownership check | Server-side tag validation | Non-tagger sends tag RPC, verify flag |
| Master client abuse | PhotonVRManager.cs (AutomaticallySyncScene) | Master is player | None | No | Minimize master authority | Move room state to backend | Dedicated server | Master forces scene load, verify clients resist |
| RPC flood | ThusterController, Flash_Light | Client-driven | None | No | Per-player rate limits | Rate limit + flag | + kick on exceed | Spam RPCs, verify rate limit |
| Null crash | PlayerSpawner, Hand_Physic, Monster_Track | Unprotected | None | No | Guard null refs | Add null checks | + server-side crash detection | Trigger NRE, verify no crash |
| Version spoof | Oculus_Login.cs:474-485 | Client-side title data check | Title data check | Partial (client can ignore) | Server-side version in custom auth | Add version to auth response | + block old versions | Old client connects, verify rejected |
| Duplicate session | None | Not tracked | None | No | Heartbeat-based detection | Track session IDs | + kick older | Two clients same account, verify flag |

## Named Tool Research

### Singularity
- **Identity:** Quest 2 exploit chain (historical). Now patched by Meta.
- **Relevance:** Historical. Demonstrates that Quest devices can be compromised.
- **Current applicability:** UNVERIFIED for current firmware. Likely patched.
- **Defense:** Meta attestation (if available) + server-side validation. Cannot prevent all root.
- **Confidence:** Historical.

### Fugu
- **Identity:** iOS jailbreak. NOT relevant to Quest/Android.
- **Relevance:** None. Included in prompt but not applicable.
- **Confidence:** Confirmed (iOS only).

### Wizard (and similarly named tools)
- **Identity:** Could not verify a specific "Wizard" tool for Quest. Multiple unrelated tools share this name.
- **Relevance:** Ambiguous. Marked as unverified.
- **Confidence:** Unverified.

### Frida
- **Identity:** Dynamic instrumentation toolkit (frida.re). Open source, widely used for security research.
- **Relevance:** High. Can hook methods, modify returns, inspect memory on Android (rooted or via ADB).
- **Detection:** Process/library name checks (weak). Behavioral anomalies (stronger).
- **Defense:** Server-side enforcement. Frida detection = low-confidence flag only.
- **Confidence:** Confirmed.

### UABEA
- **Identity:** Unity asset bundle editor (github.com/nesrak1/UABEA). Open source.
- **Relevance:** High. Can modify Unity assets (textures, materials, prefabs, scenes).
- **Defense:** Asset integrity hashes (v2). Server-side validation of outcomes.
- **Confidence:** Confirmed.

### dnSpy / dnSpyEx
- **Identity:** .NET decompiler/debugger. dnSpyEx is the maintained fork.
- **Relevance:** Medium (only for Mono builds). ScreechVR uses IL2CPP for Quest -> managed assemblies not present.
- **Defense:** IL2CPP (already used). Symbol stripping.
- **Confidence:** Confirmed.

### IL2CPPDumper
- **Identity:** Extracts IL2CPP metadata and generates dummy DLLs for reverse engineering.
- **Relevance:** Medium. Can be used to analyze IL2CPP builds.
- **Defense:** Symbol stripping, code obfuscation (cosmetic). Server-side validation.
- **Confidence:** Confirmed.

## Meta Attestation Compatibility

### What is known
- Native symbol `ovr_DeviceApplicationIntegrity_GetIntegrityToken` in libTomahawkCore.so.
- Tomahawk requires Meta Data Use Permissions: User ID, User Profile, Device Ban.
- ERR-5xxx codes: modified binary (5001), invalid signature (5002), missing Meta update (5003), rooted (5004), ADB (5005), cheat software (5006), attestation failures (5101-5108).

### What is UNVERIFIED
- API availability to all Quest developers vs gated.
- Token verification endpoint and flow.
- Eligibility requirements.
- Platform restrictions (Quest 2/3/Pro differences).
- Whether available for sideloaded builds.
- Exact meaning of device_integrity_state (Advanced/Basic/NotTrusted).
- security_update_pending_days availability/meaning.

### Recommendation
- Design attestation as optional module.
- If available: Layer One signal (not gate).
- Primary security: server-side validation (Photon custom auth + PlayFab + worker).
- Do not depend on attestation for v1.

## Research completeness
- Searched: official Meta/Unity/Photon/PlayFab docs (where accessible), OWASP MASVS/MASTG, Tomahawk research (web + local + binary), ScreechVR project files.
- Limitations: Meta attestation docs gated (404), web search tool down, no PlayFab/Photon dashboard access, no hands-on testing.
- All categories from the mission prompt addressed. Additional categories added: APK repackaging, asset modification, IL2CPP binary patching, runtime instrumentation, mod loaders, memory manipulation, Android debugging, network manipulation, auth manipulation, backend attacks, gameplay manipulation, prevention-vs-detection matrix, Meta attestation compatibility, project-specific coverage map.
