RealAnalytica
SOC 2 Type 2 Certified

Security and trust

What we do with your CRM, your email, and your MLS data, and how it stays yours.

Brokerages hand this platform their client relationships and their mailbox. This page describes how the system is built, in enough detail that your IT reviewer can check the claims against what the product actually does.

Last updated: August 2026

Accounts and access

How people sign in and what they reach

Authentication runs on Supabase Auth. The web app keeps the session in cookies that the server reads on every request. The iOS and Android apps send a bearer token in the authorization header instead. Both paths end at the same check.

The gate in front of every request asks the auth service to verify the token on the server. A session object decoded in the browser does not get to decide who someone is. If verification fails, the request is unauthenticated and nothing further runs.

Route access is an allowlist. Marketing pages, the login screen, public agent profiles, and a short list of shared links are declared public by name. Everything else requires a verified session, and an unauthenticated request to any of it is sent to the login page. A new page is private until someone adds it to that list on purpose. The match runs on path segments, so a public entry for /research cannot accidentally expose /research-private.

You can sign in with an email and password or with Google. Staff access to a customer account runs through a separate impersonation path. That session is bound to the staff member who opened it and carries an expiry, and the server rechecks both before it honors the session.

Server-verified sessions

The route gate verifies the token with the auth service rather than trusting what the client presents.

Default private

Paths are private unless explicitly listed as public, so a forgotten registration fails closed rather than open.

Data isolation

Your rows are yours

Customer data lives in Postgres with row-level security enabled across the application schema. Row-level security moves the ownership check out of application code and into the database, where it applies to the query itself.

The policies are written against the authenticated user ID. Your contacts, campaigns, tasks, automations, synced messages, and rental records all carry a predicate matching the row's owner to the signed-in user. Child records inherit through their parent, so a presentation block is reachable when the project it belongs to is yours. The predicate is part of the table definition, which means a query that forgets to filter by owner returns nothing instead of returning everything.

Shared brokerage records use a wider predicate of the same shape. Team, office, and organization tables check whether the requesting user holds an active membership, an ownership record, or an active enterprise seat for that organization. A departed team member has their membership end-dated and a deactivated seat stops matching, so access ends when the relationship does.

Two categories are readable more widely, on purpose. MLS and public-record reference data, such as market statistics and sold history, is shared across signed-in agents because it is licensed market data rather than anyone's private records. Research reports we publish are readable by anyone, which is what makes them published. Neither category carries a customer's private pipeline.

Application code scopes each query to the signed-in user as well. Row-level security sits underneath that as an independent check on anything reaching the database directly, including the browser client and realtime subscriptions.

Transport and browser hardening

What every response carries

Security headers are applied in middleware, so they land on every response the application serves rather than on a handful of pages someone remembered to configure. Your reviewer can confirm each of these with a single request against www.realanalytica.com.

One note on the content security policy, because a reviewer will find it anyway. The directives that stop framing, form redirection, base-tag rewriting, and plugin objects are locked down today. The script-source side still permits inline and evaluated script, which is where the application currently is while bundle sources get consolidated. We would rather write that here than let you discover it in a scan.

HeaderValue and effect
Content-Security-Policy

frame-ancestors 'self'; base-uri 'self'; form-action 'self' https:; object-src 'none'

Only our own origin may frame the app. Forms cannot be retargeted at an attacker's endpoint, the document base cannot be rewritten, and plugin objects are blocked outright.

Strict-Transport-Security

max-age=63072000; includeSubDomains

Served on HTTPS responses. Browsers refuse plain HTTP to realanalytica.com and its subdomains for two years after the last visit.

X-Frame-Options

SAMEORIGIN

Clickjacking protection for browsers that predate frame-ancestors.

X-Content-Type-Options

nosniff

Browsers honor the declared content type instead of guessing it from the bytes.

Referrer-Policy

strict-origin-when-cross-origin

Full paths stay inside our origin. Third-party sites you click through to receive the origin alone.

Permissions-Policy

camera=(), microphone=(), geolocation=(), interest-cohort=(), payment=(self)

Camera, microphone, and location are switched off for the whole document. Payment is limited to our own origin.

Cross-Origin-Opener-Policy

same-origin-allow-popups

Cross-origin documents cannot reach into our browsing context. Popups we open ourselves, such as an OAuth consent screen, still work.

Cross-Origin-Resource-Policy

same-site

Other sites cannot pull our resources into their pages.

Third-party integrations

Scoped access to your mailbox and calendar

Connecting Gmail, Outlook, or a calendar runs the provider's own OAuth flow. You approve the grant on Google's or Microsoft's consent screen, and you can revoke it from your account settings there whenever you want. We never ask for or store your email password.

Scopes map to capabilities rather than arriving as one blanket grant. Sending maps to the send scope by itself, which carries no permission to read your mailbox. Calendar sync maps to calendar scopes. Contact import maps to read-only contact access. Below are the mailbox, calendar, and contact scopes we request.

Two things we do not ask for are worth naming. There is no full-mailbox Gmail scope and no Google Drive scope anywhere in the platform. Contact access is read-only on both providers.

Google

  • https://www.googleapis.com/auth/gmail.send
  • https://www.googleapis.com/auth/gmail.readonly
  • https://www.googleapis.com/auth/calendar
  • https://www.googleapis.com/auth/calendar.events
  • https://www.googleapis.com/auth/contacts.readonly
  • https://www.googleapis.com/auth/userinfo.email

Microsoft Graph

  • https://graph.microsoft.com/Mail.Send
  • https://graph.microsoft.com/Mail.Read
  • https://graph.microsoft.com/Calendars.ReadWrite
  • https://graph.microsoft.com/Contacts.Read
  • https://graph.microsoft.com/User.Read
  • offline_access

Tokens encrypted at rest

Access and refresh tokens are encrypted with AES-256 before they are stored, and they are never sent to the browser.

Decryption is fenced in

Only the integration auth module may decrypt a token. A custom lint rule fails the build if any other file reads one directly.

Disconnect purges the data

Disconnecting email drops the mail scopes from the stored grant, turns sending and reading off, and purges the synced mail for that user and provider. A full disconnect deletes the stored credentials outright.

Deleting a user removes the tokens

Stored credentials are tied to the user record with a cascading delete, so removing the account removes them with it.

Calendar survives an email disconnect

Turning off email leaves calendar access intact, so scheduling keeps working while mailbox access ends.

Connect flows carry CSRF state

Each connect request is rate limited and carries a random state token, so a consent callback cannot be replayed at you.

Outbound actions

Atlas agents draft. You approve.

Every capability in the platform is registered with a flag that says whether it needs a permission prompt before it runs. Every outbound capability carries that flag, and agents are created in ask-before-acting mode.

Sending email as you through Gmail or Outlook needs approval per send. Text messages need approval per message. Dispatching a campaign needs approval, and the prompt shows the exact recipient count before you accept. Destructive operations such as deleting contacts follow the same rule and say plainly that the action cannot be undone.

An approval is a durable record, not a passing dialog. It stores the exact arguments that will execute if you accept, so the model does not get to re-enter and change the plan between your click and the send. Resolving one is single-use at the database level, which is what stops a double-click from sending twice. If you edit a draft before approving, the editable fields are content only. The recipient, the linked contact, and the share token are never editable.

Two things are worth stating plainly so nobody is surprised. Scheduled email sequences send on their own timetable once you approve the enrollment, because that is what enrolling someone in a sequence means. And on an individual transaction, the deal owner can switch on auto-execute so future drafted plans run without stopping at each step. Turning that on requires an approval of its own, it applies only to that deal, and it stays off until someone asks for it.

Reading your own data is free. Pure reads are marked read-only and skip the prompt, because a report that pauses to ask permission to show you your own pipeline helps nobody. The prompt exists for writes and for anything that leaves the account.

Independent assurance

SOC 2 Type 2

RealAnalytica holds a SOC 2 Type 2 certification. A Type 2 engagement tests whether controls operated correctly across a window of time, which is a higher bar than a Type 1 report on how the controls are designed on one day.

Our trust center hosts the current status and the report request process. The SOC 2 badge in the footer of every page links there.

Visit the Trust Center

We list the certification we actually hold. If a framework is not named on this page, assume we have not been audited against it, and ask us rather than inferring it.

Policies and reporting

Where to read more and who to tell

Our privacy policy covers what we collect, how long we keep it, who processes it on our behalf, and the rights you can exercise over it. It also states that we do not sell personal information and that data is stored and processed primarily in the United States. Our terms of service set out account responsibilities and the obligations that come with prospecting and outreach data.

For a security question during vendor review, or to report a vulnerability, use our contact form and mark the message as a security report. Give us enough detail to reproduce what you found. We will confirm receipt and work the issue with you. Hold off on public disclosure until we have had a chance to respond.

Brokerages running a formal diligence process can request the SOC 2 report and a security questionnaire review through the same route.

Frequently Asked Questions

Hire your AI workforce

Specialist Atlas agents handle the follow-up, the prospecting, and the routine work. You review, approve, and stay in control.