Skip to main content

Security model

Authentication

Google Firebase Authentication, shared across the Swyftscale product family so one account works in MedJot and ACTrack. Entitlements are per-application and do not carry across.

  • Email and password. Password policy, hashing and credential storage are Firebase's, not ours — we never see or store a password.
  • Self-service password reset by emailed link. The response is identical whether or not the address is registered, so the endpoint cannot be used to enumerate accounts. It is rate limited per client IP.
  • Federated Google sign-in has been removed and will not be reinstated. It could not be made to work in an installed iOS web app.
  • Email verification is required for certain account functions.

Sessions are held by the Firebase SDK in browser storage and refreshed with a refresh token. This is the reason the TLS inspection exemption matters: those tokens are the credential.

Authorisation

Every privileged operation is checked server-side, regardless of what the client believes:

  • Entitlement is re-checked server-side on every AI request and every report-start check. A client cannot grant itself Premium.
  • Attribution — role, sector, entitlement, organisation, region — is derived server-side from the account record and never read from the request body.
  • Administrative functions are server-mediated and gated on a server-verified administrative flag. The browser cannot write privileged fields directly.
  • Organisation membership and manager rights are verified server-side on every organisation endpoint.
  • Every administrative mutation is written to an append-only audit log. Sensitive values are recorded as "changed" rather than copied into the log.

Transport

  • HTTPS only, TCP 443. HTTP/3 advertised over UDP 443.
  • Certificates from Let's Encrypt, rotated roughly every 60 days, chaining to ISRG Root X1.
  • HSTS with a one-year max-age, includeSubDomains and preload.
  • .app is an HSTS-preloaded TLD, so browsers refuse plaintext and refuse to bypass certificate errors. This is a security property, and it is also why interception produces a hard block.

Browser security headers

HeaderPosition
Strict-Transport-Security1 year, includeSubDomains, preload
Content-Security-PolicyDeployed report-only while being validated against real traffic, with violations collected centrally. Directives restrict script, connect, frame, object and base-uri to an explicit allow-list.
frame-ancestorsRestricted to our own origin and the Swyftscale portal
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin
Permissions-PolicyCamera permitted (QR transfer scanning) and payment; geolocation and microphone denied
X-Powered-ByRemoved
info

We describe the CSP accurately: it is report-only pending a clean observation window, then moves to enforcement. Shipping an enforcing CSP blind on a clinical tool that uses the camera, a payment element and a service worker would risk breaking it mid-report for no security gain over a staged rollout.

Application security

  • No clinical data server-side, which removes the entire class of risk associated with a central patient data store. There is no clinical database to breach, exfiltrate or subpoena.
  • PII redaction on the AI path, client-side and again server-side. See Data flows.
  • Closed-catalogue analytics with no free-text field anywhere in the schema, revalidated server-side.
  • Rate limiting on sensitive unauthenticated endpoints, including password reset and device-transfer code generation. The proxy's forwarded client address is honoured so limits key on the real client.
  • Payment card data never reaches us. Stripe-hosted checkout and payment elements; we receive subscription status by signed webhook.
  • Webhook signature verification on all inbound payment events.
  • One-time, short-lived tokens for device transfer (10 minutes, in memory) and organisation invitations (7 days, single use).
  • Ticket access links carry their token in the URL fragment and are sent to the API in a header — never as a query string or path segment, so a working credential is never written to a proxy or server access log.

Anti-abuse

Registration and sign-in are assessed for indicators of fraudulent or disposable accounts, using hashed device and IP signals only — no fingerprinting, no third-party trackers. See Data flows.

No account is suspended by automated decision alone. Flagged accounts are queued for human review, and suspended users retain a session specifically so they can read the recorded reason and appeal to a person.

Client-side storage

Clinical data is in localStorage and IndexedDB on the device, protected by the browser's origin isolation and by the device's own security — screen lock, disk encryption, MDM controls.

This is the correct threat model to apply: on a lost or compromised device, in-progress reports are exposed to whoever holds the device, exactly as with any locally-stored document. It is also why the device policy guidance matters, and why clinicians are instructed to keep patient-identifiable data out of MedJot in the first place.

Clinical working data is cleared when a different user signs in on the same browser.

Availability and updates

  • UK-hosted infrastructure with automated deployment.
  • The app is offline-capable, so a server outage does not stop a clinician documenting a patient — which is an unusual and genuine resilience property for a clinical tool.
  • Updates are delivered as web assets. Users are prompted rather than interrupted, except where a fix must reach everyone at once; in-progress work is preserved either way.

Reporting a vulnerability

Email hello@swyftscale.com with the detail. We will acknowledge, investigate and keep you informed. Please give us a reasonable opportunity to fix an issue before disclosing it publicly.