How Libera Europe protects customer records and confidential worker reports, written for security, privacy and procurement reviewers. Scope: the Libera web application, customer console, worker reporting channels and their backend.
This is product and security documentation written by Libera Europe, not a certification or third-party audit. Statements describe what is built today. Items awaiting external validation are labelled as such.
Current status: pilot-stage prototype. No live customer pilot has run yet. Campaign email/SMS delivery is built but switched off, and WhatsApp worker reporting is switched off; workers use the web channel. Descriptions of controls such as PostgreSQL row-level security or the kiosk's 60-second warning and 90-second reset explain how the software is designed and built. They are not guarantees of outcome, and they have not been independently tested.
Security at a glance
Tenant isolation
Row-level security on every customer table, decided by organisation membership.
Private evidence
Worker files sit in a private bucket; no public URLs, 2-minute signed links for designated reviewers.
Minimal public surface
Anonymous visitors have no direct table access; public forms go through rate-limited server code.
Confidential, not anonymous
No account, name or contact details required to report; absolute anonymity is not promised.
Signed webhooks
Payment and WhatsApp webhooks are rejected without a valid signature.
Honest gaps
No certification or external pentest yet. Listed below, not hidden.
Architecture overview
Application layer: React and TypeScript on TanStack Start, with server-side rendering and typed server functions for protected operations.
Backend: a managed PostgreSQL database with an integrated authentication and file-storage service, operated through Lovable Cloud.
Multi-tenant model: every customer record carries an organisation identifier, and database policies scope reads and writes to that organisation.
Sensitive public flows (worker reports, status checks, worker replies) run only through server-side code paths, never through direct browser access to tables.
Worker access campaigns
Campaign outreach data (campaigns, aggregate events, daily page-open counts, temporary contacts) is stored in separate tables with no reference to worker reports, intake answers, follow-ups or cases.
Invitation links use one token per campaign, not per person, and only count page opens per day. The link onward to the reporting form carries no campaign data, so reports are created without an invitation, contact or delivery reference.
Customer-managed distribution is the recommended option and stores no worker contact details. Direct contact import is optional, write-only from the console, not visible to platform administrators, and deleted after 1–30 days or when the campaign closes.
Email (Resend) and SMS (Twilio) sending is implemented server-side but switched off by default. It needs provider credentials, a verified sender domain, signed delivery callbacks and a deliberate on-switch; WhatsApp campaigns are not available.
Definitions: 'sent' means the provider accepted the message; 'delivered' means the provider confirmed, by signed callback, that it reached the inbox or phone; 'page views' count visits to the invitation page, not people. None of these show that a worker read, understood or trusted the message.
Residual correlation risk: providers, mobile networks and hosting infrastructure see message and request metadata (time, recipient, IP address). Libera stores no IP address or per-recipient open with campaign data and counts views per day only, but in very small groups the timing of an invitation and a later report could still allow inference. Bulk sending therefore requires at least 10 contacts.
Controller and processor roles depend on the processing context and should be documented in the DPA and privacy documentation.
Shared-device kiosk mode (pilot MVP)
A kiosk lets workers without a phone use a shared on-site screen. Each kiosk has a random access key shown once; Libera stores only a SHA-256 hash of that key, so a database reader cannot recover it. Anyone holding the original key or kiosk URL can still open that kiosk, so keys should be retired if copied.
Kiosk pages write nothing to browser storage (no local or session storage, no draft saving). A warning appears after 60 seconds of inactivity and the screen resets after 90 seconds; a clear-screen button resets it immediately. Browser history and any device-management or screen-recording software on the device are outside Libera's control.
The server forces the organisation and site from the kiosk key, drops file uploads, and applies per-kiosk rate limits. The kiosk identifier is not written to the report. The receipt code is hidden until the worker taps to reveal it.
Residual risks: shoulder-surfing, CCTV pointed at the screen, and timing inference in small teams. A kiosk being available does not show that workers know about it, trust it or can use it privately; placement should be agreed with worker representatives where possible.
Contact and report segregation
Campaign contacts, invitation tokens and delivery statuses are stored in tables with no column referring to reports, intake answers, follow-ups or cases, and the link from an invitation to the report form carries no token. A test checks this separation.
Libera does not store IP addresses with reports or campaign records. Anti-abuse counters hold only a daily-rotating keyed hash per network and a count, deleted after 48 hours.
Residual risks that software cannot remove: the hosting platform, email/SMS providers and mobile networks see request and message metadata (IP address, time, recipient). In small groups, the timing of an invitation and a later report may allow someone to guess who reported.
What these controls do not guarantee
Confidential is not anonymous. Libera minimises what it collects but cannot guarantee anonymity: writing style, details in a message, device, network and workplace context can identify a person.
SHA-256 checksums show whether a file or export has changed since it was hashed. They do not prove who created it, when it was created, or that its content is true, and they are not a qualified electronic signature.
The activity log is append-only for customer users, but the platform operator and database infrastructure sit outside that boundary. It supports audit review; it is not an independently certified record.
Libera has not been independently penetration-tested or certified (no SOC 2, ISO 27001). Automated tests and internal reviews are not an external audit. Using Libera supports due-diligence documentation; it does not establish legal compliance with any regulation.
Tenant isolation
Organisation membership records are the single source of truth for access. Database helper functions check membership and role on every protected query.
A user's profile cannot be edited to point at another organisation: that field is blocked from client writes by column permissions and a database trigger.
Removing someone from an organisation removes their access to that organisation's records immediately, because policies check current membership rather than a cached pointer.
Organisation identity fields (plan, owner, address slug) are server-managed. Only organisation admins can rename an organisation.
These rules are enforced in the database, so hiding a button in the interface is never the only protection.
Roles & least privilege
Four organisation roles: Admin, Compliance Manager, Investigator and Viewer / Auditor, each with a narrower permission set.
Sensitive Reviewer is a separate, explicit designation granted per person by an admin, with a recorded reason. Being an admin does not by itself grant access to raw worker content.
Ordinary organisation users see grouped signal counts and non-sensitive flags. They cannot read worker free text, guided-intake answers, follow-up messages, evidence files or receipt values.
Platform administration (Libera staff) is a separate boundary: it uses aggregate cross-tenant functions, each access is logged, and raw worker submissions are not shown.
Worker reporting privacy model
Confidential, not anonymous: Libera does not ask for a name, email, phone number, account or precise location. Device, network and context can still reveal identity, so anonymity is never guaranteed.
Two web formats: a short direct report and an optional guided, one-question-at-a-time intake. The server re-derives concerns and severity from guided answers; client-supplied values are ignored.
After reporting, the worker gets a random receipt code to check status and answer reviewer questions. No contact details are collected and no notifications are sent.
Drafts are kept only in the current browser tab and cleared after a confirmed save.
Safeguarding flags are computed by the database from the signal type and never trigger site-level notifications.
WhatsApp is not a worker reporting channel. Libera Europe's WhatsApp number is reserved for business and customer-service enquiries; incoming WhatsApp messages are not processed as worker reports.
Child-sensitive safeguarding workflows
Guided intake has a child-sensitive branch: a young person describing their own situation gets short, plain questions; an adult worried about a young person keeps adult wording. Age is asked only as a band (or "I don't know") — never date of birth, school, home address or parent identity.
Answers are mapped to child-safeguarding indicators and a deterministic review priority (standard, priority or urgent). Age alone never makes a concern urgent; urgent review is driven by combinations such as immediate danger, sexual exploitation or abuse concerns, trafficking or coercion patterns. These are indicators for human review, not determinations of child labour, forced labour or any legal breach.
Child-safeguarding records are visible only to designated Sensitive Reviewers in the same organisation. They are excluded from management dashboards and from Libera platform-administration views; each opening is logged.
No customer email, inspection or authority notification is sent automatically. Reviewers document a checklist, an escalation decision and any referral their team carries out outside Libera. Remediation actions and effectiveness follow-up are tracked separately.
Worker pages offer a "Leave quickly" button that opens a neutral page and clears the unsent form; it does not delete browser history. Libera is not an emergency service, child-protection authority or substitute for local safeguarding professionals. Child-branch translations are not yet professionally validated.
Sensitive evidence
Worker uploads go to a private storage bucket with a 16 MB file limit, restricted to image files and to a valid organisation folder path.
No public evidence URL is ever produced. Designated Sensitive Reviewers open files through 2-minute signed links.
Web uploads receive a server-calculated SHA-256 checksum, and evidence views/exports are recorded in an append-only evidence history.
Authentication & authorization
The customer console requires sign-in through the managed authentication service, with email/password or Google sign-in. Sessions are token-based.
Authorization is enforced by database row-level security, role checks in database functions, and server-side checks in protected server functions.
Multi-factor authentication and SAML/enterprise single sign-on are not implemented today.
Database & public-surface hardening
Direct table privileges for anonymous visitors were removed from all sensitive tables, including worker reports, intake answers, follow-ups and audit records.
Anonymous visitors have no remaining table privileges. The pilot and access-request forms are stored by a server function that validates input, applies a per-network hourly limit, a hidden honeypot field and a minimum fill time. Default privileges for future tables are also revoked from anonymous visitors.
Anonymous execution of internal database routines has been removed; signed-in-callable routines check permissions themselves and use a fixed search path.
Application security
Inputs to server functions are validated with schemas before use. Worker reports can only be written through one guarded server path that applies rate limits, idempotency and safeguarding.
Stripe and WhatsApp webhooks verify the provider signature before processing.
When a required server secret or integration is missing, guarded flows fail closed rather than falling back to weaker behaviour.
Service-role credentials are only read on the server and never shipped to the browser.
Response headers currently set: X-Content-Type-Options (nosniff), Referrer-Policy, Permissions-Policy (geolocation, microphone, camera, payment, USB disabled), Strict-Transport-Security, and a limited Content-Security-Policy (object-src none, base-uri self, form-action self). This is not a strict script-source CSP, and frame embedding is not yet blocked because the editor preview needs it.
Abuse & rate-limit protection
Network identity is taken only from the hosting platform's connecting-address header; caller-supplied forwarding headers are ignored.
Counters store only a daily-rotating, server-keyed one-way hash and a count, deleted after 48 hours. There is no weak fallback key.
Limits are designed for shared factory Wi-Fi: unusual volumes are flagged for human review rather than silently dropped, severe and safeguarding reports get a higher (but finite) allowance, and when a network is busy the worker keeps their draft and sees retry guidance.
Exact thresholds are not published to avoid helping circumvention.
Audit & evidence integrity
The activity log, evidence history, risk events and access-point records are append-only from the application: customer users cannot update or delete them through the data API.
Cases link signals, evidence, remediation actions and effectiveness checks into one timeline.
SHA-256 checksums and append-only history support integrity review. They are tamper-evident in practice, not a digital signature or a non-repudiation guarantee.
Data retention
Anti-abuse counters are deleted after 48 hours.
Worker reports are kept until an organisation admin applies a retention period, with a minimum of 365 days. Evidence history is kept for the life of the workspace.
Known gap: deleting reports under the retention control does not yet delete associated private evidence files, because automatic deletion could remove case-linked evidence. This currently needs manual handling.
A documented procedure covers reporting, triage, containment, assessment, recovery, notification subject to law, records and review.
There is no 24/7 security operations centre or on-call rota, and no fixed notification window is promised publicly; contractual terms are agreed per customer.
Run in a throwaway local PostgreSQL 17.9 sandbox loaded with the same schema, functions, row-level security policies and indexes as the project, using synthetic data only. Live production was not load-tested. Results show relative trends, not production capacity or a service level.
Model
Synthetic data
Observed
1 company
50 suppliers, 100 sites, ~3k reports
0 errors; report submit p95 ~100 ms
5 companies
250 suppliers, 500 sites, ~15k reports
0 errors; report submit p95 ~60 ms
10 companies
500 suppliers, 1,000 sites, ~30k reports
0 errors; report submit p95 ~30 ms
10 companies, 10× history
~300k reports, ~900k log entries
0 errors at 50 concurrent; dashboard p95 >1 s; 2–6 s at 300 concurrent
Network latency, cold starts, hosted plan limits, file storage and long-running behaviour were not modelled. A production-equivalent staging load test is still required.
335 automated Vitest tests passed in the last verified internal run, including tenant-isolation, private-evidence, rate-limit and safeguarding regression tests. These are Libera's own tests, not an external audit.
The basic automated security scan reports no open issues. Database linter warnings (signed-in-callable protected functions) were reviewed: each function checks permissions itself.
A non-destructive internal security review was carried out and its critical and high findings fixed. This is not an independent professional penetration test.
Control matrix
Area
Control
Status
Evidence / scope
Tenancy
Membership-based row-level security
Implemented
All customer tables; verified with rolled-back two-organisation tests
Tenancy
Profile organisation pointer locked
Implemented
Column permissions + trigger
Access
Sensitive Reviewer designation
Implemented
Admin-granted with reason, audited
Access
MFA / enterprise SSO
Roadmap
Not implemented
Evidence
Private bucket, signed 2-minute links
Implemented
16 MB, images only, organisation path
Evidence
Retention deletion of files
Roadmap
Manual today
Surface
Anonymous table privileges removed
Implemented
None remain; forms use a rate-limited server function
Kiosk
Hashed kiosk access keys, no browser storage, idle reset
Implemented
Pilot MVP; physical-site review required
Access
Independent receipt cards / NGO-assisted intake
Roadmap
Specification only, not exposed
App
Webhook signature checks
Implemented
Stripe, WhatsApp
App
Strict CSP / frame blocking
Roadmap
Limited CSP today
Testing
Automated test suite
Internal test
Passing at last update; internal, not an audit
Testing
Synthetic capacity benchmark
Internal test
Local sandbox, not production
Testing
Penetration test
Requires external validation
Internal review only so far
Testing
Production-equivalent load test
Requires external validation
Not performed
Assurance
SOC 2 / ISO 27001
Roadmap
Not held, not in progress
Known limitations & assurance roadmap
No independent professional penetration test has been completed.
No production-equivalent load test has been completed.
Strict script CSP and frame-embedding protection are limited by the current editor preview setup.
Retention deletion does not yet remove associated private evidence files.
Backup, restore, uptime and hosting-region commitments are not defined in this project and are not claimed here.
No MFA, enterprise SSO (SAML/OIDC), SCIM provisioning, SOC 2 report or ISO 27001 certificate.
Internal automated tests and scans are not an independent audit.
Platform staff access to case notes and evidence is limited to time-limited, reason-logged break-glass grants; aggregate cross-tenant counts remain visible to platform admins.
WhatsApp worker reporting is not live; the number is for business enquiries only.
Worker translations other than English are drafts not reviewed by native speakers.
The SHA-256 provenance hash chain and supplier relationship map exist in the synthetic demo only.
2026-10-14 — Added kiosk mode, contact/report segregation and limitations sections; public forms moved behind a rate-limited server function and the last anonymous table privilege removed.
14 October 2026 — Trust Center expanded: architecture, tenant isolation, evidence, public-surface hardening, synthetic benchmark, control matrix and known limitations.
Request a security review
Tell us your questionnaire, entity and jurisdiction requirements and we will walk your team through these controls.