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.
| Header | Value 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.
- 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.
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.