TTIME Business

Security model

How your workspace stays yours

ERGON TIME is multi-tenant: many organizations share one database. Separation is enforced by Postgres row level security, not by application code, and every rule resolves through your organization membership.

Deny by default

Row security is enabled on every table. With no matching policy the answer is no rows and no write — never an open table.

Identity cannot be spoofed

Every helper begins with user = auth.uid(), so a caller can never have a policy evaluated as somebody else.

Enforced in the database

Authorization lives in Postgres, not in the UI. A leaked API call is refused by the same rules the screens obey.

Organization membership gating

Every business record — transactions, invoices, customers, employees, deals, meetings, workbooks — carries the organization that owns it. A request is answered only when three things line up: you are signed in, you hold an active membership in that organization, and your role (or an explicit override) allows the operation.

request
  └─ signed in?                      no → refused
       └─ active membership in org?  no → no rows returned
            └─ role or override
               allows this action?   no → refused, decision traced
                 └─ yes → row returned or written, action audited

Owner

Full control, cannot be removed while last owner

Admin

Governance, permissions, integrations

Finance

Money-moving work, approvals under threshold

Accountant

Records and reporting, limited edits

Viewer

Read-only

Security helper functions

Policies never query the table they protect — that would recurse. They call small, audited helper functions that run with elevated rights but always re-check the caller's own identity first.

Deny-by-default, verified on every build

The baseline is checked automatically, not assumed. Continuous integration fails the build if any workspace table loses row security, gains a blanket-allow policy, becomes reachable by anonymous callers, or stops resolving through membership. A separate integration suite signs in as real users and proves that a member reads their own organization while a member of another organization — and a user in no organization at all — reads, writes and deletes nothing.

Build guard

Every workspace table must have row security on, at least one policy, no blanket allow and no anonymous access. A violation stops the release.

Isolation tests

Two throwaway organizations, real sign-ins, real API calls, in both directions — including attempts to join another organization or promote a role.

Access trace and audit trail

Sensitive operations — approval submission and decisions, reconciliation matching and unmatching — record which helper was consulted, which membership path applied, and whether access was granted or refused, together with the reason. Owners and admins read this trace inside the app; nobody can write to it by hand, and neither the trace nor the audit log can be edited or deleted.

Available in the app under Governance → Access trace, alongside the append-only audit log.

Run your finance operations on enforced boundaries

Create an isolated workspace and invite your team with the exact rights they need.

Create your workspace