Security
Data security is essential for an HR system. Here we describe the specific technical and organisational measures we use to protect client data. This page is a living document — we update it regularly after new measures are deployed.
Infrastructure
- Hosting: Oracle Cloud Infrastructure, region
eu-frankfurt-1(Germany, EU) - Reverse proxy: Caddy with automatic renewal of TLS certificates (Let's Encrypt)
- Application server: ASP.NET Core 8 in an isolated Docker container
- Database: PostgreSQL 17 in a private Docker network, not accessible from outside
- Operating system: Ubuntu 24.04 ARM with automatic security updates
Encryption
- In transit: TLS 1.2+ (enforced at the reverse proxy level), HSTS header, automatically renewed certificates
- Passwords: BCrypt with an adaptive work factor
- MFA secrets: encrypted at rest
- Refresh tokens: SHA-256 hash; the original value is not stored
Authentication and authorisation
- JWT access token (15 min) + refresh token (7 days) with rotation
- MFA (TOTP, compatible with Google Authenticator, Authy, 1Password, etc.)
- Option to enforce MFA for the whole company (admin in Settings)
- Recovery codes in case of device loss
- Rate limiting on the login endpoint
- Role-based access control (RBAC) with permissions per module
Multi-tenant isolation
HRko hosts the data of dozens of companies in a single application. Isolation is implemented at the database level:
- Every entity has a
company_idand a global query filter at the ORM level - The audit log records every mutation, identifying the user, the company and the IP address
- Super-admin mode is strictly separated from ordinary user roles
Audit log
The application automatically records:
- Logins (successful and failed), logouts, company switches
- Creation, modification and deletion of every entity (with a diff of old and new values; sensitive fields omitted)
- MFA activation/deactivation
- Password changes, password resets, user invitations
As an admin, you can view the audit log in the application in the Audit section.
Backups
- Frequency: daily at 03:00 CET
- Content: complete database dump (pg_dump --gzip) + tar archive of uploaded files
- Retention: 7 days (rotation)
- Location: same region (eu-frankfurt-1), separate disk
- Restore test: performed and documented (last verification: see internal log)
Regular maintenance
- OS security updates: automatic (unattended-upgrades)
- Application runtime (ASP.NET, PostgreSQL): monthly check, critical patches within 7 days
- NuGet and npm dependencies: audit on every deploy build
Incident response
In the event of a security incident (data breach):
- Immediate isolation of the affected component
- Forensic analysis — scope, affected data
- Notification of affected clients within 48 hours by e-mail
- Where required by the GDPR, notification of the ÚOOÚ (Czech Office for Personal Data Protection) within 72 hours
- After resolution: postmortem report, update of measures