Boundaries

Security

The authentication boundary, tenant isolation, permissions and separation of duties — and what we do not claim.

One place checks a password

Console never authenticates and has no registration — it does not even have a login form. Identity can only arrive through the one-time handoff from Portal. When you audit who can sign in, there is exactly one place to look.

Tenant isolation sits in the database

Each company's data lives in its own PostgreSQL schema, and Console sets the search_path per request. The schema name comes only from the credential payload — not from the URL, a cookie or the request body — so there is no parameter to tamper with.

Permission slugs decide what opens

7 roles and 36 permission slugs, seeded into each tenant schema by RbacSeeder. The sidebar is generated from the permissions held, with no hardcoded menu — what you cannot see is absent because the right was not granted, not because the front end hid it.

"Only your own rows" is not something a slug can say

A permission slug opens a page; it cannot express "only the rows belonging to you". So on self-service, my pay slips and my reviews, the real security boundary is an ownership check in the controller and dedicated middleware — not the slug, and never the template.

Preparing the numbers is not signing them off

Opening and calculating a payroll period needs hr.payroll.manage; finalizing or voiding it needs hr.payroll.finalize. They are deliberately separate so whoever prepares the figures does not automatically approve them. The same split is applied to compliance exports and to posting the accounting journal.

Stored secrets are encrypted

Webhook signing secrets are encrypted with the application key rather than stored in the clear. That makes APP_KEY itself secret-bearing — any backup of it has to be treated as a secret too.

Roles

Seven roles, and room to split further

The default roles are cut finer than "admin and everyone else" on purpose. A payroll administrator can run payroll and file the statutory returns without holding the employee master; a shift supervisor can build the roster and read attendance without seeing a single salary figure.

Roles and permissions are seeded data, not code. Grants can be reshaped to match how your company actually divides the work, without a release.

Default roles
RbacSeeder
Super Admin super_admin
HR Administrator — every module and setting hr_admin
HR Manager — people, attendance, leave, payroll hr_manager
Payroll Administrator — payroll and filings, without the employee master payroll_admin
Shift Supervisor — roster and attendance, without payroll shift_supervisor
Department Manager — their own department and its leave approvals department_manager
Employee — their own records only employee

What we do not claim

This page describes how the software is built. It is not an audit report. FincoHR does not hold ISO 27001, SOC 2 or any third-party security certification, and we will not imply otherwise. Ask us directly about penetration testing, data residency, backup retention and recovery objectives — we will answer honestly, including where the answer is "not yet".

For security questions or to report a vulnerability, contact support@fincosoft.com

Next step

Wondering whether it fits how you already work?

Tell us how you run payroll today, which time clock you use and how many departments you have. We will tell you straight whether it fits.