Orafila Documentation Book a demo

Document 5 of 13

Security and privacy

Technical measures, backups, data processed, GDPR roles, sub-processors.

For whom: Privacy, DPO, IT

This document describes Orafila's security measures and how it fits into the obligations of the GDPR. It can be used as the basis for the annex on technical and organisational measures (Art. 32 GDPR) of the data processing agreement.

The guidance on the GDPR is practical and is not legal advice: contracts should be checked with a privacy consultant or with the DPO.

In brief

Area Measure
Separation between companies PostgreSQL Row-Level Security enforced on every table, foreign keys that include the company, a database role without privileges; the app stops at start-up if the role can bypass the isolation
Access Passwords of at least 12 characters (scrypt hash), two-step verification mandatory for everyone, lockout for 15 minutes after 5 attempts, 12-hour server-side sessions
Authorisation Roles and 23 permissions; every page and every action checks the permission again on the server
Encryption in transit HTTPS with Let's Encrypt certificates renewed automatically, HSTS; with an external database, TLS with mandatory certificate verification
Encryption of secrets Two-step verification secrets, mailbox passwords and Fatture in Cloud tokens encrypted with AES-256-GCM; for session and invitation tokens only the fingerprint (hash) is kept
Traceability An activity log that cannot be changed or deleted from the application, without secrets
Backups Every night, encrypted, verified and copied to separate storage; the private key must also be kept off the server
Infrastructure Database not reachable from the internet, application containers with a read-only file system and without privileges, automatic operating system security updates
AI Optional, can be turned off per company, read-only, data limited to what is needed, never secrets

1. Separation of data between companies

Orafila is multi-company: several companies can use the same installation, each with its own company code.

  • Every table with a company's data has the company column and a PostgreSQL Row-Level Security rule that is enforced (it also applies to the owner of the tables). Every operation of the application sets the company of the person signed in; with no company set, the database returns zero rows: in case of error the system stays closed.
  • Foreign keys include the company: a record cannot point to a record of another company, even if the code were wrong.
  • The application connects with a role without privileges (not a superuser, without BYPASSRLS, not the owner of the tables). At start-up the app and the mail worker check their own role and stop if it could bypass the isolation.
  • The isolation is verified by automated tests that fail if a table is left uncovered or if a company manages to see another company's data.
  • Queries always use values as parameters: SQL injection is ruled out by design.

2. Access and sessions

  • Passwords: at least 12 characters; stored only as a salted scrypt hash; never written to the logs or to the activity log.
  • Two-step verification (TOTP) mandatory for everyone, turned on at the first sign-in; QR code generated by the application, without external services; encrypted secret; each code is valid only once. The IP address never decides authentication.
  • Lockout after 5 wrong attempts (password or code) for 15 minutes, also when changing the password; the error message does not say which of company code, e-mail and password is wrong, and checking the password takes the same time even for a user that does not exist.
  • Sessions server-side for 12 hours, in HttpOnly, Secure, SameSite=Lax cookies; only the fingerprint of the token is kept. Everyone sees their own sessions (device, IP, expiry) and can close the others; changing the password closes them.
  • After sign-in you always go to the dashboard or to turning on two-step verification: no redirects to external addresses.
  • Invitations are single-use and valid for 7 days; there is no automatic password recovery by e-mail (an administrator does it by resetting the access).
  • Suspending a user: their sessions are closed immediately.

3. Authorisation

  • 23 permissions grouped into roles (see Roles and permissions). Visibility rules are declarative, never code stored in the database.
  • Double check: the page checks the permission and shows a notice; the action on the server checks it again; downloads (PDF, CSV) check it too.
  • The company always has at least one active administrator.

4. Encryption

  • In transit: HTTPS is mandatory, with a Let's Encrypt certificate obtained and renewed automatically; HTTP is redirected to HTTPS; HSTS header (2 years). Connections to mailboxes are always encrypted (TLS or STARTTLS). With an external database the connection is always TLS with certificate verification (verify-full or verify-ca): a configuration without verification is refused.
  • Application secrets: encrypted with AES-256-GCM with a key (APP_ENCRYPTION_KEY) that is only in the server configuration and must also be kept off the server, in a password manager.
  • Backups: encrypted with age using a public key. The private key is created on the server (it is used to verify every backup) and must be copied into a password manager: without it, the backups cannot be opened. Anyone who has only the backup files, including the storage provider, cannot read them.
  • Disks: encryption of the server's disks depends on the hosting provider you choose.

5. Activity log

  • It records who did what and when: successful and failed sign-ins with the IP address, password changes, sign-outs from other devices, users and roles, customers and contracts, tickets, products and stock, documents, settings.
  • The application's role can neither change nor delete the log.
  • It never contains passwords, codes, tokens, secrets or unnecessary personal data; it stores codes and details, read in the language of the person consulting it.
  • Administrators can consult it, with filters by area, person, period and text.

6. Protection of the application and the infrastructure

  • Security headers on every page: X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: same-origin, Permissions-Policy (no camera, microphone or location), Strict-Transport-Security; the server does not disclose the software it uses.
  • Request limits: 8 MB per request to the web server, 4 MB for forms (CSV import), 2 MB for e-mails received from the gateway.
  • Mail: no connections to internal or private network addresses (against SSRF attacks), no loops of automatic replies, headers that discourage automatic replies, customers' e-mails never deleted from the mailbox.
  • Containers: app, mail worker, migrations and tools with a read-only file system, no Linux capabilities, no privilege escalation and a non-administrator user; Caddy read-only with only the capability to open ports 80 and 443; the database in the official PostgreSQL image; memory limits for all of them.
  • Network: the database is on an internal network without internet access and without public ports; only ports 80 and 443 of the HTTPS proxy are exposed.
  • Server: Ubuntu and Docker security updates installed automatically every day; SSH access with keys only (recommended in the installation guides).
  • Orafila updates: they arrive as a package with the provider's digital signature; the installer and deploy/nova.sh update check the signature and the fingerprint of every file before changing anything, take a backup and never go back to an earlier version by themselves. The provider can give each server its own access credentials and revoke them.
  • Health check endpoint (/api/health): answers only "ok" or "unavailable", with no data.
  • Logs: the messages of the mail worker and of e-mail reception do not include addresses, texts or secrets; container logs rotate automatically (5 files of 10 MB per service).

7. Backups and continuity

  • Full database backup every night at 02:30 (Italian time), encrypted and verified before being kept; a backup missed while the server was off is taken at restart.
  • Copies: the last 7 on the server and a copy on external S3-compatible storage (for example Oracle Object Storage or DigitalOcean Spaces) for 30 days. On Oracle Object Storage, if you create the retention rule described in the guide, backups cannot be deleted for 29 days, not even with the server's keys.
  • An e-mail alert if a night's backup fails, by setting up an external monitoring service (for example Healthchecks.io).
  • Restore in one command, preceded by a safety backup: the backup is loaded into a temporary database that replaces the current one only if the load succeeds (with an external database, in a single transaction).
  • Maximum data loss with the nightly backup alone: the changes made after the last backup (at most about 24 hours). With a database managed by the cloud provider, its backups and, where offered, point-in-time recovery are added.
  • The procedures for restoring and for rebuilding on a new server are described and must be tested when the service starts (see Operations and maintenance).

8. Personal data processed

Category of data subjects Data Notes
The company's users Name, e-mail, language, roles, hourly cost, last sign-in, password hash, encrypted TOTP secret, sessions (device, IP), sign-ins in the activity log
Customers' contacts Name, e-mail, phone, role in the company, contact person for, consent to marketing communications E-mails from a contact open tickets in the customer's name
E-mail senders Address, subject and text of the e-mails received by the queues Unknown e-mails stay in Inbox; attachments are not imported
Customers and suppliers (legal entities and sole traders) Tax details, addresses, PEC (certified e-mail), suppliers' IBAN, commercial documents
Employees Name, e-mail, phone, work details (job title, department, contract, hours, start and end dates), hourly cost, notes, absences with an optional note For sick leave only the dates are recorded: the form asks you not to write diagnoses or certificates in the note (it is a reminder, not a block). The type of absence is seen by those with “sees employees and absences” (by default Administrator, Accounts and Human resources); everyone else sees “Away”

9. Roles in the processing (GDPR)

  • The controller is the company that uses Orafila for its own customers, contacts and employees.
  • The processor (Art. 28) is whoever provides the service, if Orafila is supplied as a managed service: a data processing agreement (DPA) is needed.
  • Possible sub-processors, to be listed in the DPA according to the installation:
Service When What it receives
Hosting provider (for example Oracle Cloud, DigitalOcean or another EU provider) Always The server, the database and the encrypted backups
Backup storage (from the same provider or another one) If configured Only encrypted backups, unreadable without the key
AI provider (Anthropic, OpenAI, Google) Only if AI is on The data listed in Artificial intelligence
Fatture in Cloud Only if connected The invoices issued, with the customer's data; usually a direct contract between the company and the service
Mailbox providers and sending services Always, if mailboxes are connected Outgoing and incoming e-mails; usually the company's own services
E-mail forwarding gateway Only if used The forwarded e-mails
  • Where the data is: in the server region chosen at installation. The installation guides use European Union regions (Milan, Frankfurt, Amsterdam). For AI providers, check where they process the data and their terms.

10. Data subjects' rights and retention

  • Access and rectification: data is consulted and corrected from the module pages.
  • Erasure: contacts, sites, installed products, products, suppliers, employees and other records are deleted from the interface when they are not used elsewhere; those linked to documents or history (for example a contact mentioned in a ticket, an issued invoice) are changed instead of being deleted, so as not to falsify the history and the tax documents. Customers, users, tickets and received e-mails cannot be deleted from the interface (users are suspended): a request to erase this data is handled by the platform operator.
  • Portability: CSV exports of income and expenses and of the reports; a complete export of a company's data is not yet available from the interface and is a task for the platform operator, on request.
  • Retention: at present there are no automatic deletions on expiry (for example of tickets closed years ago); retention periods must be decided by the controller and applied on request.

11. Secure development

  • Every change to the code goes through automated checks: strict type checking, hundreds of unit and integration tests on real databases, SQL tests of the isolation between companies, building the image.
  • Secret scanning of the code and checks for known vulnerabilities in the dependencies on every change.
  • No secrets in the code: keys and passwords are only in the server configuration.
  • PDFs generated in pure JavaScript, with no browser and no external services on the server.

12. What remains the customer company's responsibility

  • Assign roles with the minimum permissions needed and suspend anyone who leaves the company straight away.
  • Check the activity log periodically (for example failed sign-ins).
  • Use mailboxes dedicated to the queues, with app passwords where the provider requires them.
  • Decide which AI features to turn on and, if necessary, inform your own customers and employees.
  • With an installation on your own server: keep deploy/.env, the backup key and APP_ENCRYPTION_KEY in a password manager, test the restore, keep an external check of the site and of the backups running.