Access control
- Every financial table is scoped to an organization and protected by row level policies enforced in the database, not only in the app
- API calls and agent tool calls run as the signed-in user, with the same policies applied
- An explicit organization id is checked against the caller's active memberships before any read
- Role hierarchy is enforced on membership changes: nobody can raise their own role or assign one above their own
- Viewer and analyst roles cannot write. Employee edits are limited to their own rows
Files
- Uploaded originals and processed representations are stored separately, in per organization paths
- Downloads use short lived signed URLs, not public object URLs
- Deleting a document removes its stored objects as well as its rows
Logging
- Full account numbers, full document contents, raw OCR output and credentials are never logged
- Account identifiers are masked for display and in stored error reports, for example 4821 shown as the last four digits
- Agent and assistant calls are recorded with the tool name, a trimmed argument summary, row count and duration
Audit trail
- Category, amount, date and merchant changes record the previous value, the new value, the user and the timestamp
- Document processing state changes are recorded with their stage and error
- Manual corrections are tracked separately from extracted values, so extraction accuracy stays measurable
The customer facing summary lives on the security page, and data handling is described in privacy.