Privacy Posture
Updated May 17 2026
This document is the operational complement to our privacy policy. The privacy policy says what we MAY legally do with data; this page says what we ACTUALLY do, what tooling enforces it, and how we would answer did Amargi staff look at my data with specifics. It is published, customer-readable, and binding on us. If we ever deviate from a commitment here, the deviation is a P0: we fix it, log it, and tell affected customers.
TL;DR
We do NOT browse customer message contents. The platform admin panel shows only counts and metadata. There is no view this message button. Operator access to message bodies happens only when an audit record explains why: abuse investigation, customer-opened support ticket, or lawful order. Every such access is logged. We do NOT sell data, do NOT share it with third parties for advertising, and do NOT train models on customer messages or on end-customer messages.
Authentication architecture (Amargi Workspace SSO)
Amargi is a product family (Reach, Mail, Agents, Meet, Escalate). All products share a single identity provider called Amargi Workspace for sign-in. Workspace stores ONLY: Account credentials (email, password hash, 2FA secrets), Active sessions and refresh tokens, Organization membership and roles (who can see what inside each product). Workspace does NOT store any WhatsApp message data, contact lists, or any content governed by Meta Business Solution Provider (BSP) terms. All of that is owned and processed exclusively by Reach. The boundary is clean by data type. Lives in Workspace: Account identity (email, password hash, 2FA), Sessions and refresh tokens, Org membership and roles, Workspace metadata, Cross-product navigation. Lives in Reach: WhatsApp Business Accounts (WABAs), Phone numbers and quality ratings, message tiers, Templates, campaigns, audiences, Conversations, messages, contacts, consent records, Webhook subscriptions, outbound delivery state. This pattern mirrors Twilio, MessageBird, 360dialog, and Infobip: the verified Meta Business entity is the same regardless of which product the customer uses. Workspace is NOT a subprocessor and NOT a third party; it is an internal authentication service operated by Amargi Creative, same legal entity, same hosting, same compliance perimeter.
What an Amargi operator can see
The Amargi platform admin panel (route group platform, gated on the platform_admin JWT claim) exposes the following per customer organization: /platform shows org count, user count, WABA count, MRR, aggregate message counts (last 7 or 30 days), outbox and webhook delivery stats. /platform/orgs shows org name, slug, plan, user count, WABA count, message count last 30 days, created date. /platform/orgs/{id} shows the above plus users with role and last-login, WABAs with provider id, region, verification status, phone-number count, usage and cost rollups, suspend and unsuspend controls. /platform/users shows email, name, verified flag, 2FA flag, platform-admin flag, org count, last-login timestamp. /platform/wabas shows provider WABA id, owning org, region, verification, active flag, phone-number count. /platform/phone-numbers shows E.164, display name, owning org, status, quality rating, MPS throughput, filterable by quality. /platform/templates shows template name, owning org, language, category, status, status reason. /platform/campaigns shows campaign name, owning org, status, queued, sent, delivered, and failed counts. /platform/health shows outbox counters, webhook counters, phone-number quality details.
What an Amargi operator does NOT see (in the panel)
Message bodies, text, captions, document filenames, button payloads. Not in any DTO returned to the operator panel. Conversation transcripts between a customer and their end customers. Recipient phone numbers for individual messages (only the count per campaign). Contact lists, contact attributes, audience definitions beyond aggregate sizes. Webhook payload bodies, only delivery status counters. Stripe card details, never seen, held by Stripe.
When operator access to message contents is allowed
Three cases. Every one is logged. Abuse investigation: Meta has flagged a customer WABA, or we have received a report of spam, scam, or prohibited content. The operator opens the inspection tool, supplies a reason that references the abuse case, and reviews the minimum necessary message bodies to corroborate or refute the report. We are contractually obligated to do this under Meta Business Solution Provider terms; we cannot opt out. Support ticket the customer opened with us: The customer has asked us to look at message X for them (why didnt this render?). The operator audit record references the ticket number. Lawful order: subpoena, court order, or equivalent in any jurisdiction the customer or their end-customers reside in. We require the order in writing, scope our response to the orders actual scope, and notify the affected customer except where prohibited by law. We do NOT access message contents for product analytics, model training, marketing, sales prospecting, or curiosity. Doing so is grounds for termination of the operator employment and for notifying affected customers and regulators if the access cannot be justified after the fact.
How the access log works
Every action under PlatformAdmin writes a row to platform.audit_events: actor_user_id, the Amargi staff member who took the action. actor_email, denormalized for human-readable display. action, Controller.Method, for example PlatformOrgs.Suspend. target_type, target_id, target_org_id, the record acted on. ip, user_agent, status_code, request context (failed access attempts are visible too). reason, free text, required for sensitive actions. occurred_at, UTC timestamp. The log is append-only at the application layer (no UPDATE or DELETE paths in the codebase) and visible to operators in /platform/audit-log. Customer-facing access (show me every operator action that touched my org) is on the roadmap. We retain audit records for at least 7 years.
Encryption posture
Documented in detail so Meta reviewers, enterprise procurement teams, and security auditors can verify the controls without reading source. In transit: TLS 1.2 minimum on every public endpoint. TLS 1.3 preferred and default on supported clients. HSTS (max-age=31536000; includeSubDomains; preload) on every customer-facing domain. mTLS on internal service-to-service traffic where the platform spans multiple hosts. Webhook signature verification (HMAC-SHA256) on every inbound Meta webhook before any business logic runs. Outbound webhooks to customer subscribers are HMAC-signed with a per-subscription secret that the customer rotates from the UI. At rest, layered controls: We use a defense-in-depth approach with three independent layers protecting customer messaging data on the wire to disk. Disk-level full-volume encryption: All Postgres volumes are encrypted at rest by the cloud provider (LUKS-equivalent, KMS-managed AES-256). Database backups (snapshots and WAL archive) are encrypted with provider keys. Defends against physical disk theft and raw block storage exfiltration. Application-level envelope encryption on secrets: Sensitive credential fields, WABA access tokens, Page Access Tokens, Instagram tokens, webhook signing secrets, are written through ASP.NET Core IDataProtector API. Each cipher-text row carries an application-issued key id; the master key lives in the secret backend (AWS Secrets Manager, GCP Secret Manager, or HashiCorp Vault) and is rotated quarterly. A database dump on its own does not yield usable tokens. pgcrypto available for column-level encryption of message bodies on a per-org opt-in: This is the strongest tier but reduces query flexibility (substring search stops working) and is OFF by default. Enterprise customers who require it can flip the flag on for their org. What we deliberately do NOT do: Customer-managed keys (BYOK, CMK). Planned as an enterprise feature; not yet offered. Until then, Amargi is in the trust boundary for at-rest data and this document is the commitment that bounds what we do with that trust. Encrypt every column. A WhatsApp conversation is by nature a log of customer and agent text; encrypting every row breaks the inbox search box. We encrypt the secrets that, if leaked, would let an attacker impersonate the customers business to Meta; we do NOT encrypt every text-body row by default. This is the same posture that every major WhatsApp Business Solution Provider takes; see Twilio, MessageBird, and 360dialog public security pages. Key rotation cadence: Master encryption key (envelope key for DataProtector): quarterly. Webhook signing secrets: customer-controlled, recommended quarterly. WABA access tokens: Meta-controlled lifecycle; we re-acquire on expiry via the BSP refresh path. Internal mTLS certificates: 90-day Let Encrypt rotation. How a reviewer can verify: messaging.wabas.access_token_ref in a fresh database dump shows cipher-text, not plaintext. Confirm by inspecting any row. Reach:Secrets:Mode env var on prod must be set to a non-passthrough value, aws, gcp, or vault. (passthrough is dev-only and the API logs a startup warning when used outside development.) All inbound and outbound webhook handlers terminate with a 401 if the signature is missing or fails the constant-time HMAC compare. See the Webhooks integration-test suite for the negative-path coverage.
Tenant isolation
Every entity owned by an organization in the domain layer carries the ITenantOwned marker. EF Core query filters are automatically added to every query to constrain reads to the caller requests active organization. This prevents cross-tenant data leakage structurally, not just by convention, regardless of who signs in or via which product. Code that tries to query without the tenant filter breaks a unit test in the repository layer.
Data residency
Production data is stored in a single region selected per customer at onboarding. Default is eu-central-1. Cross-region replication, if any, stays inside the same legal jurisdiction.
Subprocessors
The complete list (with purpose, location, DPA link for each) is published on the subprocessors page. We notify customers of new subprocessors at least 30 days in advance.
Changes to this document
The current revision is committed to the repository at apps/reach/docs/PRIVACY-POSTURE.md and mirrored here. The git history of the repository file is the canonical change log. Material changes are announced to customers by email at least 30 days before they take effect.
Contact
Privacy questions, access requests, deletion requests: contact@amargicreative.com. Security issues: contact@amargicreative.com.