Skip to content

Sub-processors

Every third party that receives customer data, what we send each one, and what we deliberately never send.

Last updated: 6 August 2026

The providers, and what each receives

This list is generated from the register our own backend holds, so it cannot drift away from the software. Each entry names the source files the claim was checked against. The same register is served as JSON at /api/privacy/disclosure if you would rather read it that way.

Groq, Inc.

Optional

LLM inference for incident root-cause analysis, and for the Nivaran in-product chat assistant.

LLM analysis is entitlement-gated and falls back to deterministic rules-based analysis; the rules engine remains the source of truth.

What we send

  • Incident context: monitor type, status codes, response times, timestamps and incident timeline.

  • The affected asset's domain name (deliberately retained -- an analysis that cannot name the host is not actionable).

  • Monitor error messages, truncated to 500 characters and scrubbed of credential-shaped substrings.

  • Root-cause text you confirmed yourself on this organization's own past resolved incidents for the same asset or the same kind of check, so the analysis can take account of what you already diagnosed. Length-capped and scrubbed of credential-shaped substrings like any other free text. Never crosses an organization boundary, and nothing here trains or fine-tunes a model.

  • For the chat assistant: the message text the user types.

What we never send

  • Organization UUID, incident/asset/monitor primary keys -- dropped by sanitize_for_llm before the prompt is built.

  • The name you gave the asset. Unlike the domain, an asset name is free text you typed and routinely identifies a client, a project codename or a person, and it tells a model nothing the domain does not -- so it is removed before the prompt is built. The weekly recap's per-asset incident distribution is likewise sent as counts with the asset labels removed.

  • Account email addresses, names, or payment data.

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/core/intelligence/context/redaction.py (sanitize_for_llm)
  • app/core/intelligence/prompts/incident_rca_prompt.py
  • app/providers/groq.py

NVIDIA Corporation (NVIDIA API Catalog)

Optional

Fallback LLM inference for incident root-cause analysis, the weekly incident summary, asset change-event explanation, and the Nivaran in-product chat assistant.

Invoked only when the primary provider fails.

What we send

  • Identical payload to whichever Groq call it backs up -- the incident/weekly-summary/asset-event cascade shares one FallbackProvider path, and Nivaran chat shares a separate, interface-matched cascade (NivaranFallbackProvider); both send Groq's payload unchanged to NVIDIA when Groq fails.

What we never send

  • Organization UUID and row primary keys (dropped by sanitize_for_llm).

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/core/intelligence/providers/nvidia_provider.py
  • app/core/intelligence/providers/fallback_provider.py
  • app/providers/nvidia.py
  • app/providers/nivaran_fallback.py

Dodo Payments

Optional

Payment processing for paid subscription plans: checkout, customer/subscription lifecycle, refunds, and discount codes.

Only invoked when a customer starts paid checkout; free-tier and manually-invoiced accounts never reach Dodo.

What we send

  • Customer email and, when provided at signup, name.

  • Product/price selection (plan and billing cycle), resolved server-side -- never a client-supplied amount or currency.

  • Checkout/subscription metadata: organization_id, user_id, package_id -- used to reconcile Dodo's webhook back to the correct Nivaronix account, not shared for any other purpose.

  • Card and other payment-instrument details, entered directly into Dodo's own hosted checkout page -- these never transit or touch Nivaronix's servers.

What we never send

  • Asset, monitor, or incident data.

  • Passwords or session tokens.

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/subscription/dodo_provider.py (create_checkout_session, create_customer)
  • app/routers/subscription.py (checkout route metadata)
  • app/routers/dodo_webhook.py (signature-verified inbound events)

Resend

Required to run the service

Transactional email delivery.

What we send

  • Recipient email address.

  • Email subject and body, which may include asset domain names, incident summaries and the recipient's first name.

What we never send

  • Passwords or payment data.

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/email/resend_provider.py
  • app/services/email_service.py

Cloudflare, Inc.

Required to run the service

Four distinct roles, kept separate here because they differ in who controls the account and the data: (1) CDN / WAF / public TLS termination for Nivaronix's own production infrastructure (the API, web, dashboard and admin hosts, and the status-page fallback origin) -- every visitor and customer request reaches Nivaronix's origin only after passing through Cloudflare's edge. Not optional; always in the path. (2) Optional storage backend for generated report artefacts (REPORT_STORAGE_BACKEND=r2) -- Nivaronix's own Cloudflare R2 account. The default backend is local disk, which never reaches Cloudflare at all. (3) Custom hostname + TLS provisioning (Cloudflare for SaaS) for a customer's own status-page custom domain, also on Nivaronix's own Cloudflare account (the nivaronix.com zone) -- this is Nivaronix routing the customer's chosen hostname, not an action on the customer's Cloudflare account. (4) A customer-directed Remedy connector: the customer supplies their OWN zone-scoped Cloudflare API token for their OWN Cloudflare zone, which Nivaronix's servers use only to execute WAF/rate-limit/DNS mitigation actions the customer authorized and to read that zone's traffic analytics for detection. Role (4) is Nivaronix acting on the customer's instruction against the customer's own Cloudflare account, not Nivaronix-controlled processing -- included here because the customer's credentials and zone data still pass through Nivaronix's servers to make the call.

Role (1) (edge CDN/WAF/TLS) is not optional -- it fronts all production traffic unconditionally. Role (2) (R2 report storage) is optional and off by default (local disk). Role (3) (status-domain provisioning) only applies to a customer who configures a custom status-page domain. Role (4) (the Remedy connector) only applies to a customer who connects their own Cloudflare zone.

What we send

  • Role (1), CDN/edge: all visitor and customer HTTP traffic bound for Nivaronix's own domains -- source IP, request headers, path, and TLS connection metadata -- terminates at Cloudflare's edge before Nivaronix's origin ever sees it.

  • Role (2), report storage (only when REPORT_STORAGE_BACKEND=r2): the generated report artefact's full content (PDF/HTML/JSON/CSV/SARIF bytes), which may include asset domain names and incident summaries, stored under an organization-scoped object key.

  • Role (3), status-domain provisioning: the hostname the customer chooses for their status-page custom domain, and the DNS/TLS validation records Cloudflare requires to prove and route it.

  • Role (4), customer's own Cloudflare account: the customer's own API token and zone id (stored, used only against the zone it was issued for); DNS record names/values and WAF/rate-limit rule parameters for the specific action the customer authorized; that zone's own traffic analytics, read back for attack detection.

What we never send

  • Role (2) report content is sent to Cloudflare only when the operator has explicitly set REPORT_STORAGE_BACKEND=r2 -- the default 'local' backend writes to Nivaronix's own disk and never reaches Cloudflare.

  • Role (4)'s customer-supplied token and zone id are never used against any zone other than the one they were verified against at connect time (CloudflareConnector.covers_domain fails closed on a domain outside the pinned zone).

  • Passwords or payment data, in any role.

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/core/trusted_proxies.py (CLOUDFLARE_RANGES; trusted-proxy configuration for the edge hop)
  • deploy/compose/Caddyfile (Cloudflare terminates public TLS for the origin; Cloudflare for SaaS fallback-origin TLS)
  • app/reports/storage.py (_r2_client, write_artifact/read_artifact 'r2://' backend, REPORT_STORAGE_BACKEND)
  • app/core/status_domain/provider.py (CloudflareForSaaSStatusDomainProvider; CLOUDFLARE_STATUS_DOMAIN_API_TOKEN / _ZONE_ID -- module docstring states this is Nivaronix's own platform credential, never a customer's)
  • app/core/remedy/connectors/cloudflare.py (CloudflareConnector -- customer-supplied api_token/zone_id, covers_domain zone pinning)
  • app/core/monitoring/cloudflare_telemetry_source.py (customer zone analytics translated for detection)

Amazon Web Services, Inc. (Route 53)

Optional

A customer-directed Remedy connector, not Nivaronix-controlled processing: the customer supplies their OWN AWS IAM access key and their OWN Route 53 hosted_zone_id, which Nivaronix's servers use only to write TXT records (SPF/DMARC auto-fix) to that customer's own Route 53 zone. This is Nivaronix acting on the customer's instruction against the customer's own AWS account; it is listed here because the customer's credentials and DNS record data still pass through Nivaronix's servers to make the API call. No use of Nivaronix's own AWS account -- for hosting, storage, email or anything else -- was found anywhere in the codebase or deployment configuration; see the 'data_not_sent' note below.

Only invoked when a customer connects their own AWS/Route 53 account to Nivaronix's SPF/DMARC auto-fix remedy; never invoked otherwise.

What we send

  • The customer's own AWS access key id and secret access key, and their Route 53 hosted_zone_id and domain -- supplied by the customer at connect time and used only to call Route 53 on the customer's own account.

  • The TXT record name and content for the specific SPF/DMARC record being read or written on the customer's Route 53 zone.

What we never send

  • Nivaronix's own infrastructure, storage or email data -- no S3, SES or any other AWS service call was found outside this connector, and no AWS reference was found in docs/deployment/README.md or the Caddy/compose deployment config, which name Cloudflare for edge TLS instead. The AWS_CLOUDFRONT / Route 53 references in app/scanner/playbooks.py are static remediation instructions shown to a customer who already uses those AWS services themselves, not an API call Nivaronix makes.

  • Any record type other than TXT, and any zone other than the one the customer confirmed at connect time -- both refused outright (execute() rejects non-TXT; covers_domain fails closed outside the configured domain).

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • app/core/remedy/connectors/route53.py (module docstring; Route53Connector.__init__, validate, _upsert_txt_record, covers_domain)
  • app/core/remedy/provider_registry.py (comment scoping boto3 usage to TXT-record writes for this connector)

Google LLC (Google Analytics)

Optional

Optional web analytics for the public marketing site (nivaronix-web) only -- aggregate visitor/usage measurement. Not used by the dashboard, admin console, or API, and no server-side integration exists anywhere in this codebase.

Loads only if NEXT_PUBLIC_GA_MEASUREMENT_ID is set (it is set in the production build) and only after the visitor accepts analytics cookies; an unset value renders nothing.

What we send

  • Standard GA4 (gtag.js) client-side telemetry -- page views, session/device/browser metadata, and the visitor's IP address (used by Google to derive an approximate location) -- sent directly from the visitor's own browser to Google. It never transits or is proxied through Nivaronix's servers.

What we never send

  • Any Nivaronix account data -- gtag.js has no knowledge of a signed-in user, organization, asset, or incident; there is no backend call to Google anywhere in this codebase.

  • Anything at all before the visitor accepts the 'Analytics' consent category. The script is not fetched and no request to Google is made until then, and withdrawing consent sets Google's own documented 'ga-disable-<id>' opt-out flag immediately (does not retroactively clear cookies already set).

Data processing agreement

Not documented

Data residency

Not documented

Transfer safeguard

Not documented

Verified against our own source code:

  • nivaronix-web/src/components/legal/google-analytics.tsx
  • nivaronix-web/src/components/legal/consent-gated.tsx
  • deploy/aws/build-nextjs-native-arm64.sh (production NEXT_PUBLIC_GA_MEASUREMENT_ID build arg)

The providers underneath, which the register does not cover

The register above lists the providers we hand data to. Three more sit underneath the product and see it by virtue of running it, and a procurement questionnaire will want them named too.

Amazon Web Services hosts the platform, in the eu-west-1 region — Ireland. The database holding accounts, assets, monitors and incidents runs there, and so do the servers and the encrypted nightly backups. Cloudflare sits in front of it as DNS, CDN and WAF, so every request to us passes through whichever of its edge locations is closest to you; its network is global by design and pins no region. Google Analytics runs on this marketing website only — never in the product — and only if you accept analytics cookies. What it sets, and how to refuse it, is on the cookie page.

The Ireland figure is where our deployment configuration puts the infrastructure, not a residency commitment. We have not contracted with anyone to keep data in a region and could move it, so treat it as a description of today rather than a promise about tomorrow. If you need the promise, that is a conversation, not a page.

Where the data goes

Nivaronix is operated from Nepal, and every provider above is headquartered in the United States or the United Kingdom. If you are in the EEA or the UK, your data therefore leaves your region — first to us, then to them.

Nepal has no European Commission adequacy decision and no UK adequacy regulations, so a transfer here relies on one of the safeguards in Chapter V of the GDPR rather than on adequacy. We have not yet put those safeguards in place, and the “Transfer safeguard” row above reads Not documented for every provider because that is the truth of it today.

We would rather say that plainly than publish a safeguard we cannot produce on request. If your organisation needs Standard Contractual Clauses or an International Data Transfer Agreement in place before it can use Nivaronix, write to admin@nivaronix.com and say so — it tells us to prioritise it.

Claims we can prove

These are the statements in our privacy documentation that are easiest to get wrong over time, so each one is recorded next to the code that makes it true.

IP addresses of scan requesters are stored only as a salted one-way SHA-256 hash, never in plaintext.

app/scanner/audit.py: _hash() applies sha256 over a salt read from the environment, and the module refuses to start in production with the shared default salt.

Tenant identifiers are removed from incident data before it is sent to an LLM sub-processor.

app/core/intelligence/context/redaction.py drops organization_id and row primary keys; applied at the single prompt-building chokepoint every provider goes through.

The asset domain name IS sent to LLM sub-processors, by design.

app/core/intelligence/context/redaction.py module docstring states the domain is deliberately kept. This must be disclosed rather than glossed as 'anonymised analysis'.

The customer-chosen asset NAME is not sent to LLM sub-processors, on either the incident or the weekly-recap path.

app/core/intelligence/context/redaction.py: _DROP_PATHS removes ('asset', 'name'), and _ASSET_KEYED_COUNTS replaces the weekly recap's name-keyed incidents_per_asset mapping with counts. Asserted against the serialized prompt in tests/core/intelligence/test_llm_egress_redaction.py.

Customer-confirmed root-cause text from an organization's own past incidents IS sent to LLM sub-processors, by design, and is disclosed.

app/core/intelligence/context/context_builder.py _fetch_customer_root_causes (org-scoped, recency- and count-bounded, length-capped); carried in IncidentContext.historical_context and scrubbed as free text by redaction._FREE_TEXT_KEYS.

Scan audit logs and security event logs expire on a retention schedule.

app/legal/retention.py: SCAN_AUDIT_RETENTION_DAYS (90) and SECURITY_EVENT_RETENTION_DAYS (180), both env-tunable. NOTE: a scheduled job that actually enforces these was not located; see PRIVACY-OWNER-DECISIONS.md.

Changes, and how to ask

When we add or replace a provider, this page changes with the code that adds it. We have not yet committed to a fixed advance-notice period before a new sub-processor starts processing — if you need one written into a contract, ask.

Questions about any provider here, or a request for a data processing agreement, go to admin@nivaronix.com. How each provider fits into the wider picture is set out in our Privacy Policy.

Our other policies