Security Overview
Version: v1.5 β 2026-09-30 Effective date: 2026-09-30
Forward-looking statements. Some controls below describe our intended program rather than a completed one β in particular SOC 2 attestation, external penetration testing, the personnel programme (section 8), the restore drill (section 7), periodic vendor re-scoring (section 9), and the automated security-scanning gate (section 6). Each is called out inline as "planned", "not yet", or "in development" at the point it appears, rather than only here. Where a control is gated to a specific tier or feature flag, that is stated inline.
This document is the public-facing description of how Vestibo ("Vestibo") protects customer data. It is the companion document to the technical and organisational measures referenced in Schedule 2 of the Data Processing Addendum.
Our public Trust portal at https://vestibo.com/trust
exposes the live controls inventory, sub-processor list, and SOC 2
status.
1. Architecture and tenancy
- Service model. SaaS, multi-tenant by default; single-tenant and self-hosted options are available for customers with regulatory or sovereignty requirements (single-tenant deployment mode).
- Tenant isolation. Logical tenant isolation is enforced at three
layers of the stack: the ORM (every model carries a
tenant_idcolumn with a foreign-key constraint), the repository layer (every query is scoped through aTenant-aware base), and the HTTP route layer (every endpoint resolves the caller'stenant_idfrom the auth token and refuses cross-tenant access). An automated test suite verifies this end-to-end. Those tests are run before a change merges; they are not currently enforced by an automated CI gate β see section 6. - Hosting region. Primary infrastructure runs on AWS in
us-east-1. Single-tenant customers can pin to a specific AWS region. Sub-processors run in the regions documented inSUBPROCESSORS.md.
2. Compliance posture
| Programme | Status |
|---|---|
| SOC 2 Type II | In progress β not yet attested. A controls inventory is published in the Trust portal; no audit or attestation report exists yet, and we have not committed to a target attestation date. |
| HIPAA / BAA | Available on the HIPAA-eligible tier (off by default). BAA template at BAA_TEMPLATE.md. The PHI redaction pipeline is active when that tier is enabled. |
| GDPR / UK GDPR / Swiss FADP | DPA available at DATA_PROCESSING_ADDENDUM.md, including EU SCCs Module 2 and UK Addendum. |
| CCPA / CPRA | Privacy notice and data-subject-request flow live; we do not sell or share for behavioural advertising. |
| ISO/IEC 27001 | Not in scope for now; expected to be reassessed after SOC 2. |
| PCI DSS | Out of scope. We never store cardholder data; payments are tokenised via Stripe. |
| DPF (EU-US Data Privacy Framework) | We rely on DPF-certified sub-processors (e.g. AWS) for onward transfers; Vestibo does not itself self-certify under the DPF. |
3. Access control
- Customer authentication. Magic-link email login (default) plus TOTP-based MFA available on every account.
- Customer authorisation. Role-based access at the dashboard layer (Owner, Admin, Manager, Staff). API keys can be issued with scoped permissions and revoked at any time.
- Internal access. Vestibo is a three-founder company with no employees today. Access to the production cloud account is limited to the founders, is denied without multi-factor authentication at the account level, and is logged. The in-product operator console is restricted to platform-operator accounts, and sensitive operator actions are recorded in the tamper-evident audit ledger described in section 5. TOTP-based MFA for operator accounts is enforced: an operator without a confirmed second factor is refused every operator surface. It was switched on once every operator account had completed enrolment. There is no employee SSO estate, no hardware-token fleet and no just-in-time approval workflow β there is nobody yet to provision one for; each becomes applicable at the first hire.
- Access review. An access-review classifier is implemented and is run on demand. It is not yet on an enforced quarterly schedule, and the row-level review it produces is not persisted as a stored snapshot.
- Privileged access. Database superuser, KMS administrator, and cloud-account root are limited to a documented short list and used only via break-glass procedures with audit logging.
- Session lifetime. The session token (a JWT) is valid for seven (7) days; its httpOnly cookie is cleared after thirty (30) days at the latest, and the token is revoked server-side on logout.
4. Encryption
- In transit. TLS 1.2+ for every external connection; TLS 1.3 preferred. HSTS enabled on every public host. Strong cipher suites only; we run our endpoints through Mozilla's intermediate cipher profile.
- At rest (storage layer). The application database and its backups are encrypted at the AWS storage layer (RDS) with AES-256, using AWS KMS-managed keys. A compliance evidence bucket is also provisioned; it is encrypted at rest with S3-managed AES-256 keys (SSE-S3) rather than KMS, and no customer content is written to it today.
- Customer-supplied secrets (application layer). API keys, OAuth tokens, and other credentials the customer connects are encrypted with an application-layer Fernet envelope (AES-128-CBC + HMAC-SHA-256) before being persisted, so a database leak alone does not yield usable secrets.
- Key management. Master keys live in AWS KMS, where automatic key rotation is available. The application-layer key can be rotated on demand via an operational runbook.
5. Audit logging
Security- and compliance-relevant actions emit a structured audit
event recording the actor (user or system), tenant, action/route,
status, and request ID, with before/after values included in the
event description where material. The append-only ledger is hash-chained with a keyed
HMAC (HMAC-SHA-256) so that tampering is detectable; on PostgreSQL a
database trigger additionally rejects UPDATE and DELETE on the
ledger, so append-only is enforced by the database and not by
application code alone. (Coverage is being extended toward every
state-changing endpoint.)
Retention. Audit records are currently retained indefinitely. The immutability controls above are the reason: a record cannot be edited or removed once written, and no expiry process runs today. Our retention period is seven (7) years β one (1) year in primary storage followed by six (6) years in encrypted, checksum-verified cold storage. The mechanism that enforces it is built but is not yet switched on, so in practice records are currently kept longer than seven years rather than deleted early. We will update this section when it is live.
We chose seven years rather than the shortest defensible period. Documentation required under the HIPAA Security Rule must be kept for six years, and while it is not settled that a security audit log is that documentation, we would rather sit above the benchmark than argue about it β a record we destroyed early cannot be recovered by winning the argument. Seven years also matches the period we apply to our other long-lived compliance records, so one figure governs all of them. An earlier version of this section named a four-year target; it has been corrected upward, and no record was deleted under it, because nothing has ever expired.
We process audit records on the basis of our legitimate interest in the security, integrity and abuse-prevention of the Service, and where applicable to meet legal and contractual audit obligations (including under a Business Associate Agreement). The ledger is deliberately decoupled from account data and therefore survives account deletion β see "Deletion and the audit ledger" below.
Deletion and the audit ledger. When an account is erased, the ledger keeps only the tenant and actor identifiers. Those are opaque UUIDs whose underlying records the erasure removes, so they cease to identify anyone once the account is gone. Records written before 10 August 2026 may additionally contain an email address inside the free-text event description; those cannot be edited out without breaking the tamper-evidence the ledger exists to provide, and are instead bounded by the seven-year retention period above β including in the archived copy, which holds them verbatim for the remainder of that period rather than in a redacted form. New records do not contain contact details, and an automated check enforces that.
Export. Customer-facing export of the audit ledger is on our
roadmap and is not available today; streaming to an external SIEM
(for example via webhook) is likewise planned. The activity log in
your dashboard (Settings β Audit log, owner and admin roles only) is
a read-only view of recorded account activity β it is not an export,
and it is not the hash-chained ledger described above. Those activity
records are included in the self-service data export an account
owner can request (as notifications.json); it is the tamper-evident
ledger itself that has no customer-facing export. Platform
administrators can review and integrity-verify the ledger internally,
and we can produce your records on request.
6. Vulnerability management
- Tooling. Our repository defines static-analysis jobs (Ruff, Bandit, ESLint, TypeScript strict mode, and a custom Walker that asserts zero dead buttons on every public route), dependency- and secret-scanning jobs (pip-audit, npm audit, Trivy for the container image, Gitleaks), and schema-fuzzing jobs (Schemathesis contract tests over HTTP endpoints).
- How those jobs run today. They are currently disabled in our hosted CI and do not run automatically, so no finding blocks a merge today. Linting, type checks and the test suite are run before a change merges; the dependency, container-image and secret scanners are not running on a schedule at present. We will update this section when the automated gate is restored.
- Change review. Every change lands through a pull request that records its rationale. We are a small team and do not today enforce an independent second-reviewer gate on every pull request; adding that gate is planned.
- Penetration testing (planned). We intend to commission an external, independent penetration test before general availability, and at least annually and on material architectural change thereafter. No external penetration test has been completed yet.
- Vulnerability disclosure. Public researcher programme at
VULNERABILITY_DISCLOSURE.md.
7. Backups, recovery, and resilience
- Backups. Encrypted automated backups with point-in-time recovery for the primary database, retained fourteen (14) days. A cross-region disaster-recovery replica and weekly restore-integrity checks are on our roadmap.
- High availability. The primary database runs as a Multi-AZ deployment: a synchronous standby in a second availability zone, with automatic failover. This protects against the loss of an availability zone or of the database host. It does not undo an erroneous change to the data; point-in-time recovery does that.
- Restore drill. We intend to rehearse a full restore from a backup snapshot at least every six (6) months and log the result in the Trust portal. No restore drill has been completed yet.
- RPO / RTO targets. Target RPO β€ 1 hour; target RTO β€ 4 hours.
- Availability. See
SLA.mdfor the contractual uptime commitment and credits.
8. Personnel security
Vestibo is three founders with no employees today. The measures below are the programme that applies from our first hire; because there is currently nobody to whom they apply, none of them is operating yet, and there are no training or background-check records to produce. We will update this section when that changes.
- Background checks where permitted by law, for personnel with access to Customer Data.
- Confidentiality agreements for every employee and contractor.
- Annual security and privacy training, with role-based extensions for engineering, support, and sales.
- Off-boarding revoking every access within twenty-four (24) hours of separation.
9. Vendor management
- Selection. Sub-processors are assessed before engagement against a documented standard (SOC 2 report, HIPAA BAA where needed, DPA, security questionnaire).
- Disclosure. The live sub-processor list is published at
SUBPROCESSORS.mdand mirrored at/legal/subprocessorson the marketing site; customers are notified of additions per the DPA. - Periodic re-scoring β built, not yet in service. A vendor risk-scoring and review queue is implemented, but it ships behind the HIPAA tier (off by default) and the vendor register has not been populated, so no annual re-scoring cycle is running today. We will update this section when it is.
10. Browser Agent sandbox (planned)
The Browser Agent is an experimental capability, off by default and not yet available in production. As designed, it will run in an isolated sandbox with an allowlist of hosts the customer has explicitly approved β refusing and logging any off-allowlist navigation, isolating credentials per customer, and destroying the sandbox after each session. These egress controls describe the intended design; the production sandbox backend has not shipped yet.
11. Voice runtime security
On the default telephony path, live calls are handled through Twilio, including Twilio's speech recognition on the call fallback; Twilio is the voice sub-processor on that path. Deployments that enable the self-hosted voice runtime process speech-to-text and text-to-speech on our own infrastructure (self-hosted STT with Nemotron and TTS with Kokoro / Chatterbox), with no third-party voice sub-processor. Third-party STT/TTS providers (e.g. Deepgram, OpenAI Realtime, ElevenLabs) are optional and used only where a deployment explicitly configures them and the relevant BAA is in place. Full live-call audio is not recorded by default. Where the voicemail / message-capture path is enabled, the recorded message is Twilio-hosted, encrypted at rest, and deleted after ninety (90) days; text transcripts of conversations are stored. Recording behaviour is configured at the deployment level.
12. Incident response
- Alerting is automated: CloudWatch alarms publish to an internal alert topic that notifies the founding team by email, and a founder triages. We do not operate a 24Γ7 on-call rotation or a paging service today.
- Documented per-failure-mode runbooks are maintained internally.
- Defined incident severities (SEV1βSEV4) and response targets.
- Customer-affecting incidents posted to
https://vestibo.com/status. - Personal data breaches notified to affected customers within forty-eight (48) hours of awareness per the DPA.
- Post-incident review within ten (10) business days of resolution.
13. Customer responsibilities
Some security controls are shared between Vestibo and the customer. You are responsible for:
- protecting your dashboard credentials and enabling MFA;
- configuring guardrails appropriate to your use case;
- collecting any consents and providing any AI / recording disclosures required by law in your jurisdiction;
- reviewing the suggested-improvements and escalation queues;
- not uploading PHI without a BAA in place;
- securing the third-party integrations you connect (Google, Acuity, HubSpot, Salesforce, etc.);
- reviewing your audit log and revoking access promptly when personnel change.
14. Reporting a security issue
See VULNERABILITY_DISCLOSURE.md.
Urgent: security@vestibo.com.
Changelog
- v1.5 (2026-09-30) β Β§7 (Backups, recovery, and resilience). Point-in-time recovery for the primary database is now retained fourteen (14) days instead of seven (7). The database now runs as a Multi-AZ deployment, a synchronous standby in a second availability zone with automatic failover, instead of in a single availability zone. Β§7 still states that no restore drill has been completed, because none has. Like v1.4, this change is more favourable to us than the text it replaces. It describes the production configuration from the date of this version, and v1.4 stands unedited as the accurate description of the period before it.
- v1.4 (2026-08-25) β Β§3 (Internal access), superseding the v1.3 entry below on the same day. Operator-console MFA is no longer "staged behind a deployment flag that is not yet switched on":
MFA_REQUIRED_FOR_OPERATORSwas switched on in production on 2026-08-25, after every operator account had completed TOTP enrolment, and an operator without a confirmed second factor is now refused every operator surface. The Β§3 bullet states this. Unlike the corrections above, this one is MORE favourable to us than the text it replaces, so it is recorded here with the date it became true rather than presented as though it had always been the case β v1.3 stands unedited as the accurate description of the ten days before it. - v1.3 (2026-08-25) β Β§3 (Internal access), one correction. "Production access is limited to the founders, requires multi-factor authentication, and is logged" bundled two access surfaces. It is true of the production cloud account, whose IAM policy denies everything without MFA. It was not true of the in-product operator console: MFA enforcement for operator accounts is built and staged behind a deployment flag that is not yet switched on. The bullet now states each surface separately and discloses the console's enforcement status. This replaces a claim more favourable to us than the truth, so it takes effect immediately.
- v1.2 (2026-08-18) β a second correction pass the same day, over the sections v1.1 did not touch. Sections 1 and 6 no longer state that tests and scanners run on every CI build β every CI workflow is disabled, so nothing blocks a merge; section 6 no longer claims an independent second-reviewer gate, which branch protection cannot enforce on this plan. Section 12 no longer claims a 24Γ7 on-call rotation. Sections 3 and 8 no longer describe an operating employee security programme β the entity is three founders with no employees β and section 3 no longer claims a scheduled quarterly access review. Section 7 records that no restore drill has been completed and that the database is single-AZ; section 9 records that the vendor re-scoring queue is built but not in service; section 4 no longer says no object storage is in use, nor promises future object storage will be KMS-encrypted (the evidence bucket that exists uses SSE-S3). Section 12's severity range is corrected to SEV1βSEV4, which is what the SLA actually defines β SEV5 was defined nowhere. Every change replaces a claim more favourable to us than the truth, so it takes effect immediately.
- v1.1 (2026-08-18) β Β§5 (Audit logging), three changes.
(a) The retention period moved from a four-year target to seven years
(1 primary + 6 cold). Β§5 had published four while
docs/v10/DATA_ARCHITECTURE.mdsaid seven; resolved upward, because only the shorter figure could destroy a record early and nothing had ever expired under it. The stated basis is deliberately hedged: HIPAA's six-year documentation period is a benchmark we choose to sit above, not an obligation we assert applies to an audit log β Β§164.316(b)(2)(i) attaches to Β§164.316(b)(1) documentation, and Β§164.312(b) audit controls sets no retention period at all. (b) The Β§5 text corrected by PR #269 on 2026-08-10 β retention is indefinite today, the tiering is not enforced, the database trigger is described, and customer audit-log export does not exist β reaches customers for the first time here. That correction only ever landed in the archival copy; the served copy at/legal/securitykept telling readers records "are intended to be retained for one (1) year in primary storage and three (3) more years in cold storage", the exact wish #269 was written to retract. (c) The pre-10-August-2026 free-text addresses are now described as bounded by the retention period including in the archived copy, which holds them verbatim rather than redacted. Effective immediately: (a) lengthens a retention period rather than shortening one, and (b) and (c) replace claims that were more favourable to us than the truth, so no reader is disadvantaged by the correction taking effect at once. - v1.0 (2026-07-23) β first published version; rebranded to Vestibo and reconciled to the current product.
- v0.1 (2026-05-16) β initial internal draft.