Security

SiteSquare is operated by SoloFive LLC, a California limited liability company. It holds other companies' insurance documents — that is a liability product, and it is built accordingly. Here is what actually protects your data.

SiteSquare in brief

What it is
SiteSquare tracks certificates of insurance for cities, counties and districts: it reads each certificate, checks it against the agency's contract requirements, and chases renewals.
Who decides compliance
Ordinary code, not AI. AI reads each certificate; code checks it against your requirements, and text inside a document cannot change a result.
Human review
Every certificate is confirmed by a person on your staff before it counts as compliant.
Where data is stored
The application and background worker: Railway, US West (California). The database, including its backups: Neon on AWS, US West (Oregon), us-west-2. Uploaded certificates and documents: Cloudflare R2, Western North America (WNAM). Your documents are not used to train AI models.
Accessibility
Designed to WCAG 2.1 AA, with a published Accessibility Conformance Report.
Who makes it
SoloFive LLC, based in Chino Hills, California.

Tenant isolation at the database, and again in every query

Every table holding your vendors, certificates, documents, templates, reviews and audit history carries an organization id and has PostgreSQL row-level security enabled and forced. The connection is scoped to your organization before any query runs, so a query that forgets its filter returns nothing rather than somebody else's rows — it fails closed. The application connects as a database role that row-level security binds, and refuses to start if it is ever given one that could bypass it. Every query also names your organization explicitly, so isolation never rests on one mechanism alone. Cross-organization checks run in our test suite against a database role configured exactly like production.

A few tables are deliberately outside that policy, and we would rather say so than round the claim up. Each one has to be readable before we know which organization a request belongs to, or exists to answer a question that spans all of them. Support and contact messages can be sent by people who are not signed in, so those rows may have no organization to scope to. Vendor upload links must be resolvable from the token alone — that lookup is by unguessable token, and every action it permits is then re-scoped to the one vendor it names. Membership rows are how we learn which organization you belong to in the first place, and are read by your user id. The email suppression listis deliberately global: a hard bounce or a spam complaint must stop mail everywhere, not only where it happened. The background job queue is claimed by the worker before it knows whose job it is, and the job binds its organization before it reads any of your data. None of these tables holds an insurance document, and none is reachable from a signed-in session without an organization filter in the query.

The AI never decides anything

Extraction is strictly one-way: the model transcribes a certificate to structured data and has no tools, no network, and no authority. Ordinary code then validates that data and scores it against your requirements. Nothing downstream reads free text from a document, so instructions hidden inside an uploaded PDF — a real attack against document-processing systems — cannot influence a compliance decision. We have a test that asserts exactly this.

Your documents are not used to train AI models.

Uploads are treated as hostile

File type is determined by inspecting the bytes, not by trusting a filename or a declared content type. Storage keys are generated server-side and cannot be steered by a filename. Documents live in private storage and are served only through short-lived signed links — there is no public URL for a certificate.

Signs a certificate was edited

When a certificate arrives as a PDF, we inspect the file's structure for signs it was changed after it was created — content edited later, or text laid over the original. Anything found is shown to your reviewer as a flag with its reason, beside the certificate.

These signals are advisory. A flag never approves or turns away a certificate on its own; a person on your team decides, and the terms say the same. A photo of a certificate gets no such check, because a photo has no file history to inspect — when it matters, ask the vendor or their broker for the PDF.

Authentication and access

Sign-in is by emailed magic link, or Google SSO where enabled. A password is optional and additive: you can set one, and nothing stops working if you never do. When you do, we store only a scrypt hash — never the password — and a failed attempt gets one identical refusal whether the address exists, has no password, or has the wrong one, so the refusal cannot be used to enumerate accounts. Setting, changing, resetting or removing a password invalidates every existing session and emails the account; a first set or a reset requires fresh proof (a recent sign-in, or a code emailed to the address on file). Link tokens are stored only as hashes and are single-use. Sessions are HMAC-signed with a sliding window and an absolute expiry. Access is deny-by-default at a single middleware choke point, and every write is checked against your verified role on the server; the browser is never trusted to say what role it has.

An audit log you cannot quietly edit

Consequential actions — a review approval, a compliance decision, a document deletion, a waiver granted — are written to an append-only audit log. Update, delete and truncate are revoked on that table at the database level for the role the application connects as, so no entry can be altered or removed while your account exists, and an entry survives the deletion of the thing it describes: delete a certificate and the record that you deleted it stays.

Append-only is not the same as permanent, so we will be exact about the one thing that ends it. The log is scoped to your organization, and if the account owner deletes the account, it is destroyed along with everything else the organization owns — we do not keep a history of your company after you have told us to delete it. What deliberately outlives the account is a single record that the deletion happened and that any subscription was cancelled; it is kept outside your organization's data precisely so the cascade cannot take it, holds none of your vendors' information, and stores the owner's email address only as a one-way hash. The privacy page lists exactly what that record contains.

Payments

Card details are handled entirely by Stripe on Stripe-hosted pages. We never see, store, or transmit a card number. Subscription state is written only by Stripe's signature-verified webhook — never by anything a browser sends us.

Infrastructure

Traffic is TLS-only with HSTS, a content security policy that admits a script only by a nonce issued for that one response, and strict referrer and content-type headers. Data is encrypted at rest by our database and object-storage providers. Rate limits apply to sign-in, the public vendor portal, and inbound email, and a per-organization daily processing ceiling caps what an abusive sender can cost.

Where your data is stored

Here is where each part of your data lives:

  • The application and background worker: Railway, US West (California).
  • The database, including its backups: Neon on AWS, US West (Oregon), us-west-2.
  • Uploaded certificates and documents: Cloudflare R2, Western North America (WNAM).

The outside services that process data for us — email delivery and certificate reading among them — are named in section 5 of the privacy policy.

For your procurement review

Send security questionnaires, vendor forms and data-protection paperwork to security@sitesquare.app and we will complete them.

Reporting a vulnerability

Email security@sitesquare.app. Please include enough detail to reproduce the issue, and give us a reasonable chance to fix it before publishing. We will acknowledge your report, keep you updated, and credit you if you want the credit. We will not pursue legal action against good-faith research that respects customer data and avoids service degradation. Machine-readable contact details are at /.well-known/security.txt.

Privacy

What we collect and why is on the privacy page; data questions go to privacy@sitesquare.app.

Security · SiteSquare