Production Gateway Active • Mews Certified Partner Node Layer
Back to the security pack
Self-authored

SwiftInvoicePro — Security & Controls Whitepaper

Apex Flow Technology Ltd · Company No. 17347345 · England & Wales Self-authored. Version 1.8 · 20 August 2026 · Next review: February 2027

This document describes controls that are currently implemented in the product. It is not a third-party audit, certification, or penetration test report, and it does not claim to be one.

1. Entity and scope

FieldValue
Legal entityApex Flow Technology Ltd
Company number17347345 (England & Wales)
Registered office29 Railway Road, Rhoose, Barry, Wales, CF62 3FE
Product in scopeSwiftInvoicePro — corporate folio aggregation and invoice generation
Security contactnatromrich@googlemail.com
Data controllerThe hotel or hotel group. Apex Flow acts as processor.

Out of scope: the customer's own PMS, POS, and finance systems; any network or endpoint the customer operates.

2. Data handling and integration security

  • Data minimisation profile. PMS integration is read-only parameter mapping. We request only the fields required for corporate folio and ledger reconciliation — transaction codes, amounts, tax components, business dates, and the corporate account reference. Nothing is written back to the PMS at any point.
  • PII isolation. Guest names, personal contact details, and card data are filtered out at the ingestion layer before aggregation. No guest PII is permanently written to the SwiftInvoicePro database.
  • Encryption. All traffic between the hotel PMS or marketplace and SwiftInvoicePro is protected with TLS 1.3, terminated at the edge. Data at rest in the production database is encrypted with AES-256 by the managed database provider.
  • Ephemeral in-memory processing. Ledger cross-matching runs inside a per-request isolate. Transaction lines are parsed, reconciled against the corporate account map, and released with the request context. There is no long-lived server state and no intermediate write to cache or disk.

3. Multi-tenant architecture and boundary protection

  • Logical separation of customer data. SwiftInvoicePro is a cloud-native multi-tenant application. Every tenant-scoped table carries organization_id or user_id, and isolation is enforced at the database query layer by PostgreSQL Row Level Security — not in application code — so a mistaken or compromised client cannot widen its own scope.
  • Role-based access control. Administrative surfaces are gated by explicit role tiers. Roles are stored only in user_roles and read through the has_role security-definer function, which prevents client-side privilege escalation and blocks horizontal access across properties within a group.
  • Cryptographic tenant isolation on inbound integrations. Each property's PMS webhook endpoint is addressed per tenant (/api/public/webhooks/opera/<organizationId>) and verified with an HMAC-SHA256 signing key derived per organisation from a root key held in the server vault. Tenancy is taken from the verified URL path, never from the request body, so a caller holding one property's key cannot sign a payload that writes billing lines against another property. The legacy shared-secret endpoint no longer accepts billing writes. Signature verification is paired with timestamp and nonce checks to reject replayed deliveries.
  • Resource throttling on abusable surfaces. Outbound transactional email is restricted to an explicit template allowlist, attachment links are validated as belonging to the calling account's own storage prefix, free-text fields are length-clamped, and every send is attributed to the authenticated sender and counted against a per-account daily cap. The endpoint cannot be used as an open relay or as an amplification path against third parties.
  • Server-vault credential protection for automation. Scheduled background workers (anomaly scanning, authorization-window settlement) authenticate with a server-only credential read from the managed secret vault at invocation time. The public anon/publishable key is explicitly rejected, and comparisons are constant-time. No automation credential exists in client bundles, source control, or scheduler definitions in plaintext.
  • Enforcement at the network edge. Signature verification, tenant resolution, credential checks, and throttling all execute in the edge runtime that terminates the request, before any database session is opened — a rejected caller never reaches Postgres.
  • Integration token lifecycle. Credentials issued for a shadow pilot are scoped to that pilot and carry a hard 60-day expiry, so a pilot credential cannot persist unmonitored past the validation window. A pilot is terminated at any time by revoking that single credential. Automated rotation on a fixed schedule is a commitment for first paid deployment, not a control in place today.

4. Vulnerability management and continuous monitoring

  • Dependency scanning. Application dependencies are scanned automatically against known CVEs by a continuous-integration job (.github/workflows/dependency-audit.yml) that runs on every push and pull request, on a weekly schedule, and on demand. The job executes scripts/audit-dependencies.mjs against the committed lockfile and fails the build on any high or critical finding, so a vulnerable dependency cannot reach a release unnoticed. Each run publishes a retained JSON report giving an auditable scan history. Findings are triaged on discovery; the affected package is upgraded and the lockfile regenerated before the next deploy.
  • Software Bill of Materials. The same continuous-integration job generates a CycloneDX 1.5 SBOM (scripts/generate-sbom.mjs) from the committed lockfile on every run, listing each dependency's name, resolved version, package URL, distribution artefact hash, and licence where the package declares one. The SBOM is retained alongside the scan report as a build artefact and is supplied to customers, prospects, and reviewers on request; it is not published publicly. It is generated from the lockfile rather than hand-maintained, so it cannot drift from what is actually deployed.
  • Continuous automated code and configuration scanning. An automated scanning platform (Aikido) runs continuously across the codebase and its infrastructure configuration, covering static application security testing (SAST), software composition analysis, secrets detection, and infrastructure-as-code and cloud posture checks. Findings surface to the operator as they are raised and are triaged on discovery. This is automated analysis, not a penetration test: no live target is attacked and no third party attests to the result.
  • Adversary-simulation regression suite. A test suite written from the attacker's perspective runs in continuous integration on every change (src/lib/security/adversary-simulation.test.ts). It comprises 63 tests across five classes — webhook forgery and replay, tenant-identifier manipulation, privilege escalation through server functions, post-authentication open redirect, and credential exposure in the client bundle. Each test asserts that a specific attack fails, so weakening a control breaks the build rather than passing silently. As of 18 August 2026 all 63 pass. The suite covers application-layer gates; database-layer isolation is covered separately by the automated post-migration validation described in §2.
  • Patch management targets. We target production deployment of critical security patches within 48 hours of a fix being available, and remediation of high and medium findings within a 30-day cycle. These are operating targets, not a contractual SLA. A binding patch SLA can be scoped and agreed as part of a commercial agreement.
  • Audit logging. Billing, invoice-usage, and inbound webhook events are written to a central audit_logs store recording actor, action, resource type and identifier, IP address, user agent, and timestamp. The log is append-only in practice: no update or delete path is exposed to any client, authenticated users can read only their own rows, and writes are made server-side only. Extending coverage to authentication attempts and role changes is on the roadmap and is not claimed as a control in place today.
  • Incident response framework. A written incident response plan governs suspected security events, defining severity tiers, the named responder, containment and evidence-preservation steps, recovery, customer communication, and post-incident review. See docs/INCIDENT-RESPONSE-PLAN.md, available to reviewers on request.
  • Breach notification. On confirmation of a personal-data breach affecting a customer, we notify the affected controller without undue delay and, where feasible, within 72 hours of becoming aware, with the facts known at that time. Notification is not withheld pending a complete investigation.

5. Endpoint security and operational governance

Apex Flow Technology Ltd is a single-operator entity. The controls below describe the actual operating practice today; controls that are not yet in place are listed as planned rather than implied.

In place today

  • Full-disk encryption. The development workstation holding local application code uses hardware-backed full-disk encryption (FileVault/BitLocker class), with automatic screen lock.
  • Multi-factor authentication. MFA is enforced on every account that can reach infrastructure, the code repository, the deployment pipeline, and operational communication channels. Authentication is authenticator-app (TOTP) based.
  • Secure credential storage. System passwords, API tokens, and cloud environment secrets are held only in the server-side environment vault and a dedicated encrypted password manager. No credential is committed to source control, pasted into documents, or shared over chat or email.
  • Production / non-production separation. Development and testing use non-production credentials and non-production endpoints. Local development does not target production database configuration, and production deployment is a separate, explicitly authenticated action.
  • Browser hardening headers. Every response leaving the edge worker — pages and API responses alike — carries Content-Security-Policy (with frame-ancestors 'none', object-src 'none', base-uri 'self' and form-action 'self'), Strict-Transport-Security (2 years, subdomains, preload), X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy and Cross-Origin-Opener-Policy. These are applied centrally in the worker entry point, so no route can ship without them.
  • Abuse throttling on unauthenticated endpoints. The public contact, interest and pilot-request endpoints are rate-limited per caller (hashed source address, never a stored IP) using an atomic database counter rather than per-process memory, so the limit holds across concurrent edge isolates. Machine-to-machine billing endpoints remain protected by per-tenant HMAC signatures with replay and timestamp rejection, as described in section 3.

Planned, not yet in place

  • In-product multi-factor authentication for customer accounts. Committed for delivery before the first production pilot goes live, and scoped as part of the pilot agreement. It is not offered today because there are no production tenants yet. The operator-side MFA described above is a separate, already-implemented control.
  • Hardware security keys (FIDO2/WebAuthn) for deployment and provider console access, replacing TOTP as the second factor.
  • Container-sandboxed local development workloads isolating testing from all other local state.
  • Formal mobile device management (MDM) with enforced device policy and remote wipe.

These gaps are a function of company stage. Each is in scope to be closed as part of a commercial engagement and can be prioritised against a customer's procurement requirements.

6. Architecture

  • Edge/application tier — TanStack Start application served from Cloudflare's edge network. Server functions execute in per-request isolates with no long-lived server state between requests.
  • Data tier — managed PostgreSQL (Supabase via Lovable Cloud), provisioned in EU-West (Ireland).
  • Aggregation tier — folio aggregation runs in a stateless handler. Guest PII and transaction lines are held in memory for the life of the request only and are not written to relational tables, cache, or disk.
  • Payments — Stripe-hosted. No card PAN, CVV, or expiry ever reaches Apex Flow systems.

7. Data flows

  PMS / POS  --(read-only, HMAC-signed webhook or pull)-->  Edge handler
                                                              |
                                          in-memory aggregation + validation
                                                              |
                              +-------------------------------+------------------+
                              |                                                  |
                    invoice document returned                       invoice metadata persisted
                    (PDF/A stream to caller)                        (org-scoped, RLS-enforced)
  1. Ingestion is read-only. Nothing is written back to the property management system at any point. A pilot is terminated by revoking a single credential.
  2. Validation. Inbound payloads pass a schema validator that enforces types and UUID formats, strips angle brackets from free-text fields, and caps batch size.
  3. Aggregation. PMS, POS, and corporate-ledger lines are joined in a single request context.
  4. Return and flush. The rendered document is streamed to the caller; the request context is released for garbage collection.

8. What is stored, and what is never stored

Stored (organization-scoped, RLS-enforced): organization and membership records; user account identifiers and authentication metadata; invoice and folio records the customer asks us to keep; corporate account profiles; audit and webhook event logs; website contact and pilot enquiries.

Never stored: card primary account numbers, CVV, or expiry; raw guest PII from aggregation batches beyond the life of the request; credentials belonging to a customer's PMS in plaintext.

9. User access limits

  • Tenancy is expressed by organizations and organization_members. Every tenant-scoped table carries organization_id or user_id.
  • Row Level Security is the isolation boundary. Access is decided in the database, not the application, so a mistaken or compromised client cannot widen its own scope.
  • Policy predicates call SECURITY DEFINER, STABLE, search_path = public gatekeeper functions: is_org_member, is_org_admin, is_hotel_manager, and has_role. They take explicit arguments, return booleans only, and expose no row data.
  • Roles are never stored on profile tables. They live only in user_roles and are read through has_role, which prevents client-side privilege escalation.
  • Default privileges on the public schema have been revoked from anon and authenticated. Every table holds only the commands its own policies permit, for only the roles those policies name. New tables start with zero access until their migration grants it.
  • service_role bypasses RLS and is used exclusively by server-side code after the caller has been verified. It is never exposed to the browser.
  • Membership cannot be self-assigned from a client: organization_members is SELECT-only for authenticated users; writes are service-role.

10. Secrets management

  • API keys, webhook secrets, and provider credentials are held in server-side environment vaults and read inside request handlers only.
  • No secret carries a client-visible (VITE_) prefix; client bundles contain publishable keys only.
  • Webhook authenticity is verified with HMAC-SHA256 against a per-tenant shared secret using a timing-safe comparison, with a short-lived nonce cache to reject replays.

11. Error handling and failure isolation

  • All errors are normalised to safe codes (VALIDATION_FAILED, UNAUTHORIZED, AGGREGATION_FAILED). Raw SQL text, stack frames, and database error strings are not returned to clients.
  • A global error middleware wraps every server function; catastrophic server-render errors are normalised before the response leaves the edge.
  • Logs are scrubbed of personal data before forwarding.
  • Failure isolation: during a shadow pilot the validation layer runs alongside the existing process. The PMS ledger remains authoritative, and a fault in our layer cannot affect the guest path or PMS operations.
  • Duplicate webhook delivery is idempotent; replays do not produce duplicate invoices.

12. Automated security validation

security_validation_report() (service-role only) inspects every table in public and reports: tables without RLS enabled (critical); tables with privileges but no policies (warning); and tables where anon or authenticated hold privileges wider than their policies allow (warning). Runs are written to security_validation_runs with counts, pass/fail, and operator, giving an auditable history. Any critical finding blocks release.

Cadence: after every migration touching public, and before any enterprise security review or pilot go-live.

13. Retention

RecordRetention
Contact and pilot enquiriesUp to 12 months from last contact, then deleted
Pilot accountsDuration of the pilot; deleted or anonymised within 30 days of pilot end
Tokenised card references for incidentals2–4 hours after checkout, then purged
Invoices and folio recordsFor the period the customer requires for tax and accounting
Aggregation batch PIINot retained — request lifetime only

Data subjects may request access, correction, export, deletion, or withdrawal of consent at natromrich@googlemail.com. We aim to respond within 30 days.

14. Sub-processors

Sub-processorPurposeRegion
Cloudflare, Inc.Edge hosting, DNS, TLS terminationGlobal edge
Supabase (via Lovable Cloud)Managed Postgres, authentication, storageEU-West (Ireland)
Stripe Payments Europe, Ltd.Payment processingEU / Global
ResendTransactional email deliveryEU / US

Invoice and account records are stored in a single EU region. Where a sub-processor necessarily processes personal data outside the UK or EEA, the transfer is made under the EU Standard Contractual Clauses, supplemented by the UK International Data Transfer Addendum for UK-originating data. Apex Flow is UK-established and does not self-certify under the EU–US Data Privacy Framework.

15. Inherited infrastructure compliance — and its limits

Our infrastructure providers maintain their own independent assurance programmes:

  • Cloudflare — SOC 2 Type II and ISO 27001 for its platform.
  • Supabase / AWS EU-West (Ireland) — SOC 2 and ISO 27001 for the managed platform and underlying cloud.
  • Stripe — PCI DSS Level 1. No card PAN touches Apex Flow systems.

These certifications cover the providers' platforms. They do not extend to the SwiftInvoicePro application layer, and Apex Flow does not claim them as its own. Apex Flow Technology Ltd is not currently SOC 2, ISO 27001, or PCI DSS certified, and holds no completed third-party penetration test. See the accompanying bridge letter for the plan and trigger for a SOC 2 Type 1 engagement.

16. Incident and vulnerability handling

  • Report a suspected vulnerability or incident to natromrich@googlemail.com. We acknowledge within one business day.
  • Breach notification timing and the incident response framework are set out in Section 4.
  • We do not currently operate a paid bug bounty. Good-faith research is welcome and will not be pursued legally where it avoids service disruption and access to other tenants' data.

17. Known accepted findings

  • enterprise_settings and public_rate_limits have RLS enabled and no policies, and hold no anon/authenticated privileges. This is intentional: both tables are service-role only.
  • The database linter flags the gatekeeper functions as SECURITY DEFINER callable by signed-in users. This is required — RLS policies call them on behalf of the caller. They accept explicit arguments, return booleans only, and expose no row data.

18. Related documents

  • Bridge letter (bootstrapped-vendor transparency statement) — available on request.
  • CAIQ Lite self-assessment responses — available on request under NDA.
  • Art. 28 Data Processing Agreement — available on request.
  • docs/SECURITY-ARCHITECTURE.md — internal architecture register.
  • docs/DATABASE-MIGRATION-STANDARD.md — mandatory structure for new tenant-scoped tables.
  • docs/INCIDENT-RESPONSE-PLAN.md — incident severity tiers, response steps, and notification clock.

Apex Flow Technology Ltd is a private limited company registered in England & Wales. Company No. 17347345. Registered office: 29 Railway Road, Rhoose, Barry, Wales, CF62 3FE.