Subprocessor register version 1.0.0, effective from 2026-10-05.
At rest: third-party API credentials (AI provider keys, data-connector OAuth tokens, SSO and webhook secrets) are sealed with AES-256-GCM under a per-organisation data key, and each data key is itself wrapped by a master key held outside the database. A stolen database dump is not enough to open any of them.
The master key: in production the master key lives in an external key-management service, so the application can ask for a data key to be unwrapped and no human account can. A master key sitting in an environment variable beside the database connection string is the arrangement envelope encryption exists to replace, and the code refuses to start with that configuration in production rather than warning about it.
In transit: this application is designed to run behind HTTPS/TLS. Enforcing that in production (e.g. HSTS, TLS termination, certificate management) is a real deployment/hosting-platform responsibility, not something hard-coded in the application itself — confirm it’s actually configured for any given deployment rather than assuming it.
What this does not mean: at the moment a secret is used, its plaintext is in the memory of the process using it. No design stops someone with root on a running host from reading memory. What this achieves is no standing access — reading a secret requires deliberately compromising the live system, and with a key-management service it leaves an audit record. It never means a database query or a backup is enough.
Bringing your own provider keys only means something if nobody can retrieve them afterwards. There is no read path, and that is a property of the code rather than a policy:
When someone here needs to look at an organisation's account to answer a question, that access is a real, bounded record rather than a shared admin login:
The honest gap: these sessions are currently visible to us and not to you. A customer cannot yet see, in their own account, that a support session was opened against their organisation. That surface is not built, and until it is, this control is auditable internally rather than transparently.
Every third party that receives any of your data, what it receives, and where it is processed. Published as a versioned record so that a change to it is dated rather than discovered.
We give 30 days notice before any addition to this list takes effect. This is version 1.0.0 of the register, effective from 2026-10-05.
| Subprocessor | Purpose | What it receives | Where | Status |
|---|---|---|---|---|
| Stripe | Subscription billing and payment processing | Billing email address, organisation name, the amount and currency of each charge, and the card details the payer enters directly into Stripe's own hosted fields. Card numbers never reach SignalOS. | United States, with EU processing under Stripe's own data-residency terms | In use |
| Resend | Transactional email — verification, invitations, alerts, billing notices | Recipient email address, the subject and body of the message sent, and delivery status | United States | In use |
| Sentry | Application error monitoring | Error messages, stack traces, request paths and user and organisation identifiers. Provider keys and other secrets are wrapped in a type that renders as a mask, with a second scrubbing layer in the Sentry integration itself. | United States or European Union, depending on the configured Sentry region | Configurable, not currently enabled |
| Amazon Web Services — S3 | Object storage for generated reports, data exports and uploaded assets | The contents of generated reports and exports, and any logo or asset an organisation uploads | The AWS region configured in S3_REGION | Configurable, not currently enabled |
| Amazon Web Services — KMS | Wrapping the data keys that encrypt provider credentials and other secrets | Encrypted data keys only. No credential, no customer content and no plaintext secret is ever sent to KMS — it receives a 32-byte key to seal and returns it sealed. | The AWS region configured in KMS_REGION | Configurable, not currently enabled |
Entries marked as configurable are listed because enabling them is a configuration change rather than a code change. A register that named only what is switched on today would be wrong the day one of them is switched on.
You hold the account, the contract and the bill with each AI provider; we hold the key you gave us and call the provider on your behalf. That makes them your processors rather than ours, which is a real difference in who is responsible to you and not a technicality. They are named here anyway, because a subprocessor register that was silent about where the measurement text goes would be hiding the most important answer in it.
No formal, documented incident-response runbook exists in this codebase or organization today — this is a real gap, not a claim of readiness. A real incident-response plan (severity classification, escalation path, customer-notification commitments and timelines) needs to be written and owned by whoever operates this deployment before it can be honestly described here.
No third-party penetration test has been performed on this application. A real cadence commitment (e.g. annually, or before each major enterprise deal) should be set once a real test is scheduled — nothing here should be read as implying one has already happened.
No SOC 2 audit — Type I or Type II — has been performed or started. A real path to SOC 2 Type I readiness looks like:
No timeline is committed here — this is the real, ordered list of what readiness requires, not a date.