open-source, self-hosted HR platform

Prove how every employee record is handled.

  1. Recruit
  2. Onboard
  3. Track time
  4. Review
  5. Offboard

One continuous employee record — from requisition to settlement. Recruit, onboard, track time, review and offboard in one system, with encrypted PII, four-tier RBAC and a full audit trail, on infrastructure you control.

The live demo runs on mock data, with no backend required. Changes are local to your browser session and reset on reload.

peoplevate / dashboard mock data
  • Headcount 248
  • Departments 12
  • Expiring documents 7

Onboarding status

  • In progress 5
  • Completed this month 9
  • Overdue tasks 2

Live activity

  • 09:14 A. Sample UPDATE employee.compensation [redacted]
  • 09:02 B. Sample CREATE document.contract
  • 08:47 C. Sample APPROVE timesheet.2026-W37
  • 08:31 system FLAG auth.failed_login_spike
The demo dashboard, shown on mock data.
  • Three containers One docker compose up
  • AES-256-GCM PII and salary encrypted at rest
  • Four-tier RBAC Enforced on the API and the UI
  • Full audit trail Every mutation, read and export
  • GDPR tooling Rights, retention, 72-hour breach workflow
  • v1 Actively maintained, full lifecycle coverage
  • Public CI + coverage Build, test and coverage are open
  • Apache-2.0 Open source, self-hosted, no vendor
01

How to choose

Ask any HR system the same three questions.

Every HR system answers the same three questions. Which answers your organisation can live with is the real decision — so here they are side by side, including where the other approaches win.

How cloud HR platforms, assembled open source and Peoplevate answer the same three questions, and where each approach is the better fit
Cloud HR platforms Hosted and managed for you by the vendor Assembled open source Separate modules you integrate and secure Peoplevate One record, compliance in the base system
Where does employee personal data physically live? Not who the vendor is — where the records actually sit. Cloud HR platforms With the vendor, in a multi-tenant store. Residency and sub-processors become commitments the vendor manages on your behalf. Assembled open source Wherever each module put it — often several databases, each with its own access model. Peoplevate In your PostgreSQL database and your encrypted uploads volume. No multi-tenant store, and no vendor in the data path.
Who has accessed a record — and can you prove it? Not whether a permissions screen exists — whether you can reconstruct what happened. Cloud HR platforms Through the vendor’s own access tooling. The depth of retained audit history varies by product and by plan. Assembled open source Partly. You collect logs from each component, where that component keeps them at all. Peoplevate Four-tier RBAC enforced on the API and the UI, with every mutation, sensitive read, download and export written to one audit log.
What does staying compliant cost? In licences, in engineering time, and in the next audit. Cloud HR platforms A recurring subscription, typically sized per seat or per module, with compliance tooling spread across tiers. Assembled open source Engineering time: integrate, harden, document — and keep all of it that way as each module moves. Peoplevate Apache-2.0, with no per-seat licence and no paid tier holding back encryption, RBAC or the GDPR tooling. Your team contributes the operational effort instead — that is the trade.
Where each approach is the better fit Honestly, all three are the right answer somewhere. Cloud HR platforms When zero operational burden matters more than where the data sits. Assembled open source When you need to compose specific best-of-breed modules and have the engineering time to run them. Peoplevate When data residency and provable handling are non-negotiable, and you are willing to operate the stack yourself.

How it is built

Three engineering decisions, all in the direction of being able to account for the record:

  • A clean layered architecture

    routes → services → Prisma, in strict-mode TypeScript.

  • Security that is on by default

    AES-256-GCM encryption of PII and salary at rest, JWT with rotating refresh tokens, and RBAC enforced on both the API and the UI.

  • Auditability you can prove

    Every mutation, and every sensitive read, download or export, is written to the audit log.

Peoplevate fits when

  • You self-host by policy — data residency, procurement rules or a regulator requires it.
  • You have to answer “where is our employees’ personal data, and who has seen it?” with evidence rather than assurance.
  • You want the whole employee journey — recruit to settlement — in one system rather than a permanent integration project.
  • You have the engineering capacity to run three containers and own your own backups.

It is not the right fit when

  • You want a fully managed cloud HRIS with no operational work — a SaaS provider is the better answer.
  • You need a partner network for payroll, benefits and local statutory filings to be handled for you out of the box.
  • You need a staffed helpdesk with contractual response times; Peoplevate is community-supported open source.

A narrow fit is deliberate. If the second list describes you, one of the approaches above is the better choice — and it is better to know that now.

02

Why Peoplevate

Compliance built in, not bolted on.

Many open-source HR suites are assembled: separate modules, each with its own data model, access rules and upgrade path. Joining them up is one project; securing the result is another.

Peoplevate takes the opposite approach — the whole employee lifecycle in one data model, with compliance built in rather than bolted on.

Assembled modules

  • Module
  • Add-on
  • Plugin
  • Your security

Integrated, configured and secured by you.

One data model

  • Encryption
  • RBAC
  • Audit trail
  • GDPR tooling

In the base system, not a paid tier.

Both columns describe an approach, not a product. In an assembled stack each module keeps its own access rules; here, encryption, roles and the audit trail sit inside one data model.

The record, the access rules and the audit trail are one system, on your infrastructure — so “where is this data, and who has seen it?” has one answer.

  1. 01

    Lifecycle continuity

    One employee record, continuously, from job requisition → offer → onboarding → attendance, timesheets & leave → performance review → offboarding & settlement. Every stage is a workflow with an approval path and an audit trail, not a standalone table.

  2. 02

    Compliance by default

    AES-256-GCM field encryption for PII and salary, GDPR data-subject rights with SLA tracking, retention policies with legal hold, a breach workflow with a 72-hour deadline, and consent evidence — in the base system, not a paid tier.

  3. 03

    Provable access control

    Four-tier RBAC (ADMIN / HR_MANAGER / MANAGER / EMPLOYEE) enforced on the API and the UI, with account lockout, argon2 password hashing and rotating refresh tokens with reuse detection.

  4. 04

    Auditable by design

    Every create, update and delete is recorded — plus sensitive reads, downloads and exports — with anomaly detection for failed-login and bulk-download spikes. Salaries appear as [redacted] in the log, because plaintext is never stored.

  5. 05

    Yours to run

    Three containers, one docker compose up, migrations applied on start, persistent volumes and health checks on every service. No vendor and no multi-tenant data store — the database, the encrypted documents and the audit log stay on your infrastructure.

03

The employee record

One record, five stages, no hand-offs.

Every stage is a workflow with an approval path and an audit trail — not a standalone table, and not something you have to reconstruct later. Select a stage to see what it holds.

Stage 01 · Recruit

Job requisitions, postings and a candidate pipeline, from application to offer letter.

What the stage holds

  • Job requisitions with an approval workflow, postings and interview scheduling.
  • A candidate pipeline that ends in a signed offer letter rather than a spreadsheet hand-off.

Approval path

Requisition

  1. draft
  2. pending
  3. approved
  4. published
  5. closed

Candidate

  1. APPLIED
  2. SCREENING
  3. INTERVIEW
  4. OFFER
  5. HIRED

One funnel, one record, one data model — and every step lands on the audit log. Nothing is handed to a spreadsheet between stages.

04

A quick tour

Four surfaces you will actually live in.

Each one is part of the same record — the time data, the compliance queue, the audit log and the directory all read and write the same employee.

01

Timesheets

Weekly project × day grid, draft → submit → approve, with approval history and working-time reports.

timesheets / week 37 mock data
Weekly timesheet for week 37, hours per project per day
Project Mon Tue Wed Thu Fri Sat Sun Total
Atlas rollout 87864 33
Support rota 01024 7
Internal 100002 3
Week total 988882 43
Draft Submitted 09:41 Approved 10:02

Approved by C. Sample · Mon–Sun week · daily cap 24h

Weekly project × day grid with a 24-hour daily cap, manager approval and working-time reports.

02

Data subject requests

GDPR access, erasure, portability and rectification requests tracked against a 30-day SLA.

compliance / data subject requests mock data
Data subject request queue with request type, status, received date and SLA deadline
Type Status Received SLA deadline Days left
Access In progress 02 Sep 02 Oct 28
Erasure Queued 09 Sep 09 Oct 21
Portability Completed 21 Aug 20 Sep met
Rectification In progress 11 Sep 11 Oct 19

SLA tracking is part of the base system. Retention policies, legal hold, consent evidence and a 72-hour breach workflow sit alongside it.

Access, erasure, portability and rectification requests tracked against a 30-day SLA.

03

Audit log

An immutable record of every mutation, with before → after values and redacted salaries.

security / audit log mock data
Audit log showing user, action, resource, before and after values, status and timestamp
Time User Action Resource Before After Status
09:14:22 A. Sample HR_MANAGER UPDATE employee.compensation [redacted] [redacted] OK
09:02:07 B. Sample ADMIN CREATE document.contract aes-gcm · v2 OK
08:47:51 C. Sample MANAGER APPROVE timesheet.2026-W37 SUBMITTED APPROVED OK
08:31:09 unknown LOGIN_FAILED auth.session attempt 4 of 5 WARN
08:12:40 D. Sample HR_MANAGER EXPORT report.working_time CSV · 412 rows FLAGGED
Illustrative rows from the demo dataset. The live demo runs on mock data — no real employee records are shown.

04

Employees & organization

Hierarchical departments, positions, encrypted PII and employment-change history.

employees / directory mock data
Employee directory with department, position and employment status
Employee Department Position Status
A. Sample People Ops HR Manager Active
C. Sample Engineering › Platform Engineering Manager Active
D. Sample Finance Payroll Analyst On leave
B. Sample Engineering › Data Platform Engineer Probation
  • national_id [redacted]
  • compensation [redacted]
  • documents 7 expiring · alerts scheduled
Hierarchical departments and positions with employment status. Names shown are illustrative.
05

Security & compliance

Security is a design constraint here, not a feature flag.

Encryption, RBAC, audit logging and the GDPR tooling are part of the base system, not a paid tier.

  • 72h Breach notification deadline
  • 30d Data subject request SLA
  • 5 Failed attempts before lockout
  • 15m Access token lifetime

In plain terms

  • Not readable off the disk Personal data and salary are encrypted at rest, so the database on its own does not reveal them.
  • Only the access you grant Four role tiers decide what each person can see — checked on the API and in the interface, not just hidden in it.
  • Every change on record Creates, updates, deletes, and sensitive reads, downloads and exports all land in one audit log.

01 Protecting data at rest and in transit

  • PII and salary are encrypted at rest with AES-256-GCM using FIELD_ENCRYPTION_KEY, with versioned key management and a legacy decryption fallback for older records.
  • Plaintext passwords, salaries and national IDs are never logged or stored — salaries are rendered as [redacted] in the audit log.
  • JWT secrets and encryption keys are environment-only, enforced to be ≥ 32 characters, and never committed.
  • Helmet security headers (CSP/HSTS), CORS allow-listing and request body limits are applied by default; no source maps ship in production unless VITE_SOURCEMAP=true.

02 Authentication and access control

  • 15-minute access tokens with 7-day rotating refresh tokens, hashed at rest, with reuse detection via token families.
  • Account lockout after 5 failed attempts (15-minute cooldown) plus login rate limiting.
  • RBAC enforced on both frontend routes and backend middleware.

03 Accountability

  • Every create, update and delete is audit-logged, alongside sensitive reads, downloads and exports.
  • Anomaly detection for failed-login and bulk-download spikes.

04 GDPR

  • Data subject rights (access, erasure, portability, rectification) with a request queue and SLA tracking.
  • Retention policies across eight data categories with hard-delete and anonymize actions.
  • Legal hold support.
  • A breach notification workflow with a 72-hour deadline.
  • Consent management with evidence records, and IP data minimization.
06

Self-hosting

Yours to run.

Three containers, one docker compose up, migrations applied on start, persistent volumes and health checks on every service.

Prerequisites

Docker Engine 24+
With Docker Compose v2 Recommended for self-hosting
Node.js ^24
Local development
pnpm ^11
Local development The repository pins pnpm@11.21.0 via packageManager
PostgreSQL >= 18
Non-Docker manual setup only Not required for the Docker stack

Required environment variables

Validated by zod at startup, which fails fast on invalid values. Secrets are enforced to be at least 32 characters and are never committed.

DATABASE_URL backend
PostgreSQL connection string
JWT_SECRET backend
At least 32 characters
FIELD_ENCRYPTION_KEY backend
At least 32 characters (AES-256 for PII and salary)
VITE_USE_MOCK frontend
Set to false to use the real API instead of data/mock-data.ts
VITE_API_BASE frontend
Optional API base URL override

The recommended self-hosted stack

Docker
# 1. Configure environment (secrets are REQUIRED — >= 32 chars)
cp .env.docker.example .env
#    edit .env: set POSTGRES_PASSWORD, JWT_SECRET, FIELD_ENCRYPTION_KEY

# 2. Build and start all three services
docker compose up -d --build

# 3. Verify — all services should report "healthy"
docker compose ps
curl http://localhost/healthz        # frontend (Nginx)
docker compose exec backend wget -qO- http://127.0.0.1:4000/health   # backend API
  • Open the app at http://localhost. The backend API is proxied at /api; its own health check is at /health.
  • Data lives in named volumes (peoplevate-db-data, peoplevate-uploads, peoplevate-logs) and survives docker compose down. Migrations run automatically on backend start.
  • The frontend is the single public entrypoint — the database and backend ports bind to 127.0.0.1 only.
07

Modules

Everything it does, in one register.

Core lifecycle and platform modules — each one reading and writing the same employee record, which is the point. This is the reference list.

Core lifecycle

  • 01

    Recruitment → hire

    Job requisitions with an approval workflow (draft → pending → approved → published → closed), postings, a candidate pipeline (APPLIED → SCREENING → INTERVIEW → OFFER → HIRED), interview scheduling and offer letters.

    One funnel, one record — no spreadsheet hand-off.

  • 02

    Onboarding

    Tasks for document submission, equipment assignment, orientation and system access setup.

    New hires become productive and provably compliant from day one.

  • 03

    Attendance, timesheets & leave

    Clock in/out with IP capture and configurable grace minutes; a managed project & task catalog; weekly (Mon–Sun) timesheets with a 24-hour daily cap, manager approval and email notifications; leave types, policy groups, entitlements and balances with a multi-step manager → HR approval flow; and holiday calendars.

    All time data in one place, with role-scoped reporting and CSV export.

Platform & governance

  • 04

    Performance

    Evaluation cycles (probation / mid-year / end-year) with a self → manager → HR review workflow and optional rebuttals.

  • 05

    Offboarding

    Clearance checklists, exit interviews, settlements and a full offboarding state machine (INITIATED → CLEARANCE_IN_PROGRESS → EXIT_INTERVIEW → SETTLEMENT → CLOSED).

  • 06

    Organization

    Hierarchical departments, positions and employees with manager relationships, plus employment-change tracking (promotion, transfer, manager change, salary adjustment, status change) with before/after history.

  • 07

    Documents

    Typed documents (contract, national ID, passport, …) with AES-encrypted PII, expiry tracking and automated expiry alerts.

  • 08

    Security & compliance

    JWT + rotating refresh tokens, argon2 password hashing, account lockout, rate limiting, four-tier RBAC, full audit logging, and GDPR data-subject rights, retention policies and breach notification.

  • 09

    Automation

    Scheduled jobs for document expiry, leave accrual, probation, deactivation, retention purge and DSAR SLA checks.

08

Architecture

Three services, one command.

No vendor and no multi-tenant data store — the database, the encrypted documents and the audit log stay on your infrastructure.

Data flow

Browser frontend :80
Nginx + React SPA · /api reverse proxy
frontend backend /api
Express 5 + Prisma 7 · Node 24
backend PostgreSQL 18
Employee records and audit trail
backend Encrypted uploads volume
Documents, encrypted at rest
backend Logs + audit trail
Winston, plus the audit log
backend SMTP / mock mailbox
Notifications
09

Documentation & status

Read it before you run it.

Four documents cover the modules, the role matrix, the REST API and production deployment.

Built with

Backend
Node.js 24 · Express 5 · TypeScript (strict, ESM) · Prisma 7 · PostgreSQL 18
Frontend
React 19 · TypeScript · Vite 8 · Tailwind CSS v4 · Radix UI · framer-motion
End-to-end
Playwright, driven through a real browser against a real backend and seeded database
Testing
Vitest · supertest · Testing Library · MSW
10

Questions

The questions a self-hosting decision raises.

What it costs, what you have to run, and what happens if you ever want to leave.

Anything not covered here is best asked in the open — open an issue (opens in a new tab) and the answer stays public for the next team that asks.

Get started

Run it yourself — and be able to prove it.

Walk every workflow in the live demo without a backend, then deploy the full stack with three containers and one command. The database, the documents and the audit log stay on infrastructure you control.

  • Licensed under Apache-2.0 and self-hosted, so there is no vendor in the data path.
  • Running a security review? The security policy and the compliance documentation are public.
  • Building on it? Contributions are welcome — run pnpm ci before opening a pull request.