Version 1.0 · Effective 2026-09-20

Security & Trust

ZekoHR is a multi-tenant HR platform. Our customers trust us with employee records, payroll, and confidential grievance reports. This page states what we actually do — including where we are not yet where we want to be. Where a control is planned rather than live, it is marked as such.

Operated by Teknowledge Software, Kolkata, India.

Encryption in transit

  • All traffic to *.zekohr.com is served over TLS through Cloudflare.
  • The connection between Cloudflare and our origin server runs in Full (Strict) mode with a Cloudflare Origin CA certificate — the origin's certificate is validated on every hop; there is no plaintext or unverified leg.
  • The origin server only accepts HTTPS connections from Cloudflare's published IP ranges (firewall-enforced, refreshed weekly). Connecting to the raw IP times out — the WAF and edge protections cannot be bypassed.
  • The database and Redis are bound to 127.0.0.1 and are not reachable from the network at all.

Encryption at rest — the honest state

  • Files (employee documents, payslips, receipts, grievance evidence): stored in Cloudflare R2, where all objects and metadata are encrypted at rest with AES-256 (GCM), keys managed by Cloudflare.
  • Passwords: bcrypt-hashed (never stored in recoverable form).
  • API tokens: stored hashed (SHA-256); the plaintext token is never persisted.
  • Platform staff TOTP secrets: encrypted at the application layer with the app key.
  • The primary database is not currently encrypted at the database or filesystem layer. MariaDB table encryption is off and the server filesystem is plain ext4. Whether the hosting provider (Linode) applies hypervisor-level disk encryption on this plan has not been confirmed.

Planned: confirm hosting-provider disk-encryption status for this instance; evaluate MariaDB data-at-rest encryption (or application-level encryption for the most sensitive fields) before public signup opens.

Backups & retention

Honest current state:

  • The database is dumped daily at 01:00 UTC, integrity-tested (the archive is decompressed and checked for expected content — a corrupt dump fails the run loudly), shipped off the server to a Cloudflare R2 bucket, and pruned to the most recent 14 daily copies. Backup freshness is checked every 15 minutes by our health monitor, which alerts on failure.
  • Files in R2 are stored separately from the server, so loss of the server does not lose customer files.

Two known gaps, stated plainly:

  1. A dedicated backups bucket exists, but the credential that isolates it from the application is not yet configured — backups currently fall back to the documents bucket, which means the application credential could delete them. Every backup run warns about this until it is fixed.
  2. A full restore rehearsal has never been performed. The backups are verified as readable archives with expected content, but a restore into a working system has not yet been exercised. We treat an untested backup as a hope, not a guarantee, and this is on the pre-launch checklist.

Data retention on cancellation: after a subscription is cancelled, the tenant retains read-only access, and data is retained for 90 days (configurable per plan), after which it is irreversibly purged — every database row and every stored file. An immediate purge on request (e.g. a DPDP erasure request) is supported as a deliberate, audited, manually-confirmed operation.

Access control — who can see what

Within your tenant: access is role-based (Admin, HR Manager, Manager, Accounts, Employee), enforced per-permission on every API route. Grievance case files are restricted to HR Managers and Admins even against other managers. Every tenant's data is isolated by a tenant identifier on every table, enforced twice: by request middleware and by a database-level query scope, so a missed filter fails closed. Our CI pipeline runs a dedicated tenant-isolation test job on every change.

Within our company (platform staff):

  • Platform staff accounts live in a separate table with a separate login surface; a tenant credential cannot reach platform routes.
  • Two-factor authentication (TOTP) is mandatory for all platform staff, with no opt-out. The login endpoint structurally cannot return a session from a password alone — it returns a challenge that only an authenticator code completes.
  • An optional IP allowlist can restrict platform login further.
  • When our staff access a tenant account for support ("log in as"), the session is time-boxed (60 minutes by default, hard cap 8 hours, no refresh), shows an undismissible banner to the operator, and every action taken is written to the tenant's own audit log with both identities — the affected user and the staff member answerable for the action.
  • Production secrets live only on the production host, root-owned, mode 600. They are not in the repository and not in CI logs.

Tenant user sessions: short-lived bearer tokens (60-minute access tokens with 7-day refresh tokens; both record IP and user agent), plus per-email-per-IP lockout on repeated failed logins (5 attempts / 15 minutes).

Planned (honest gap): two-factor authentication for tenant users (including tenant admins) is not yet available — it is a planned feature. Mandatory 2FA today covers platform staff only.

Audit logging

Every material action in a tenant — record changes, approvals, payroll operations, role changes, overrides, support-access sessions — is written to an append-oriented audit log carrying the actor, the affected entity, before/after values, and (when applicable) the impersonating staff member. Platform-level staff actions are logged separately in a platform audit log.

Planned: tenant-facing audit log export — the data exists and the admin screen exists; the export endpoint does not yet.

File access

Customer files are stored in a private bucket — nothing is publicly listable or readable. Downloads are served through a signing gateway: the application authorises the user, then issues a short-lived (5-minute) signed URL; the gateway verifies the signature (constant-time comparison, server-side expiry, path-traversal rejected) before streaming the file. The only unsigned prefix is public/ (tenant logos and email images), and application code can only write there through a separate, deliberate storage disk.

Incident response

We maintain an incident runbook covering severity classification, roles, customer communication timelines (first notice within 30 minutes of confirming a customer-visible incident, even before we have answers), and the DPDP-mandated breach notification procedure (intimation to affected individuals and a report to the Data Protection Board of India within the statutory window). The runbook is an internal document; a summary is available to customers on request.

Planned: a public status page at status.zekohr.com is planned and not yet live.

Subprocessors

The full, versioned list — with a 30-day change-notification commitment — is available to customers on request while this site is pre-launch, and will be published at a public URL.

Data residency

Primary database: Mumbai, India. Files and backups: Cloudflare R2, Asia-Pacific placement — with an honest caveat about what Cloudflare does and does not guarantee. The full statement, including where email and error data go, is available on request and will be published alongside the subprocessor list.

Payments

Card and mandate data never touch ZekoHR systems. A full PCI scope statement is available on request.

Responsible disclosure

Report suspected vulnerabilities to security@zekohr.com. We will acknowledge within 2 business days and will not pursue good-faith research conducted without data exfiltration or service disruption.

What we do not yet have — stated plainly

  • No SOC 2 or ISO 27001 certification (planned only when the pipeline justifies it; most evidence-producing controls above already exist).
  • No external penetration test yet (committed before public launch, scoped to the tenant-isolation boundary and entitlement gates).
  • No tenant-configurable password/session policy yet (planned).
  • Restore rehearsal pending, as stated in the backups section.