flyox
Security
What is actually built, in plain terms — and what is not.
This page claims no certification and no guarantee. It describes measures that exist in the software
and are covered by automated tests, so that anyone evaluating Flyox can check the claims rather than
take them on trust.
Keeping one business's data away from another's
- Every request works out which company it is for from the signed-in user's own membership records —
never from an identifier sent by the browser, which could be changed.
- Every record fetched by id is fetched with the company as part of the lookup, so another company's
record is simply not found.
- Removing someone from a company ends their access immediately, including on a session they already
have open.
- This is tested by a suite that plays the attacker: a real, signed-in user of one company calling
every endpoint with another company's identifiers, and checking both that the request is refused and
that no trace of the other company's data appears in the reply.
Signing in
- Passwords are stored only as salted hashes using Django's password hashing — never in a form that
can be read back, including by us.
- Repeated wrong passwords lock an account for 15 minutes; repeated attempts from one source are
capped separately, so one attacker cannot try one password against many accounts.
- The reply to a wrong password and to an unknown email address is identical, so the sign-in page
cannot be used to find out who has an account.
- Signing in issues a fresh session; signing out destroys it on the server, not just in the browser.
- Changing a password signs out every other browser that account was signed in on.
- An invite link can add you to a company; it can never sign you in to an account that already
exists without that account's own password.
- Two-step verification is available on every account, and a company can require it of everyone in
it. With it on, a correct password alone never signs anyone in — it reaches a code prompt and stops.
Codes work once, expire, and are rate-limited; ten single-use recovery codes cover a lost phone.
- Every sign-in attempt, successful or not, is recorded with its time and source address, and those
records are deleted after 90 days.
Roles
Four roles — founder, CFO, bookkeeper, investor — each with a fixed set of permissions enforced on the
server. The page never decides what you may do; it only reflects what the server already enforces.
Nobody can invite someone into a role with more access than their own.
Uploaded files
- Uploaded statements are never written to disk and never stored: the file is read in memory and
discarded once its rows have been read.
- Size, page count, text volume and reading time are all capped, so a file built to exhaust the
server's memory or time is refused with a message instead.
- A file is read according to what it actually contains, not what it is named or what type it claims
to be.
- Nothing in a statement is ever executed, evaluated as a command, or used as a file path. Text from
a statement is treated as text everywhere it is displayed or exported.
- A file that cannot be read completely and correctly changes nothing at all.
The figures
- Money is handled as exact decimal values, never as floating-point approximations.
- Each request is a single transaction: a change that fails part-way leaves nothing behind.
- Corrections are made by voiding, not deleting, so anything Flyox ever said can still be explained.
- Every figure states its basis — the period it covers, how many transactions it is built from, and
whether the underlying data is stale.
- There is no AI model in the calculation path. Suggestions and the "Ask Flyox" chat are fixed,
testable rules; nothing the software says about your money comes from a language model.
In transit and in the browser
- HTTPS is enforced in production, with HSTS.
- A content security policy restricts what the page may load and forbids it being framed by another
site.
- Financial replies are marked never to be cached.
- Every value displayed is escaped, so text from a statement cannot become markup.
What is not in place yet
- Two-step verification is optional unless your company requires it. Until you turn it on, your
password is the only thing protecting the account.
- No email verification on sign-up.
- No third-party penetration test or security certification.
- Database-level encryption at rest depends on the hosting provider, and must be stated here once
the provider is fixed.
Reporting a problem
If you find a security issue, please report it to [SECURITY CONTACT EMAIL] rather than
disclosing it publicly. We will acknowledge the report and keep you informed.
[COMPLETE: security contact]
A monitored email address, the response time committed to, and whether there is a safe-harbour
statement for good-faith research.