1. Executive Summary
POPS Notebook is a mobile-first operational reference tool deployed to UK Public Order and Public Safety officers. Unlike traditional police information systems that rely on IP allow-listing, VPN tunnels, or MDM certificate pinning, this platform compensates for the absence of those controls by implementing a Zero-Knowledge encryption architecture in which the server is mathematically incapable of decrypting stored officer data.
All sensitive payloads — officer profiles, command broadcasts, and operational planning data — are encrypted on the officer's device before transmission. The server stores only ciphertext. Even in a full database compromise, the attacker obtains only opaque encrypted blobs with no corresponding decryption keys.
2. Zero-Knowledge Architecture Overview
The architecture rests on a single principle: the server never possesses a decryption key. Keys are derived on the client device from values that are either (a) never transmitted to the server in plaintext, or (b) generated ephemerally and confined to browser session storage.
Three distinct encryption domains operate independently:
- Officer Profiles — encrypted with a force-derived key, synced to cloud as ciphertext only.
- Command Broadcasts — encrypted with the same force-derived key, retrievable by all same-force officers.
- Operational Planning Data — encrypted with an ephemeral per-session key, never leaves the device.
3. Cryptographic Primitives
3.1 SHA-256 with Per-Force Salt (ForceSalt)
When a ForceLicense is created, the backend generates a 32-byte cryptographically random salt (ForceSalt) using the Web Crypto API's crypto.getRandomValues(). This salt is appended to the officer's force email domain before SHA-256 hashing.
The resulting hash (HomeForceHash) is stored on the User entity. The plain-text domain is never persisted — it exists only in RAM during the verification flow and is discarded immediately after hashing.
HomeForceHash = SHA-256(forceDomain + ForceSalt)
// Example:
// forceDomain = "lancashire.police.uk"
// ForceSalt = "a1b2c3d4... (64 hex chars)"
// HomeForceHash = SHA-256("lancashire.police.uka1b2c3d4...")
// Result: "7f3a9b2c..." (irreversible)Cross-constabulary rainbow table prevention: Because UK police email domains are public knowledge (e.g. met.police.uk, lancashire.police.uk), an attacker who breached the database could pre-compute SHA-256 hashes for all 43+ forces and match them against stored HomeForceHashvalues. The per-force ForceSalt defeats this: each force's hash uses a unique 32-byte salt, making pre-computed rainbow tables useless — the attacker would need to recompute a table for each individual force's salt.
3.2 PBKDF2 Key Derivation (100,000 iterations)
The AES encryption key is not stored anywhere — it is derived on-demand using PBKDF2 (Password-Based Key Derivation Function 2) with the following parameters:
KeyDerivation: Algorithm: PBKDF2 Hash: SHA-256 Iterations: 100,000 Salt: ForceSalt (32 bytes, unique per force) Input: HomeForceHash (SHA-256 of force domain + ForceSalt) Output: 256-bit AES-GCM key
The choice of 100,000 PBKDF2 iterations introduces a deliberate computational cost: each key derivation attempt takes ~50-100ms on a modern device. For a legitimate officer, this is imperceptible (the key is cached for the session). For an attacker brute-forcing keys from a stolen database, this makes mass key recovery computationally infeasible — each candidate key requires 100,000 SHA-256 rounds.
The same ForceSalt is used both for the SHA-256 hash and as the PBKDF2 salt. This is intentional: it ensures that the PBKDF2 salt is different for every force, so even if an attacker knows the HomeForceHash value, they still need the correct force-specific salt to derive the AES key.
3.3 AES-GCM-256 Authenticated Encryption
All encryption uses AES in GCM (Galois/Counter Mode) with 256-bit keys. GCM is an authenticated encryption scheme, meaning it provides both:
- Confidentiality — the ciphertext cannot be read without the key.
- Integrity / Authenticity — the GCM authentication tag detects any tampering with the ciphertext. A modified blob will fail decryption.
Each encryption operation generates a fresh 12-byte random IV (Initialisation Vector) using crypto.getRandomValues(). The IV is prepended to the ciphertext and base64-encoded as a single blob:
Blob structure (base64): [ IV (12 bytes) | Ciphertext | GCM Auth Tag (16 bytes) ] encryptMessage(homeForceHash, plaintext, forceSalt): key = PBKDF2(homeForceHash, forceSalt, 100000) → AES-GCM-256 iv = crypto.getRandomValues(12 bytes) ct = AES-GCM.encrypt(key, iv, plaintext) blob = base64(iv ‖ ct) return blob
The Web Crypto API (crypto.subtle) performs all cryptographic operations natively in the browser's C++ layer, outside the JavaScript sandbox. This means the raw key material is never accessible to JavaScript code — the CryptoKey object is non-extractable (extractable: false).
4. Officer Profile Encryption
When an officer saves their local profile (name, collar number, mobile, rank, specialisms), the payload is JSON-serialised and encrypted client-side using the force-derived AES-GCM key before being upserted to theEncryptedOfficerProfile entity.
The server receives and stores only the EncryptedBlob(base64 IV + ciphertext). The entity is partitioned by TargetForceHashwith database-level RLS ensuring that only officers whoseHomeForceHash matches can even retrieve the record — and even then, they can only decrypt it if their device derives the same PBKDF2 key.
// Client-side flow (encryptedProfileSync.js):
const payload = JSON.stringify({ officerName, collarNumber, ... });
const blob = await encryptMessage(HomeForceHash, payload, ForceSalt);
// → Server stores: { TargetForceHash, OwnerUserId, EncryptedBlob: blob }
// Server CANNOT decrypt — it has no ForceSalt (only the hash), no HomeForceHash
// plaintext, and no derived AES key.5. Command Broadcast Encryption
Force admins and broadcast operators compose messages that are encrypted on their device with the force-derived key before transmission. TheForceBroadcast entity stores only:
TargetForceHash— determines which officers can retrieve the blob.EncryptedBlob— the AES-GCM ciphertext.SenderRole/SenderRank— server-verified identity (never client-supplied).CreatedAt— for 24-hour TTL enforcement.
When an officer retrieves broadcasts, the server returns only the encrypted blobs for their force hash. The officer's device derives the same PBKDF2 key (using theirHomeForceHash and the force'sForceSalt) and decrypts locally. Broadcasts older than 24 hours are automatically purged server-side on each list request.
6. Operational Data — sessionStorage Key Model
The Ops Planning module uses a separate encryption domain with a key that never leaves the device. A 256-bit AES-GCM key is generated once per browser session and stored in sessionStorage(not localStorage).
This creates a two-domain split on the device:
- localStorage contains only ciphertext (operational data blobs). A malware scraper reading localStorage sees only encrypted blobs.
- sessionStorage holds the decryption key. It survives page refreshes within the same tab but is automatically wiped when the tab or browser is closed.
To decrypt operational data, an attacker must compromise both storage domains — localStorage for the ciphertext and sessionStorage for the key. This raises the bar significantly over storing plaintext in localStorage, which is the common pattern.
On account suspension, the application'spurgeAllLocalData() function wipes all pops_-prefixed keys fromboth localStorage and sessionStorage, destroying both the ciphertext and the key simultaneously.
7. Cross-Force Isolation
Cross-constabulary data leakage is prevented at three layers:
- Database layer (RLS): The
ForceLicenseentity enforces Row-Level Security matchingdata.ForceHashagainst the user'sHomeForceHash. A force admin can only read/update their own force's license — the database query itself excludes all other forces' records. - Encryption layer: Each force's broadcasts and profiles are encrypted with a force-specific key. Even if a query returned cross-force data, decryption would fail because the officer's device derives a key for a different salt.
- Backend function layer: Server-side functions perform salted-hash comparison before returning or modifying data, providing a third independent check.
8. Complementary Tactical Edge Architecture
POPS Notebook is designed as a Zero-Trust Tactical Edge Module that extends your existing Microsoft 365, MDM, and enterprise IT estate into connectivity-denied operational environments. Rather than replacing these controls, the platform complements them — maintaining security posture independently of network-level infrastructure that cannot reach officers in the field.
The platform achieves this through the following complementary controls:
- Work email OTP verification: Officers must verify a legitimate
.police.ukemail domain against a whitelist of all 43+ UK territorial forces, with strict single-@parsing to prevent domain spoofing. - Per-force license quotas: Each force has a finite license pool. Seats are consumed server-side on successful OTP verification and the cap is enforced — an officer verifying against a full pool is refused, and seats are released on suspension or account deletion.
- Backend kill-switch: The
IsSuspendedflag is checked server-side on every API call. A suspended officer's token is invalidated and all local data is purged, regardless of device state. - Zero-knowledge encryption: Even if an unauthorised device gains network access, the server returns only ciphertext. Without the correct PBKDF2-derived key (which requires the officer's HomeForceHash and the force's ForceSalt), the data is unintelligible.
- 6-month re-verification TTL: Officers must re-verify their work email every 6 months, ensuring stale access is pruned.
- Serverless CSV audit exports: All administrative actions, suspended access attempts, and Secure Stand-Down initiations and data retrievals are logged to the
ForceAdminAudittable with per-force hash isolation. Force admins can export a comprehensive 12-month CSV audit report directly from the interface — no database access or IT ticket required.
9. Key Management & Session Lifecycle
Force-derived keys (for profiles and broadcasts) are derived on-demand from HomeForceHash +ForceSalt via PBKDF2. The derivedCryptoKey is held in JavaScript memory for the session and is non-extractable. It is never written to any persistent store.
Operational data keys are generated per browser session and stored insessionStorage as base64. They are wiped on tab close, on explicit logout, or on suspension detection.
Session termination: The auth context pollsIsSuspended every 5 minutes. On detection, the application immediately purges allpops_-prefixed data from localStorage and sessionStorage, clears the auth token, and hard-redirects to a suspension notice. Backend functions independently enforce the same check, so even a stale token cannot access data after suspension.
10. Communication Blackout Resilience
Public order deployments frequently occur in environments where cellular networks are saturated, deliberately jammed, or physically blocked. A spontaneous disorder incident at a city centre on a Saturday night can overwhelm local cell towers within minutes — leaving officers with no data connectivity whatsoever.
POPS Notebook is architected for this reality. Once the app is loaded, every operational tool functions entirely without network connectivity:
- Legislation & doctrine references — Public Order Act 2023 thresholds, NPCC tactical doctrine, and College of Policing APP are cached locally on first load.
- Deployment rosters & serial boards — Full hierarchical command structures, callsigns, and comms directories populated at briefing via QR scan, then available offline for the entire deployment.
- Tactical sketchpad — Freehand tactical diagrams and crowd movement sketches are saved locally, no upload required.
- NDM & Use of Force loggers — Decision logs and use-of-force records are captured offline and synced when connectivity is restored.
- Command broadcasts — Encrypted force broadcasts are cached on-device; the latest messages remain accessible even when the network drops.
- Decision Loggist module — Full CIAPOAR decision logging operates entirely on-device via IndexedDB, with QR-based transfer to force records systems when the duty ends.
This is a deliberate design choice, not a fallback. Officers operating in Code 1 kit in hostile crowd dynamics cannot afford a loading spinner. The infrastructure supports the full operational workflow — from initial briefing to post-incident debrief — in complete network isolation.
11. Information Assurance Admin Benefits
POPS Notebook is designed to make the Information Assurance team's job easier, not harder. The platform integrates with existing GRC workflows rather than creating additional burden:
- Serverless CSV audit exports: Force admins can export a comprehensive 12-month audit report covering user directory, license status, feature toggles, and admin actions — delivered as a CSV file directly from the ForceAdmin interface, no server access or database queries required.
- Per-force audit isolation: Audit logs are hash-partitioned by force, ensuring that IA teams see only their own force's data — no cross-force data leakage in exports or reports.
- Feature toggle governance: Force admins can enable or disable individual modules (Use of Force logger, NDM logger, sketchpad, ops planning, etc.) without engineering involvement, providing immediate control over the operational surface area.
- Configurable data lifecycle: The local data TTL and suspension polling interval are configurable per force, allowing IA teams to align the platform with their own data handling policies (e.g. 4-hour TTL for OFFICIAL-SENSITIVE deployments).
- Deployment PIN gate (soft control): A per-deployment session PIN deters casual access to a seized device in Faraday bag scenarios — three failed attempts trigger an automatic local data wipe, independent of network connectivity. It is a deterrent layer, not a cryptographic boundary; see Section 12.
12. Deployment PIN Gate — A Soft Control, Not a Cryptographic Boundary
During active deployments, officers may operate in environments where device seizure is a realistic threat. If an officer is detained and their device is placed in a Faraday bag or signal-blocking pouch, the backend suspension kill-switch becomes ineffective — the device cannot reach the server to receive suspension signals, and the configurable polling interval is irrelevant without network connectivity.
The Deployment PIN Gate provides an offline, device-local deterrent layer that does not depend on network reach:
- PIN setup: When a deployment is active, the officer sets a 4-digit session PIN. The PIN is never stored in plaintext — it is salted with a cryptographically random value and hashed using SHA-256. Only the salt and hash are persisted to
localStorage. - Inactivity and background lock: Any backgrounding during an active deployment locks the gate on resume, as does an offline or idle period longer than the per-force timeout (default 3 minutes via
DutyPinTimeoutMinutes). The officer must re-enter their PIN to regain access to the deployment board. - Burn protocol: Three failed PIN attempts trigger an immediate local data wipe —
burnAll()purges allpops_-prefixed data fromlocalStorageandsessionStorage, clears the auth token, and hard-redirects to login. All without any server-side signal. - Offline resilience: The PIN hash, attempt counter, and timeout logic operate entirely on-device. No server call is needed to lock, verify, or burn.
12.1 Honest threat model — what the PIN gate does and does not stop
The PIN gate is an application-state control enforced by JavaScript running inside the WebView. It is designed to defeat the realistic field scenario: a device snatched or seized in disorder and handled by someone with no forensic tooling. It is not a cryptographic boundary and should never be described to Information Assurance teams as one.
- Stops: casual browsing of the deployment board, roster and logs by an opportunist; rapid app-switching to hostile tools while the app is backgrounded; PIN guessing (three attempts, then wipe).
- Does not stop: a determined attacker with physical access and developer tooling. Anyone who can attach a debugger, read the WebView's storage directly, or freeze the JavaScript runtime can bypass the gate, read the PIN hash, and prevent the burn protocol from executing.
- Primary protection is the encryption layer: force broadcasts, officer profiles and stand-down submissions are AES-GCM-256 ciphertext that the server cannot read (Sections 3–5). Ephemeral operational data is deleted on stand-down and auto-wiped within the force's configured TTL. The PIN gate buys time and raises the effort required — it does not replace these controls.
- Device posture matters: the gate assumes an official-issue, MDM-managed device with OS-level screen lock and storage encryption. On such a device the OS lock is the hard boundary; the PIN gate is the in-app second layer beneath it.
This control is complementary to the backend kill-switch: the backend handles networked suspension scenarios (account suspended, force suspended, licence revoked), while the PIN gate handles offline seizure scenarios where the backend is unreachable. Together with zero-knowledge encryption and short data TTLs, they provide layered — not absolute — protection of operational data.