Security and Data: The Controls the Code Implements
What Quartyl enforces in code: tenant isolation, roles, TOTP MFA, per-action audit logging, a hash-sealed evidence ledger and short-lived signed links; which answers the deployment decides.
This page lists the controls that exist in the codebase, with enough specificity to be checked. It deliberately does not state hosting region, encryption at rest, backup cadence or certifications: those are deployment and contract decisions, and a product manual that guesses at them is worse than no answer. The formal commitments remain in the privacy policy.
A note on scope. Everything under “What the code enforces” is verifiable in the application. Everything under “Deployment terms, agreed per engagement” is a property of the install you are buying, and must come from the vendor statement and the processing agreement — not from this page.
What the code enforces
Tenant isolation
- Every domain table carries the firm’s
tenant_id, and the service layer filters by it. There is no cross-firm read path: another firm’s members cannot see your studies, uploads, comparables or evidence, and evidence search is firm-scoped. - The tenant-less platform Superadmin is owner-scoped: its reach is the studies it created itself, never another firm’s data. Platform-scoped API keys minted by a Superadmin follow the same rule and expose no firm’s studies or keys.
Authentication and session life
- JWT, HS256. The access token is short-lived — 30 minutes by default
(
ACCESS_TOKEN_EXPIRE_MINUTES), not a day — and refresh rotates the token version, so the used refresh token dies immediately. - Server-side revocation by version. Every token carries a token version
(
tv). A password change, an admin reset, a role change or a revocation bumps the stored version, and every outstanding session for that user stops working at once. Nothing has to wait for a token to lapse. - MFA is TOTP only (RFC 6238): free, offline, standard authenticator apps.
No SMS and no third-party delivery channel, so no SIM-swap surface.
SUPERADMINandFIRM_ADMINare mandated roles — those accounts must enrol and cannot disable it, and authenticated requests from a mandated but unenrolled account are rejected except on the enrolment, profile, refresh and logout paths. The Firm Admin can enforce it firm-wide or per role for Analyst, Manager and Partner. Ten single-use backup recovery codes are issued at enrolment in a 4-4-4 alphabet that excludes ambiguous characters; only a SHA-256 digest of each is stored, and the plaintext is shown exactly once. Verification tolerates one 30-second step of clock drift either side. A lost-device lockout with no codes left resolves only through platform superadmin recovery — secret cleared, password rotated, re-enrolment at the next login. There is no client-side bypass. - Secrets at the account layer. Passwords are bcrypt-hashed; password-reset tokens are stored as SHA-256 digests only — single-use, 15-minute expiry; API keys are stored as digests. No raw secret is stored or logged.
- Consent. Per-user terms acceptance is compared against the deployed terms version at login; a mismatch pauses the session at a re-consent step until the current version is accepted.
Login hardening
- Captcha is a deployment switch. Where the deployment enables Cloudflare
Turnstile it gates the login step and fails closed — a captcha that does
not verify does not log you in, and there is no silent fallback. It is not
always on:
TURNSTILE_ENABLEDdisables verification server-side, and the backend and frontend settings must agree, because a hidden widget against an enforcing backend fails every login while a visible widget against a disabled backend enforces nothing. - Rate limiting. Authentication endpoints are rate-limited, the MFA code step tightest, because 6-digit codes over a 30-second step are brute-forceable. Exceeding the window returns an explicit rate-limit error.
- Anti-enumeration. The password-reset flow replies identically whether or not the account exists, and the login path equalizes timing against a wrong password, so neither endpoint is an account oracle.
Authorization
Five roles in a hierarchy — Analyst, Manager, Partner, Firm Admin, and the
platform-level Superadmin — with per-role action boundaries enforced in the
backend, not in the client. Plan entitlements are a second, independent axis:
require_plan_feature guards every gated endpoint, so a capability is denied at
the API even when a client calls the route directly. The frontend additionally
hides the entry point, so a firm without a feature never sees it; the hiding is
convenience, the backend check is the control.
Files and links
Object access is through presigned, time-limited URLs — 300 seconds by default — for uploads, report downloads, evidence previews and packet exports alike. There is no durable unauthenticated link to a stored file, so an expired link is expected behaviour and a fresh one is requested from the workspace. Every download is logged.
Retention of the working data
One class of object is not permanent by design: the intermediate pipeline dump
(the normalized parquet written after quantitative screening) is purged once the
study’s review point passes the tenant’s retention window — default 7 days,
configurable between 1 and 31. A workbook rebuild attempted after that window
fails with DUMP_EXPIRED rather than quietly producing a partial file. The
study’s settled record is what persists; the working dump is not. See
troubleshooting.
Auditability
Security that cannot be inspected is not security, so each governance action is recorded with actor and timestamp: state transitions, screening overrides, exports, logins, MFA events, and views. The override ledger links each manual override to the machine reasoning it overrode — and the AI step is one pass, not a verdict: its per-company reasoning is stored on the study, and an override with a documented reason supersedes it. The evidence repository seals its ledger with a SHA-256 digest per entry and records the digest of each exported packet, so tampering is detectable rather than merely deniable.
- Audit trails overview — the forensic record: chronology, bottlenecks, rejection logs, access and security logs.
- Evidence repository — the searchable archive: global search, the digital war room, the immutable ledger, audit packets.
What a run sends outside the platform
This is the question an auditor asks, and the code has one answer: the AI
screening steps send inference requests to the model gateway configured for the
deployment, and those requests carry company names and trade descriptions taken
from the uploaded dump. That is the egress surface of a default run. Where the
optional Web Research step is enabled, the run also issues outbound search
queries and fetches pages, through the search provider set by SEARCH_PROVIDER
(DuckDuckGo by default).
- No registry pull, and no site reading by default. No legal-entity registry
record is joined onto a comparable at any point in the run. The one thing that
touches a website is the optional Web Research step — a bounded shortlist of
pages per company — and it runs only where the tenant’s plan holds the
advanced_ai_screeningfeature. Where a screening reason cites a source, it is the text in your workbook; web output appears as labelled findings carrying the URL each one rests on, never as verified facts, and a field with nothing behind it stays blank — blank means not found, not none. - The gateway is a configuration choice. Model slugs and the base URL are deployment settings, and are checked against each other at startup: a slug and a host that disagree log a configuration warning, and then show up as every screening call being rejected. Which provider sits behind that URL is a deployment fact, not a product one.
- Nothing in the codebase trains a model. There is no training pipeline and nothing is telemetry-fed into one. What the provider does with the prompts it receives — retention, reuse, whether your tenancy is excluded from training — is a term of that provider’s contract, and it belongs in your processing agreement. This page will not assert it on the platform’s behalf, because the platform cannot know it.
The free tools on the marketing site (the NIC code finder and the TP questionnaire generator) are static pages that issue no requests: they run in the browser, and nothing typed into them leaves your machine.
Deployment terms, agreed per engagement
The following are not established by this codebase, and this manual does not claim them. Ask for each in the vendor statement and the contract.
| Question | Why the product cannot answer it | What a defensible answer includes |
|---|---|---|
| Where is the data physically hosted, and under which jurisdiction? | Nothing in the code pins a region, and the object store is pluggable — an S3-compatible bucket or a local filesystem. | Named provider, named region, sub-processor list. |
| Is data encrypted at rest, and how? | Application traffic and storage access ride TLS in any sane deployment, and the application hashes its secrets, but disk- or bucket-level encryption is a property of the infrastructure sold to you. | Cipher, key management, who holds the keys. |
| Backup cadence, recovery point, recovery time? | Backups are operated outside the application. | RPO and RTO figures, plus a restore test date. |
| Retention after the study, and destruction at exit? | Only the working dump has a code-enforced window (1–31 days, default 7). The settled record’s retention and its deletion are contract terms. | A retention schedule and a certificate of deletion. |
| Which certifications or assessments does the platform hold? | No attestation is verifiable in code. | The report itself, with its date and scope. |
| What happens to another tenant’s data if a control fails? | Isolation is enforced in code and testable; the residual risk is a security-review question. | Breach notification window, incident history, escalation contact. |
Note that payment rails (card checkout, invoicing) are integrated in the code but are not enabled in every deployment; where they are off, plans are provisioned by the platform team and billing terms come from the agreement rather than a self-serve checkout.
The buyer’s-guide view
This page is the product’s own statement of the controls. The knowledge-side twin, TP software security, frames the same controls for the evaluation — what to ask any vendor, and what a defensible answer looks like.
See it working in your workspace
Sign in to run the steps above on a real study — or book a demo and we will walk the workflow end to end.
Related docs
Frequently Asked Questions
Answers to the questions firms ask before and during adoption: what Quartyl is, tenant isolation, seats, AI overrides, white-label, what leaves the platform, reports and workflow.
Read docChangelog and Release Notes
How you learn what changed in Quartyl: the product publishes no version numbers or dated release history, so this page explains what does signal a change, how deprecation is handled, and where to ask.
Read doc