Security & trust

Security you can verify — not just claims.

OPEREX is built for regulated, continuous-process plants, where the operational record has to hold up to an audit. Here is what protects your data today — measured, not aspirational — and, just as plainly, what we do not claim yet.

What protects your data today

Access & identity

  • Invite-only access — no public self-registration; every account is provisioned with its tenant and role.
  • Two-factor authentication (TOTP) is available to every user and required for platform administrators. OPEREX sets a per-tenant minimum (nobody · administrators · everyone — administrators by default for every new tenant), and the organisation can make it stricter itself, never weaker. It is enforced on every request (form submissions included), a code is never accepted twice, and switching it off, renewing recovery codes, lowering the policy or resetting a colleague’s two-factor needs a fresh second factor. Switching it off or resetting it notifies the account holder by e-mail, and a reset also ends all of their sessions.
  • Role-based access control, fail-closed — even a super-admin cannot cross a tenant boundary (verified by tests).
  • Access to each module is decided per role: a role without module access cannot use any function of that module, whatever individual permissions are set. Delegated administration is capped at the delegate — a colleague who may invite or assign sites can only grant a role no broader than their own, and only sites they can access themselves (verified by tests).
  • Server-side token verification on every request; role and tenant come from the database, never from a client field.
  • A session lasts as long as the organisation sets it — 8 hours by default, at most 13 hours (a 12-hour shift plus handover); the time starts at sign-in and using the app does not extend it. Lengthening it needs a fresh second factor from the administrator. Changing or resetting a password ends every other signed-in session immediately — the sessions are revoked on the server, not left to expire.
  • Rate limiting on login, password reset and uploads at the application layer, and at the network edge on the production server.
  • Offboarding by deactivation — access is revoked while the audit trail stays intact.

Tenant isolation — two independent layers

  • Every tenant-scoped query filters by tenant explicitly in application code.
  • Database Row-Level Security (FORCE RLS) enforced at runtime on a role without BYPASSRLS — a missed filter is still caught by the database, and the health check verifies that role on the live connection.
  • Coverage is gated on every deploy: a table missing RLS — or a tenant policy that does anything but match the exact tenant — stops the deploy.
  • Cross-tenant isolation measured against two real tenants, and in CI a probe attempts a cross-tenant write on every tenant-scoped table (mutation-verified).
  • The audit trail is append-only, and the database refuses to modify or delete it for every role — including the owner account we operate with. A lawful, contractual deletion is an explicit, logged procedure, not a quiet UPDATE.
  • Every day, a per-tenant fingerprint of the previous day’s audit trail — together with the signatures on work permits and on maintenance work orders — is chained and stored off-server, so a later change to an already anchored day, even one made with owner rights inside the database, can be detected. Each signature chain also keeps its head on the record itself, so a signature cut off the end of a chain is caught too.
  • An automated dynamic scan (OWASP ZAP) runs every night and on every pull request against a production build of the application, checking what a browser actually receives: security headers, cookie flags, cache directives and information disclosure. A finding stops the pull request, and every accepted exception carries a written justification.

Data & residency

  • Production runs on its own dedicated server, fully separated from the demo and staging environment — separate machine, separate credentials, separate encrypted volume.
  • Self-hosted database and object storage on EU (Hetzner) infrastructure — no third-party database-as-a-service sits between you and your data.
  • The primary storage location is in the EU (Germany). Transactional email is delivered by a US provider (Resend), and off-site backups are held by Cloudflare — both under the EU–U.S. Data Privacy Framework.
  • On the production server the database, the file store and the local backups all sit on an encrypted volume (LUKS); passwords are hashed and two-factor secrets encrypted everywhere.
  • Off-site backups every 6 hours, self-verifying by SHA-256 read-back, with a 90-day weekly tier. The production server backs up to an EU-jurisdiction store; the shared demo/staging environment does not.
  • Since 25 September 2026 the off-site database dumps, the weekly tier, the log snapshots and the configuration archive are encrypted on our own server before upload (age): only the public keys live there, while the private key is held off-server in a password manager and a sealed offline copy — the storage provider cannot read these backups. Two stated exceptions: the file-store mirror is synced object by object and still relies on provider-side encryption, and copies uploaded before that date stay under provider-side encryption until they age out of the 30/90-day retention.
  • Restores are measured, not assumed: on 9 September 2026 a database backup was restored from the off-site copy into a scratch instance — all 124 tables came back with row counts identical to the source; on 20 September the off-site copy of both the database and the file store was downloaded and integrity-checked. On 25 September the production server’s own encrypted backup was taken from the off-site store and decrypted with our private key, producing a valid database dump — the first drill against production data. The full table-by-table restore has so far only been rehearsed on the shared environment.
  • On-premise / air-gapped deployment is packaged for enterprise (installer, container compose, no vendor lock-in) — the data never leaves the site.

Application hardening

  • No SQL injection, stored XSS, CSRF, open redirect, mass-assignment, CSV injection or SSRF — verified by a static audit and its fixes.
  • Every application page carries a Content-Security-Policy with a per-request nonce (no inline scripts), HSTS, X-Frame-Options DENY (the single exception: the public resident-reporting form of an organisation that has switched that tier on may be embedded in a website — only in the https websites the organisation itself lists, at most ten, no wildcard on a top-level domain, and only on that one form; its status, confirmation and unsubscribe pages are never embeddable), nosniff, a strict referrer policy and a restrictive Permissions-Policy that switches off camera, microphone, location and payment access (two exceptions: the microphone, for dictation — in the signed-in application only if the organisation uses dictation (an admin turns it on, off by default, or the work-log’s dictation setting is on), and on the public field-report form reached by QR label only if dictation is on; never on error pages, the browser still asks the user for permission, speech recognition runs through the built-in service of the browser, and no audio reaches us; and the maintenance page may use the camera to scan a QR label, only for a signed-in user and only after the browser asks for permission — for that one page the policy also allows WebAssembly compilation for the fallback QR decoder, which is served from our own origin).
  • Authenticated pages are never cached (no-store); the application is excluded from search indexing.
  • Image uploads are re-encoded server-side (WebP, EXIF stripped) with size and decompression-bomb limits.
  • Infrastructure hardened — internal services bound to localhost, public storage download-only, private storage reachable only through an authenticated proxy.
  • Availability is watched by an external monitoring service every five minutes, with alerting — through the application’s health check, which runs a real database query. Monitoring is not redundancy: see “What we are still working on”, below.

Portability & data sovereignty

  • A CI-enforced blocklist keeps the code vendor-neutral — it runs on vanilla Postgres and object storage, air-gapped, with no code rewrite. Identity sits behind the same adapter boundary, so an enterprise identity provider can be added without touching business logic.
  • Secrets never live in the repository; they are generated and held on the server.

Compliance, handover and exit

  • A data processing agreement that lists the Article 32 measures item by item — not a generic template.
  • A written incident response plan with severity classes and a commitment to notify you within 24 hours, so your own NIS2 Article 23 deadlines (24 h early warning / 72 h report) stay achievable.
  • Operations do not hinge on one person: a designated second emergency contact can reach every credential needed for recovery — through a confirmed emergency-access vault, or a sealed envelope when time is short — and follows a written recovery guide. The procedure is rehearsed every six months.
  • A NIS2 supplier data sheet mapping all ten Article 21(2) measures onto what the product actually does, with the limits stated.
  • Support for ISO 45001 record-keeping (§7.5) and incident investigation (§10.2). The software is a tool for your compliance, not a certificate in itself.
  • On exit, a complete data handover: every tenant data table in machine-readable (NDJSON) and spreadsheet form (CSV), and the stored files themselves (photos, documents) — in a single zip package with a file inventory and a SHA-256 checksum per file; the manifest names anything deliberately left out, with the reason. We send the package as an expiring link with a download limit (7 days, at most 5 downloads) to the address you name, and log every step — sending, opening, downloading. The package is deleted from our servers together with your tenant.
  • Deletion on request, with a certificate: what was deleted, verified afterwards, and the checksum of the export we handed over first.
  • Erasure requests for a single person: on your instruction we pseudonymise the account (email, last sign-in, second-factor secret, sign-in credentials — and the name too, if you decide so), verify it afterwards and hand you a confirmation. A self-deleted account is pseudonymised automatically after 30 days; the name stays as the author of the records unless you instruct otherwise.

What we are still working on

Stated plainly, so nothing on a security questionnaire comes as a surprise. The detailed answers — compensating controls and timing — are in our questionnaire pack, on request.

  • External penetration test scheduled ahead of the first enterprise engagement.
  • ISO 27001 certificate none — the written, auditable equivalents are in the box above.
  • Automatic failover not yet; today 6-hourly, drill-proven backups cover it.
  • File-store mirror under our own key the database, log and configuration backups have been client-side encrypted since 25 September 2026; the file-store mirror is synced object by object and still relies on the provider’s keys.
  • Enterprise SSO (Entra ID) next up; the adapter boundary is already in place.

Reporting a vulnerability

Found a security vulnerability in OPEREX? Write to security@operex.eu. Our machine-readable contact is /.well-known/security.txt (RFC 9116).

What we commit to

  • Acknowledgement within 3 business days.
  • No legal action for good-faith research.
  • Credit on request after the fix.

What we ask

  • Do not access other customers’ data and do not destroy data.
  • No denial-of-service testing.
  • Allow reasonable time to fix before public disclosure.

How current this page is

This page describes the system as it stands today — not a roadmap. Every statement here is tied to something in the code, and our build fails if a limitation listed above has since been resolved and this text was not updated with it.

Legal & data protection

The formal documents behind the statements on this page:

A security question we didn’t answer here?

Talk to us

Let's start a pilot

We'll show you OPEREX on your own operational processes — no strings attached.

Request a demo
Newsletter

Follow how OPEREX evolves

New modules, industrial shift-log tips and ISO 45001 practices — once a month at most, no spam.

You can unsubscribe anytime — the link is at the bottom of every email.