Written for the person who has to sign off on us.
Your IT reviewer, your CA, or you at 11pm before a renewal. This page states what protects your workspace, what it is enforced by, and — in its own section, not in small print — the controls we do not have yet. Nothing here is a roadmap item written in the present tense.
- Row-level isolation enforced by Postgres
- Argon2id · 15-minute tokens
- Staff access lands in your audit log
- Built for the DPDP Act 2023
- No certifications held
The short version
No — and the honest answer is stronger. One database, org_id on
every tenant row, and Postgres row-level security with FORCE on. The
separation is the database's job, not application code remembering a
WHERE clause.
Two things are, and we will name them. Integration webhook secrets and call recordings. Your leads, contacts, deals, bookings and uploaded documents are not separately encrypted — the protection there is access control, and we would rather say so than imply otherwise.
Yes, through one narrow path, and you see every use of it. No standing access. Every access needs a reason code, is time-boxed, and writes a row into your own audit log that nobody at Saudaflow can edit or delete.
No. No SOC 2, no ISO 27001, no third-party penetration test, no bug bounty. We do not hold certifications we have not earned, and we will not imply we do. Ask us for a specific attestation and you get a yes, a no, or a date.
The separation is the database's job.
Most multi-tenant bugs are the same bug: a query that forgot to filter by customer. We
took that decision away from the code. Every tenant table carries an org_id, has a
row-level security policy attached to it, and has FORCE ROW LEVEL SECURITY
set — which binds the table owner too, not just ordinary roles.
ALTER TABLE leads ENABLE ROW LEVEL SECURITY;
ALTER TABLE leads FORCE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON leads
USING (org_id = NULLIF(current_setting('app.org_id', true), '')::uuid)
WITH CHECK (org_id = NULLIF(current_setting('app.org_id', true), '')::uuid);
- Deny by default
- That
NULLIFis the whole trick. If the tenant context is unset, the policy compares againstNULLand matches nothing — a query that forgot who it was for returns zero rows rather than everyone's. - One way in
- Tenant work runs inside
withOrg(orgId, tx => …), which sets the context for that transaction and nothing wider. A second connection pool that can bypass policy exists only for sign-in, sign-up, refresh and password reset, and the source file says every other use of it is a review finding. - What it is not
- It is one database, not one per customer. An older version of this page's meta description claimed "per-workspace database isolation" and that was wrong. Row-level isolation enforced by Postgres is what we run, and it is the answer we will give on your questionnaire.
Exactly what is encrypted, and what is not.
"AES-256 at rest" is the sentence every CRM prints and almost none of them qualify. Here is ours, subsystem by subsystem. A reviewer who checks will find the page matched the product.
Sealed with AES-256-GCM
- Integration signing secrets. The shared secret a portal like 99acres uses to sign a webhook has to be readable back to verify a delivery, so it is encrypted under a key that lives in the server environment and never in the database. A stolen database dump does not yield a usable secret. Anything that will not decrypt returns nothing and fails verification closed.
- Call recordings — when they are switched on. Each recording gets its own 32-byte key, wrapped under a key derived per recording; the audio is sealed frame by frame with your workspace id, the recording id, the key version and a hash of the file header bound into the authentication tag. A file moved between workspaces fails its tag rather than opening. Not on for anyone. No recording key has been generated for any environment, and there is no telephony account behind it yet — so no workspace has ever made one.
Not separately encrypted
- Your CRM records. Leads, contacts, deals, bookings and the payment ledger are ordinary Postgres columns. There is no column-level encryption anywhere in the schema. What protects them is row-level security, the permission model and the audit log — access control, not cryptography.
- Uploaded files. Documents and cost sheets are written to the application disk in a directory named for your workspace, and every read re-resolves the path and asserts it cannot escape that directory. They are reachable only through a permission-checked download. The bytes themselves are not enciphered.
-
Backups. Nightly
pg_dump, read back withpg_restore --listbefore it counts as a success, hashed with SHA-256, 14 kept. They sit on the same machine as the database, and they are not wrapped in a separate key envelope. Both of those are real limitations and they are listed again below.
In transit
TLS 1.2 or better everywhere, HTTPS only. Checked from outside on 02/09/2026:
app.saudaflow.in negotiates TLS 1.3 with AES-256-GCM.
Passwords
Argon2id, the memory-hard algorithm, never a reversible store. A refresh token is kept only as its SHA-256 hash, so the database holds nothing that can be replayed.
Restores, rehearsed
A restore drill puts the newest dump into a scratch database and queries it through the same tenant-scoped path the product uses. The first one found the dumps restoring into a database where the app role could read nothing. It is wired to repeat weekly, and that is why it exists.
Getting in — and the factor we do not have.
15-minute access tokens
A signed access token lasts fifteen minutes. The signing algorithm is pinned on verification, so a token that claims a different one is rejected rather than trusted.
Refresh that rotates
Each device holds its own refresh token and it is replaced on every use. Present an old
one and it is treated as theft: the whole session family is revoked and
auth.refresh_reuse_detected is written to your audit log.
Throttling that fits an office
Sign-in has its own rate-limit family and its per-IP bucket counts failures only — so thirty telecallers behind one office connection at 09:30 do not lock each other out, while a credential-stuffing run still hits a ceiling.
Phone sign-in, when SMS is live
A phone-and-code door exists and mints the identical session a password does. Our SMS sender registration is not complete, so the deployment refuses to start a challenge it cannot deliver rather than pretending. Password sign-in is what everyone uses today.
There is no two-factor authentication on a workspace account.
No authenticator app, no SMS second step, no recovery codes, and no Settings screen that offers one. Every one-time-password mechanism in our codebase belongs to our own internal staff console, where it is mandatory for our people — it is not wired to customer accounts, and we are not going to describe it as though it were.
What that leaves you today: a unique password per person, the offboarding flow that revokes a leaver's access and reassigns their open book in one action, and an audit log that shows you every sign-in. If two-factor is a hard requirement for your firm, say so on the call — it is a real gap and you should weigh it.
Four dimensions, and masking is one of them.
Permission is not a checkbox per screen. A grant is a module, an action, a data scope and a field-level visibility, and the fourth is the one that matters when a telecaller opens a contact that has a PAN on it.
Leads, contacts, deals, visits, calls, inventory, cost sheets, bookings, payments, commission, documents, approvals, reports, settings, users, audit logs, compliance and more.
View, create, edit, delete, export, approve, reject, assign, reassign, merge, hold, release, publish, import, download and the rest — export is its own action, so seeing a record never implies being able to take it out.
Own, self-created, assignment-based, direct reports, team, territory, branch, project, all accessible projects, zone, all accessible zones, all channels, read-only org, org. A zonal head does not see a peer zone. Scope is applied in the query, not after it.
Visible, read-only, masked, hidden — per field, per role. When a user holds several roles the union takes the widest scope and the most permissive field mode, and that rule is written down in one place.
Masking happens on the server, in the response.
A masked value is not a value with a CSS blur over it. The API returns a label shaped
like the value — ABXXXXX4F for a PAN,
XXXX-XXXX-1234 for an Aadhaar,
••••7890 for a bank account,
₹ •••••• for a commission figure — and the characters it shows
are not the record's characters. Nothing can un-mask it, because the real value never
left the server. One function decides whether a string is a mask, so a masked number can
never quietly become a dialable link, a copy button or a sort key.
Declared per module: PAN, Aadhaar, bank account, IFSC, GSTIN, address, budget, KYC documents, commission amount and percentage, TDS details, payout reference, clawback flags. Thirty-three role templates ship with the product — for the builder chain and the channel-partner side — and every one of them is cloneable, renamable and editable. They are a starting point, never a lock.
What happens when we look at your data.
We will not tell you that Saudaflow staff are cryptographically incapable of reading your data. Under the architecture we actually run, an authorised, policy-gated, audited access path exists — that is how support fixes your workspace at 9pm and how we would answer a lawful order. What we will tell you is that the path is narrow, that nobody stands inside it by default, and that every use of it leaves a row in an audit log you can read without asking us.
-
1
A reason is required before anything is read. The access seam refuses outright if no reason code is chosen, and refuses again if the staff member has no assigned pseudonym. Not a warning — a refusal, before the query.
-
2
The row is written into your audit log, not ours. Actor, what was accessed, why, your ticket reference, the assist session, and the timestamp — in the same transaction as the access itself. A staff row missing the pseudonym or the reason is rejected by a database constraint, so an unexplained access cannot be recorded, which means it cannot happen.
-
3
You never see a name, and that is deliberate. Your copy can only ever read
Saudaflow Support (SF-STAFF-07)— a job category and a stable pseudonym. The column's constraint makes a real name literally unrepresentable. It protects you from being able to enumerate our people and it protects them; the pseudonym resolves to a person only inside our own console, under permission, and that lookup is itself audited. -
4
The session expires on its own. An assist session is time-boxed — thirty minutes by default, and the database will not accept one longer than sixty, whatever anyone types. It is a ceiling in the schema, not a setting in an admin screen.
-
5
We cannot edit or delete your copy of what we did. Update, delete and truncate are revoked from every console role on that table, and three triggers refuse the statement even if a privilege were ever granted by mistake. The record of our access is yours, and it outlives our ability to change it — for at least 180 days, a floor neither you nor we can lower.
Your workspace also carries its own switch for whether staff assistance is permitted at all. Our console reads it and obeys it, and it holds read-only rights on that row — it cannot turn itself back on. The gap today is that there is no screen for you to set it from; it is listed below with the rest of what is missing.
What the log proves, and what it does not.
What it does
- Append-only, by privilege. The application role is granted
SELECTandINSERTon the audit table and nothing else. There is no update path and no delete path for anyone using the product. - Before and after, not just "changed". Every row carries the actor, the action, the entity, the state before, the state after, the IP, the user agent, the request id and the timestamp — so an ownership change, an approval or a discount can be reconstructed, not merely noticed.
- Scoped like everything else. The audit table sits under the same row-level security as your records, so your log is yours and no query can widen it.
What it does not
- It is not WORM storage, and we will not call it that. Our internal staff log is hash-chained and sealed daily. That chain proves a row was altered after the last seal. It proves nothing about the unsealed window, which can be up to twenty-four hours, and someone with root on the server inside that window could still rewrite it. The comment saying exactly this is in the migration, not just on this page.
- It does not prove a row was never written. A separate sequence-gap detector covers that, and it needs no hashing at all. Two different questions, two different mechanisms, and conflating them is how a security page ends up overstating itself.
Built for the DPDP Act 2023 — as behaviour, not a policy page.
Under the Act your firm is the Data Fiduciary for the buyer data you hold, and Saudaflow is your Data Processor. That split decides who answers a data-principal request: you do, and the product is built so you can, without filing a ticket with us.
An opt-out your staff cannot undo
When a buyer opts out themselves, no admin, owner or manager can reverse it. The check is held under a row lock, the attempt is written to the audit log, and only the buyer's own message re-opts them in. Consent is theirs, not the tenant's.
Consent carries its source
Recording an opt-in requires saying where it came from. "They said yes on a call" has to be a logged claim, not an assumption — and anything the system cannot recognise is treated as not consented. When we cannot tell, the answer is no.
Rights, answered where the record is
A workspace admin can find, correct, export and delete a buyer's record directly in the product — which is what answering an access, correction or erasure request actually requires. There is no request queue to wait on.
Two things we are careful not to claim.
There is no data-principal portal and no seven-day clock that we run. A page in the product explains what is held about a buyer and who is responsible for it, and it points them at the builder or brokerage that holds their record — because under the Act that firm is who must answer, and the timelines run against them. We help you answer; we do not answer for you.
Retention is configurable where it is enforced, and nowhere else. Call-recording retention is a per-workspace setting, 30 to 730 days, enforced by a sweep, with a legal hold that beats a pending deletion. There is no org-wide rule that automatically deletes old leads or contacts — you delete records, and we do not quietly expire them for you. Say so on your questionnaire, because it is the true answer.
Everyone else who could touch your data.
This is the complete list of external services the product can reach, taken from the source rather than from memory. Four of the six are not switched on for anybody.
| Service | What it handles | Status |
|---|---|---|
| Our hosting provider | The servers the application and the database run on. | In use |
| Resend | Transactional email — invitations, password resets, notifications. Recipient address and message content. | In use |
| MSG91 | SMS and one-time codes for buyer, partner and staff sign-in. | Dry-run — nothing sent |
| Meta (WhatsApp Cloud API) | WhatsApp conversations and templates. | No credentials |
| Exotel | Click-to-call and call recording. | No account |
| Expo push service | Mobile notifications to the Android field app. | No credentials |
Nothing analytics-shaped inside the workspace
No analytics tag, no error-tracking agent, no session replay, no advertising pixel in
the CRM. You can check it yourself: open app.saudaflow.in, view source,
search for a tag. There is none.
The marketing site is separate, and asks
This website may load Google Analytics if you accept the consent banner. Decline and no analytics script loads at all. Either way it covers page visits here, never anything inside a customer workspace.
Our billing is ours
The payment provider that handles your subscription to us touches your billing details and nothing else. It is not part of the product, it is not on your screens, and no money belonging to your buyers ever moves through Saudaflow.
One correction, before you find it yourself. The sub-processor list in our published Data Processing Agreement is out of date: it names two providers that appear in no code path in the product, and omits the one that actually sends your email. The table above is the accurate list, taken from the source; the DPA is being reissued to match it, and it is where each provider is named in full, hosting included. We would rather tell you than have your reviewer catch the contradiction.
What we do not have.
"Bank-grade" and "military-grade" mean nothing on a questionnaire. This is the boundary of what we will put in writing — every item here is something a competitor's page would leave you to discover in month three.
- No two-factor authentication for your users. No authenticator app, no SMS step, no recovery codes, no screen to enable one.
- No SOC 2 and no ISO 27001. Neither in progress with a date we would print.
- No independent penetration test to show you, and no bug bounty programme.
- No single sign-on. No SAML, no OIDC, no SCIM provisioning from your identity provider.
- No customer-managed keys, and no field-level encryption of CRM data.
- No off-site backup copy. Nightly dumps are verified and hashed, and they live on the same machine as the database.
- No encrypted backup envelope. The dump is not separately enciphered.
- No published status page. There is no uptime host to link you to, so we have removed the link rather than point at one that does not answer.
- No published uptime, recovery-point or recovery-time commitment, and no failover cluster.
- No 24×7 on-call. Support is 09:30–19:00 IST, every day, by email.
- No screen for your staff-assistance switch. The policy row exists and our console obeys it; setting it is a conversation with us until the screen ships.
- No data-principal request portal, and no seven-day response clock operated by us — see the privacy section for what does exist.
If any one of these is a blocker for your firm, it is better that you know it now than after a purchase order. Ask us for a specific attestation and we will tell you whether we have it, when we expect it, or that we do not.
A questionnaire, or a specific question.
Vendor assessment
Send the spreadsheet. We answer questionnaires directly rather than pointing you at a trust-centre portal, and we write "no" in the rows where the answer is no. If you need the Data Processing Agreement signed, ask for it in the same email.
Email support@saudaflow.inSecurity disclosure
Use the same address with Security disclosure in the subject line. We acknowledge every report and we do not threaten good-faith researchers. We are not going to print a response time we have no rota to back — you will hear from a person, not a bot.
Report a vulnerabilityThe ones a reviewer actually asks
Short answers, and where a short answer would be misleading we have given you the long one instead.
Is my data in its own database?
No. It is one database, with an organisation id on every tenant row and a Postgres row-level security policy on every tenant table. Those policies are set to FORCE, so they bind the table's owner as well as ordinary roles, and the deny-by-default guard means an unset tenant context matches nothing rather than everything.
This is a stronger answer than a database per customer, not a weaker one, because the enforcement is in the database rather than in application code that has to remember. A missing filter in our code returns zero rows. It does not return somebody else's leads.
Is my data encrypted at rest?
Two things are, and we will not let that sentence stand for more than it covers. Integration webhook signing secrets are sealed with AES-256-GCM under a key held in the server environment and never in the database. Call recordings are sealed with a key generated per recording, bound to your workspace and that recording — and that subsystem is switched on for nobody today.
Your leads, contacts, deals, bookings, payment ledger and uploaded documents are not separately encrypted. What protects them is row-level security, the permission model, permission-checked file downloads and the audit log. If your policy requires encryption at the column or file level for customer records, we do not meet it today and you should not buy on the assumption that we do.
Can Saudaflow staff read my data?
Yes, through one narrow path, and never silently. Nobody has standing access. An access needs a reason code before the query runs, it is time-boxed to thirty minutes by default with a sixty-minute ceiling enforced by the database, and it writes a row into your own audit log carrying what was accessed, why, your ticket reference and the time.
Your copy names a job category and a pseudonym — "Saudaflow Support (SF-STAFF-07)" — never a person, because a customer being able to enumerate our staff is its own problem. And nobody at Saudaflow can edit or delete your copy: the privileges are revoked and triggers refuse the statement.
Do you support two-factor authentication?
Not for your users. There is no authenticator app, no SMS second step, no recovery codes and no screen offering any of it. Our own internal staff console requires a second factor for our people, but that is a different application and it is not connected to customer sign-in — describing it as though it were would be the kind of claim this page exists to avoid.
What you have today: unique passwords, sign-in throttling that counts failures, fifteen-minute access tokens with rotating refresh and theft detection, an offboarding flow that revokes a leaver in one action, and a sign-in record in the audit log.
Do you have SOC 2, ISO 27001 or a penetration test report?
No, none of the three, and no bug bounty programme either. We are a small team and we would rather spend the year on controls than on an audit of controls we have not finished building. We do not hold certifications we have not earned and we will not imply otherwise on a marketing page.
If your procurement process requires a specific attestation, ask before you spend time on us and you will get a yes, a no, or a date — not a "coming soon".
What happens to my data if I leave?
You take it with you. Export is a first-class permission action across the module registry, so every major record exports to CSV or Excel, and all fifteen reports do too. Leaving is a supported operation, not a retention tactic, and there is no exit fee.
The honest limitation: there is no single button that produces one archive of an entire workspace. You export per object and per report. If you are leaving and want a complete set, tell us and we will make sure you have everything before the account closes.
How do you handle backups, and have you tested a restore?
The database is dumped nightly in the format a selective restore needs. A dump only counts as a success after it has been read back and checked for a plausible object count, its object count compared against the previous good dump, and a SHA-256 written beside it; fourteen are kept and the last good one is never rotated away.
Yes. The rehearsal restores into a scratch database and queries it through the same tenant-scoped path the product uses, then drops it; it is wired to repeat weekly alongside the nightly dump. It is not decoration: the first time it ran it found that every dump taken until then restored into a database where the application role was denied every table. The product would not have come back. The flags were fixed and the drill is what stops the fix rotting. What we do not have is an off-site copy or a separately encrypted dump, and both are listed in the gaps above.
Does Saudaflow hold or move my buyers' money?
No — and this matters for your risk assessment as much as for ours. There is no payment gateway, no collection, no settlement, no escrow and no payout for a tenant's buyers anywhere in the product. Your buyer pays you exactly as they do today, bank to bank, and someone on your team records it.
What Saudaflow holds is the record: the payment plan, the demand schedule, every rupee recorded against it, the RERA advance gate, and the receipts and statements printed from that ledger. The money moves the way it always has. The only payment provider in our stack handles your subscription to us.
Bring the hard questions to the call.
Audit trails, exit terms, what your CA wants to know, whatever this page did not answer. Twenty minutes, straight answers, and a "no" where the answer is no.
Saudaflow is sold through a short call — we set your workspace up with you. No card, no self-serve signup.