Access and security
Security practices
Sign-in protection, tenant isolation, secrets and file access.
Tenant isolation
The organisation is the boundary and every record carries it. Identifiers arriving in a request are re-verified against the caller's organisation before use — a valid identifier from another tenant is otherwise a perfectly well-formed request. In object storage the organisation is also the key prefix, checked independently of the database row, so one mistake is not enough.
Sign-in protection
- Attempts are counted against both the network address and the account, with the stricter limit deciding. By address alone, one attacker behind many addresses grinds a single account; by account alone, anybody can lock a colleague out by failing their password on purpose.
- A rate-limited sign-in is indistinguishable from a wrong password, so an attacker cannot detect where the limit is.
- The limiter fails open. If its own cache is unreachable the request proceeds and the failure is logged loudly — a limiter that rejects everything when a cache is down has turned a cache outage into an authentication outage.
- Registration, invitation acceptance, mobile token issuance and the provisioning endpoint are limited too.
Secrets
- Passwords
- Hashed with bcrypt. Accounts created through single sign-on or directory provisioning have no password at all rather than one nobody was given.
- Provisioning tokens
- Stored as a SHA-256 hash and shown once. There is nothing to do with one except present it, so a recoverable copy would be a liability with no use.
- Signing keys
- Encrypted at rest with a key held outside the database, so holding a database dump is not enough.
- Invitation tokens
- 32 random bytes, never returned from the API, and delivered only to the invited address. Accepting is an authenticated action, so a link fired by a mail client prefetching it cannot join anybody to anything.
Files
Nothing is served from a public URL. Every download is authorised and then redirected to a short-lived signed link; uploads use a pre-signed URL that is only issued after the same check. See Documents and storage.