Security
Security
Synaptiq Health AI is a read-only review layer over medical records. This page describes how access to those records is controlled, how to report a vulnerability, and which controls are not in place yet. The last of those is the part most worth reading.
Current scope: synthetic records only
The deployed environment holds synthetic records only and is not approved to hold protected health information. It is a demonstration and evaluation environment, documented internally as never promotable to real patient data. A production environment for real records would be a separate build, on infrastructure covered by the agreements named at the end of this page — not this one reconfigured. Please do not send us real patient data.
Three gates before any chart opens
An account cannot sign in until an administrator approves it, and public email domains are rejected at signup. Approval alone is not enough to read a chart. Every chart additionally requires an approved access request for that specific patient, which the patient can approve, deny, or revoke from their own portal; revoking blocks access immediately and is distinct from denying a request that was never approved. And separately, the clinician's organization must hold visibility of that patient, which is granted when an access request is approved. Both of those last two are checked independently on every chart view, every question asked of a chart, and every read of a chart's access history.
Credentials and transport
Passwords are hashed with PBKDF2-HMAC-SHA256 at 210,000 iterations with a per-user random salt, never stored or logged in any recoverable form. All traffic is served over TLS. Signing in requires a verified email address: registration sends a single-use link, valid for twenty-four hours, and the link's token is stored only as a SHA-256 hash. Browser credentials use script-inaccessible cookies backed by revocable server-side sessions. Access tokens last no more than fifteen minutes; refresh credentials rotate after one use and cannot extend a session beyond twelve hours.
Lockout and password recovery
Repeated failed sign-in attempts lock an account temporarily, counted per account rather than per network address, so an attempt spread across many addresses is still stopped. The check runs before the password is ever compared, so a locked account cannot be used to burn server time. Failed sign-ins are written to the audit trail. Users can reset their own password through a single-use link valid for sixty minutes; a reset request is answered identically whether or not an account exists, so it cannot be used to discover who has one.
Separate administrative authentication
The administrator console authenticates separately from physician and patient login, over its own scheme, and repeated failed attempts are throttled per source address. Successful administrative use is never throttled, so an operator working normally is not rate-limited by their own activity. Administrators hold individual accounts rather than a shared one, so every administrative action in the audit trail names the person who performed it as well as the person it concerned. Revoking an administrator's access revokes its sessions and partial authentication challenges immediately.
Authenticator MFA capability
Physician and administrator accounts support time-based authenticator codes and one-use recovery codes. When deployment-wide MFA is required, accepting a password creates no usable session; every protected request also checks that the server-side session completed MFA. The public synthetic-data demo currently runs with this control disabled so demonstrations do not depend on an authenticator held by one operator. The capability is implemented and tested, but it must not be mistaken for an actively enforced control on that demo deployment.
An audit trail that outlives the account
Logins and blocked logins, account approvals, denials, suspensions and deletions, access requests, patient approvals, denials and revocations, chart views, and chart questions are all recorded. Audit rows deliberately survive deletion of the account they reference, because a trail that disappears when an account is removed is not a trail. The administrator view filters free-text question and access-reason content out of its responses.
Rate limiting on every unauthenticated path
Sign-in, account registration, access requests, the contact form, email verification and resend, the public demo, and external registry lookups each carry their own limit, applied at the endpoint rather than in shared middleware so the policy protecting a route is visible at that route. Refusals return a standard response with a retry interval.
Logs written not to contain records
Application logs are structured, and the fields they may contain are allow-listed rather than filtered after the fact. They never record a question, an answer, chart content, a credential, or an exception body, and request paths are logged as route templates so a patient identifier does not appear in a log line. A scrubbing filter backs this up, but the rule is that such values never reach a log call at all.
Configuration that refuses to start when wrong
Deployments reject placeholder or weak secrets at startup rather than booting with them, and report every problem at once instead of one per attempt. The record source is validated the same way: selecting a source that is not implemented makes the application refuse to start rather than quietly falling back to a different one, so a deployment can never believe it is reading one source while serving another.
Dependency and code review
Every change runs through continuous integration: linting, type checking, the test suite against a real database, a dependency audit across both Python and JavaScript packages, and a check that no deployment secret has been committed. Dependency updates are raised automatically and reviewed rather than merged blindly.
Report suspected vulnerabilities to security@synaptiqhealth.ai, or through the contact form if email is not available to you. These are the same two channels published in our security.txt.
Please include the affected URL or endpoint, what you did, what happened, and anything needed to reproduce it. We will acknowledge reports and keep you informed while we investigate. We ask that you give us a reasonable opportunity to remediate before disclosing publicly, and that testing stays within your own accounts and data: no denial-of-service, no automated scanning that degrades the service for others, no social engineering of our staff or users, and no access to an account or record that is not yours.
We do not operate a paid bug-bounty programme, and we have not published a response-time commitment. We would rather say that plainly than imply a process we do not yet run. Reports are read by the people who build the product.