1. Keeping businesses apart
Several businesses share the platform. The single most important thing it does is make sure none of them can see another's customers, prices or takings.
- Isolation is enforced in the data layer, not by each screen remembering to filter. A query that forgets returns nothing rather than everything.
- Which business a request belongs to is decided from the address it arrived on, and a token issued for one business is refused on another's.
- An automated test walks every endpoint on every build looking for the specific mistake that would leak across businesses. It is a test about a class of bug, not a list of known ones, so a new endpoint is covered the day it is written.
Six endpoints once cached their query at start-up, before any business was known — so they served whichever rows happened to exist at that moment, to everybody. It was found when a stock list looked oddly hard-coded. The fix took minutes; the test that makes it un-repeatable was the actual work.
2. In transit and at rest
| Transport | HTTPS everywhere. There is no plain-text path to the API. |
|---|---|
| Passwords | Stored as salted hashes using Django's password hashing. Nobody at Zuuvy can read yours, including us. |
| One-time codes | Hashed, expire after five minutes, five attempts maximum, and spent the moment they are used. |
| Staff photographs | Attendance images are private and served only through short-lived signed links. Profile pictures are deliberately public-readable so apps can cache them. |
| Database and backups | Encrypted at rest. Backups are encrypted and rotate out after 35 days. |
3. Money and stock cannot move twice
The failure that matters most in this kind of system is not a break-in. It is the same delivery being recorded twice on a bad connection, or two people tapping Settle at once.
- Every stock and money movement is claimed before it is made, with a conditional update. If the claim finds nothing to claim, the work has already been done and the second attempt does nothing.
- Counters are changed by database expressions, never read-then-written, so two simultaneous updates cannot overwrite each other.
- Clients may send a request identifier, and a repeat of the same identifier returns the original result rather than performing the action again.
- Balances are recorded three ways — what the customer owes, what the staff member holds, and an append-only transaction log — and an audit command reconciles all three and reports any drift.
4. Access and accountability
- What a user can see comes from their role. Eight roles exist, from owner to trade customer, and menus and permissions follow the role rather than being switched on by hand.
- Records keep their history. Who changed a price, when a credit limit moved, what a return looked like before it was settled — all still answerable.
- Access to production is limited to people who need it and is logged. There are no shared administrator logins.
- Each Android app is signed with its own key, so a compromise of one is not a compromise of four.
5. Reporting a vulnerability
If you have found a security problem, we want to hear about it before anybody else does.
Write to rishav@zuuvy.in with "SECURITY" in the subject. Tell us what you found, how to reproduce it, and what you think the impact is. We acknowledge within 7 days.
We will not pursue you for testing done in good faith, provided you do not access, modify or destroy data belonging to anyone else, do not degrade the service, and give us a reasonable chance to fix the problem before publishing.
We do not currently pay bounties. We will credit you if you would like us to, and we will tell you when it is fixed.
6. If something goes wrong
No system is perfectly secure. If we discover a breach affecting personal data we will notify affected businesses and users, and the Data Protection Board of India, without undue delay — and we will say what actually happened rather than issuing something shaped like an apology.
What we collect in the first place, and how long it is kept, is set out in the privacy policy.