An Ed25519 key per device
Generated by WebCrypto as non-extractable, so the private half never exists in readable memory. Only the public half is registered with the server.
SHA-256 bound to the bytes that were actually uploaded
The server re-hashes the file it received and refuses the upload if it does not match the hash inside the signed manifest. On the iOS guided capture the hash is taken on the camera's original bytes before anything is resized.
Location, accuracy and time inside the signature
Latitude, longitude and GPS accuracy travel in the signed manifest, so the location claim can be weighed rather than assumed. EXIF is read server-side to decimal degrees, WGS84.
A canonical manifest, so verification is deterministic
Keys sorted, no whitespace, RFC 8785 style. A manifest that cannot serialise identically on both sides is refused rather than signed.
8 custody actions recorded
Captured, uploaded, reviewed, annotated, exported, shared, archived, deleted.
12 S500 label fields per photo
Category CAT 1 to 3, class 1 to 4, section reference, room type, moisture source, affected materials, surface orientation, extent, whether equipment is visible, secondary damage indicators, stage and capture angle. Three further fields record provenance rather than taxonomy: who applied the labels, technician notes, and a link to the moisture reading. Flagging a suspected asbestos indicator puts a stop-work banner on the inspection's photo screen — a warning to the crew, not a lock on the software.
An audit trail that records the device, not just the user
Each logged action keeps the actor, the device, the location, the previous value and the new one, with IP address and timestamp. Admin support access is written to its own separate trail.