SiteAnchor
Trust & Security

Security at SiteAnchor

SiteAnchor is built to handle sensitive business, financial, and customer data for construction and service companies. Security isn’t an add-on. It’s built into the platform at every layer, from login to database to payment processing.

Below is a full breakdown of how we protect your data — no vague assurances, just the actual controls.

Required

Multi-factor auth on every login surface

AES-256-GCM

Encryption for all stored third-party credentials

~230

API routes with full audit logging

Zero

Card numbers ever stored on our servers

Authentication & Access Control

Getting into an account takes more than a stolen password.

Mandatory multi-factor authentication (MFA)
TOTP-based (RFC 6238, SHA-1, 6-digit codes, 30-second window) via standard otpauth support, with QR-code enrollment and backup codes. Enforced across all three login surfaces: the staff app, the customer portal, and the subcontractor/collaborator portal. Pending MFA sessions are rate-limited to 5 attempts.
Password security
Passwords are hashed with bcrypt (cost factor 10). We never store passwords in plaintext or in a reversible format.
Role-based access control (RBAC)
Permissions are enforced server-side on every API call, not just hidden in the UI. This is audited across the full API surface.
Bot and abuse protection
Cloudflare Turnstile CAPTCHA runs on every login, signup, and forgot-password form.
Secure sessions
Session cookies are paired with device tracking. MFA-pending state lives in a short-lived, signed JWT with a 10-minute TTL, so an intercepted token can't be replayed after that window.

Encryption

Your data is protected both at rest and in transit.

Credentials encrypted at rest
All third-party credentials, including Stripe keys, QuickBooks OAuth tokens, and Google Reviews tokens, are encrypted with AES-256-GCM using a dedicated encryption key that's separate from the session-signing secret. This means a leaked session secret alone can't be used to decrypt stored credentials. This separation was built specifically to satisfy Intuit's QuickBooks App Store security review.
Encryption in transit
TLS is enforced everywhere via HSTS, with preload and includeSubDomains enabled and a 2-year max-age.
Verified webhooks
All incoming Stripe billing events are signature-verified. Forged webhook calls are rejected before they ever reach application logic.

Application-Layer Hardening

The browser, the cache, and the upload form are all locked down too.

Content Security Policy (CSP)
Applied on every route, with explicit allowlists for scripts, styles, images, connections, and frames. No wildcard sources. Paired with X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, and Referrer-Policy: strict-origin-when-cross-origin.
No-store caching on sensitive routes
Every authenticated route, including the app shell, portals, and all API routes, is served with no-store headers, so browsers and shared caches never retain company data after logout.
True file validation
Uploads are validated by sniffing the actual file content (magic bytes) server-side, not by trusting the client-supplied MIME type or file extension.
Signed file URLs
Private files like plans and signed documents are served through signed, time-limited URLs rather than public or guessable paths.
Rate limiting
A Postgres-backed rate limiter is applied at the login, signup, e-signature, and contact-form layer to blunt credential-stuffing and abuse.

Monitoring & Audit

If something happens in your account, there's a record of who did it.

Full audit logging
Every sensitive action across roughly 230 API routes is logged with actor, IP address, category, and entity. Logs support CSV export and follow a defined retention policy.
Error monitoring
Sentry runs on both client and server, with source-map-aware stack traces for fast, accurate debugging.
Live abuse visibility
An admin-facing rate-limit dashboard gives real-time insight into abuse attempts.

Data Privacy & Isolation

Your company's data stays your company's data.

Multi-tenant isolation
Every data model is scoped to companyId at the query layer, enforcing tenant isolation at the source rather than relying on the application layer alone.
Self-serve data export
Company admins can export their own data at any time.
Environment separation
Production databases and secrets are fully isolated from development and preview environments.
PII scrubbing
A past internal audit identified and fixed an MFA-secret leak in an API response. Sanitization is now centralized through a single sanitizeCustomer() function rather than handled per-endpoint, closing off that class of bug going forward.

Payment Security

We deliberately keep ourselves out of the payment path.

No card data touches our servers
Stripe Elements and Stripe Checkout handle all PCI scope entirely client-side, directly with Stripe.
Stripe Connect for payouts
Subcontractor and vendor payouts run through Stripe Connect, keeping payout credentials out of our database entirely.

Questions about our security practices?

If you need documentation for your own review process — a vendor security questionnaire, an insurance requirement, or a client’s IT team — reach out and we’re happy to help.

Last reviewed: August 16, 2026 · See also our Privacy Policy and Terms of Use.