Skip to content
CirroPeople
Start free

Security and tenant separation

HR data is among the most sensitive a business holds. This page describes what CirroPeople actually does — the mechanisms, not adjectives.

Tenant separation

CirroPeople is multi-tenant by design. Separating one customer from another is the single property we treat as non-negotiable, and it is enforced in more than one layer.

Ownership in the schema

Every business-owned record carries a required organization relation. There is no table where a row can exist without an owner.

Scoped data access

All reads and writes pass through a repository that mechanically applies the organization filter. A record fetched by ID is looked up by ID and organization, so another tenant’s ID simply returns "not found".

Membership proven per request

The organization address in the URL is used only to look the organization up. Access requires an active membership row, re-read from the database on every request.

Database rules deny by default

The browser is never given a database token. PocketBase’s own API rules are closed to everyone but the service account, so no cross-tenant read is reachable over the database API at all.

Isolation is tested

The test suite creates two organizations and asserts that one cannot reach the other’s records, documents, payroll, searches or exports. A failure there blocks release.

Access control

Two independent role systems that never blur into one another.

Per-organization roles

Owner, HR administrator, manager, finance, employee, intern and auditor — held per organization. The same person can hold different roles in different businesses.

Separate platform roles

Platform administration is a distinct set of roles on the user account. Being an owner of a customer organization grants no platform access whatsoever.

No privilege escalation

An administrator can never grant a permission they do not themselves hold, and the last remaining platform owner and organization owner cannot be removed or demoted.

Least privilege on approvals

Nobody can approve their own leave, and finalized performance reviews and payroll runs become immutable.

Sensitive data

Salary, banking, identifiers and health information are treated differently from a name and a job title.

Split storage

Sensitive identifiers and banking details live in a separate record behind their own permission, so they never ride along on a directory listing or an export.

Masked by default

Without the specific permission, sensitive fields are masked on the server. The real values are never sent to the browser and then hidden with CSS.

Elevated access is deliberate

Platform support staff searching across tenants see masked data unless they hold an explicit elevated permission and supply a reason — and every such access is recorded.

Protected downloads

Files are never served from a guessable URL. Each download is authorised against the caller’s organization and permissions at request time, then logged.

Application security

The ordinary web-application defences, applied consistently.

Session handling

Signed, HTTP-only, same-site cookies. The browser never holds a credential the database would accept, so a stolen cookie cannot be replayed against the data layer.

CSRF protection

Origin checks plus a double-submit token on every state-changing request.

Input validation

Every input is validated with a schema on the server. Database filters use parameter binding, so user input cannot alter a query.

Security headers

A nonce-based Content-Security-Policy, plus X-Content-Type-Options, Referrer-Policy, Permissions-Policy and frame-ancestors restrictions.

Upload validation

File size and MIME type are checked against configured limits before anything is stored.

Safe errors

Users see a helpful message; stack traces and internal detail never leave the server.

Auditability

If something happened, you should be able to find out who did it and when.

Broad coverage

Registrations, sign-ins and failures, invitations, role changes, business creation, payment exemptions, plan changes, suspensions, impersonation, employee changes, payroll and document access, exports, billing webhooks and platform settings.

Secrets are redacted

Audit payloads pass through a redaction layer, so no password, token, cookie, authorization header or provider secret can be written to the trail.

Append-only

Audit entries are written once and never edited by the application.

Exportable

Organizations on the appropriate plan can export their own audit log; platform auditors can export across the platform.

Billing integrity

Money-related state changes are only trusted from a verified source.

Webhooks are verified

Provider signatures are checked before a payload is read, with a replay window enforced.

Idempotent processing

Each provider event is recorded under a unique key, so a redelivered webhook cannot apply twice.

Redirects prove nothing

A subscription is never activated because a browser returned from a checkout page. Only a verified webhook activates a paid plan.

Exemptions are recorded

A business created without payment always records who authorised it, why, and against which subscription.

Reporting a vulnerability

If you believe you have found a security issue, please contact us before disclosing it publicly. Include the steps to reproduce and what you were able to access. We will acknowledge your report, keep you updated while we investigate, and credit you if you would like us to.