Skip to content

Security & privacy

Source material is sensitive. The product assumes it.

This page describes what CaseSignal actually does — the controls that are implemented, the limitations we know about, and the claims we deliberately do not make. It is written to be checked, not to reassure.

Access control

Private workspaces, checked on the server.

Authorization is a property of the data layer, not of the URL. Every path to a record goes through the same check.

Private by default

Every case belongs to exactly one workspace. There is no public case, no shared-by-default state and no discoverable index of cases. A case becomes visible outside the workspace only when someone deliberately publishes an evidence room from it.

Authorization on every read and write

Route protection alone is not access control. Each query and each mutation re-establishes who is asking and which workspace owns the record before it touches data, so a guessed identifier returns nothing rather than someone else’s case.

Roles inside a workspace

Owner, admin, member and viewer are distinct. Destructive operations — deleting a case, deleting every case, changing billing — are restricted to the roles that should hold them.

Analyst decisions are attributed

Review states, status overrides and notes record who made them. A human judgement is stored as a human judgement and is never silently overwritten by a later analysis run.

File storage

Stored records are not addressable without permission.

The original file is often the most sensitive object in a case. It is treated as the most sensitive object in the system.

Files are never publicly addressable

Uploaded records are written to private storage. There is no public bucket URL and no unauthenticated path to a stored file.

Short-lived signed URLs, or an authorized route

Reads are served either through a signed URL with a short expiry or through a streaming route that re-checks workspace membership on every request. A link that leaks after the fact grants nothing on its own.

Local storage mode is private too

When object storage is not configured, files are written to a private directory on the server rather than into the public asset path, and are served through the same authorized route.

Deletion removes the file and its traces

Deleting a source deletes the stored object, its extracted excerpts and every citation that pointed at it. Deleting a case does the same for all of its records.

The ingestion boundary

Where untrusted input becomes trusted data.

Uploads, pasted text and URLs all arrive from outside. Every rejection happens once, at the boundary, so nothing downstream has to re-check it.

Uploads validated on three axes

Extension, declared content type and byte size are all checked before anything is stored, and the extension and content type must resolve to the same known format. Clients that send a generic content type fall back to the extension; a genuine mismatch is rejected with a message that names the problem.

Filenames are sanitized, not escaped

Directory components, traversal sequences, null bytes and control characters are removed rather than encoded, so a stored name can never address a path outside its intended directory. Names are truncated to a fixed length and fall back to a safe default.

URL imports treat every address as hostile

A pasted URL asks the server to make an outbound request, so it is validated first: an allowlist of http and https on standard ports only, with loopback, private, link-local and unique-local ranges blocked — including the cloud metadata address — and encoded forms of those addresses decoded before the range check so that octal, hexadecimal and integer notations cannot slip past.

  • Redirects are followed to a small fixed limit, and every hop is re-validated with the same function.
  • Internal hostname suffixes are refused outright.
  • Response size and request time are both capped.
  • Known limitation: this validates addresses, not DNS answers. A deployment that must also defeat DNS rebinding should route this traffic through an egress proxy.

Fetched HTML is reduced and sanitized

A fetched page is parsed in an isolated context, reduced to its readable article text with section headings intact, and stripped of scripts, embedded frames, event handlers and remote objects before any of it is stored or rendered.

Platform controls

The rest of the surface area.

Limits, headers, signatures, configuration and the record of what happened.

Rate limiting where it costs

Sliding-window limits are applied per identity to analysis requests, uploads, webpage imports, exports, share updates and public evidence-room requests. Exceeding a limit returns a retry-after rather than failing silently or queueing indefinitely.

Content Security Policy and security headers

A restrictive CSP is served on every response: default-src self, object-src none, base-uri self, form-action self and frame-ancestors none, with script, frame and connect sources limited to the specific providers the app uses. Alongside it: X-Content-Type-Options, X-Frame-Options DENY, a strict Referrer-Policy, a Permissions-Policy that disables camera, microphone and geolocation, and HSTS.

Webhook signatures are verified

Inbound webhooks from the authentication and billing providers are verified against their signing secrets on the raw request body before the payload is trusted. An unsigned or mis-signed request is rejected without side effects.

Environment validated at startup

Configuration is parsed against a schema when the process starts. A malformed value fails loudly and immediately rather than producing a half-configured deployment that behaves differently from the one you tested.

Audit logging

Exports, share-link creation and changes, and deletions are written to an audit log with the actor and the affected record. Deletions are recorded before the rows are removed, so the log survives the data it describes.

Deletion controls you can actually reach

Delete an individual source, an entire case, or every case in the workspace from workspace settings. Deletion is a product feature, not a support request.

Sub-processors

Which services this deployment is configured to use.

CaseSignal runs with each of these either configured or absent. Where one is absent, the product falls back to a local equivalent and no data reaches that provider — the table below reflects this deployment as it is built.

External services, their role, and whether they are configured
ServiceRoleIn this deployment
AuthenticationIdentity, sessions and organization membershipA local development session is used and no identity data leaves the deployment.·Not configured
DatabaseCases, excerpts, claims, citations and audit recordsAn embedded database runs in-process and data stays on the machine.·Not configured
File storageStored copies of uploaded recordsFiles are written to a private directory on the server instead.·Not configured
AI providerExtraction, discrepancy analysis and source-backed answersDeterministic local analysis runs instead and no source text is sent anywhere.·Not configured
EmbeddingsSemantic retrieval over case excerptsRetrieval falls back to full-text search only, run inside the database.·Not configured
PaymentsSubscription checkout and billing portalBilling is read-only and no payment data is handled at all.·Not configured

Source material is sent to the configured AI provider only as the specific excerpts an analysis step needs, and only when you run that step. Your records are not used to train models. Full detail is in the privacy policy.

Honesty

What we do not claim.

A security page is only useful if it is also willing to say what is missing.

No compliance certifications

CaseSignal holds no third-party compliance certifications or attestations today. We are not SOC 2 audited, not ISO 27001 certified, and we make no HIPAA or GDPR certification claim. Where you see those acronyms on this site, it is only here, saying we do not have them. If your work requires a certified processor, CaseSignal is not yet the right tool for it.

No determinations of fact

CaseSignal organises and cites records. Its outputs are research assistance, not findings of fact, legal conclusions or determinations about any person or organization. Verify every citation against the underlying record before publication.

No guarantee of extraction accuracy

Extraction quality varies with the document. Scanned pages, poor photographs and unusual layouts produce low-confidence excerpts, which are flagged rather than hidden. The citation is what makes the output checkable; check it against the original before you rely on it.

Known limitations we would rather state than bury

  • URL fetching validates addresses, not DNS answers; DNS rebinding is not defeated by address checks alone.
  • Rate limiting is enforced per instance. A multi-instance deployment should point the limiter at a shared store.
  • Stored files are protected by access control, not by end-to-end encryption. An operator with database and storage access can read case material.

What that means in practice

Treat CaseSignal as a workspace for records you are permitted to hold and analyse, not as a vault for material whose exposure would cause serious harm to a person. If a record set requires certified handling, a signed data-processing agreement, or protection against a compromised operator, use a system built for that obligation.

The acceptable use policy sets out what may not be uploaded or done with the outputs.

Responsible disclosure

Report a vulnerability.

If you have found a security issue in CaseSignal, we want to hear about it before anyone else does.

Where to send it

Contact address not configured

This deployment has not published a contact address. Set NEXT_PUBLIC_CONTACT_EMAIL to make one available here and in the footer. Until then, please reach the operator of this deployment directly.

For anything not security-sensitive, CaseSignal is on X at @KevinMoncla. Please do not post vulnerability details publicly.

What helps

  • A description of the issue and its impact.
  • The steps needed to reproduce it.
  • The affected URL, endpoint or file, if you know it.
  • Whether you have shared it with anyone else.

What we ask

  • Test only against workspaces and data you own.
  • Do not access, modify or retain another user’s case material.
  • Avoid denial-of-service testing and automated scanning at volume.
  • Give us a reasonable window to fix the issue before publishing.

We do not currently operate a paid bug bounty. Reports are read, acknowledged and acted on, and we are glad to credit researchers who ask to be credited.

Private by default · Public only by decision

Read next