Sub-processors
Last updated [[EFFECTIVE_DATE]]
A sub-processor is any third party that may access customer data while we deliver the service. We give 30 days' notice before adding one, so you can object.
Current — production (P0 containment)
| Sub-processor | Purpose | Data accessed | Location |
|---|---|---|---|
| Microsoft Corporation (Azure) | Hosting, compute, storage, identity, telemetry | All customer data | United States — Azure West US 2 |
P0 status (effective immediately): Production runs deterministic-only for Wanda (QBR Copilot / audit insights). No customer data is sent to any external AI model provider in any deployed environment (WEBSITE_SITE_NAME set). The code gate is shared/agent.py:_llm_allowed() which returns False when deployed, regardless of AGENT_PROVIDER or whether a key is present. Credentials for NVIDIA / Azure OpenAI, if retained, are held in Azure Key Vault only and are not wired to the Function App in production (infra/09-harden.sh unwires them).
Wanda's deterministic path (shared/agent.py:_fallback_narrate, shared/audit_insights.py:_fallback_narrate_audit) uses only data already in storage and is grounding-checked (is_grounded) the same way.
What an external model would receive (when enabled)
shared/agent.py:build_context() (QBR Copilot) and shared/audit_insights.py:build_audit_context() (Instant Audit) assemble only aggregates — never raw directory objects. If an external provider were enabled, the following would be sent as the model context:
- QBR Copilot (
POST /api/agent/chat): tenant display names / IDs, per-tenantlastAnnualWasteUsd/lastAnnualSpendUsd/lastScanAt/byKindtotals, report headline (annualWasteUsd/annualSpendUsd/findings/priceAsOf/ warnings /byKind), trend summaries (wasteDeltaUsd/spendDeltaUsd), composed deltas (reclaimed_annual_usd/absorbed_annual_usd/net_spend_delta_usd/ notes), catalog version. No UPNs, no assignment roster (HMAC-tokenised), no mailbox contents. - Audit insights (
POST /api/audit/insights): anonymized audit summary (annual_waste_usd,annual_spend_usd,by_kind,sku_summarycapped 20,warnings,total_users,licensed_users,tenant_nameif supplied). Validated byroutes/audit_insights.py:_validate_summary(strict aggregate-only DTO: allowlisted fields, ranges, known kinds,byKindreconciliation, PII/injection rejection) to reject any UPN-like keys and anyfindingsarray of objects.
This is customer data under the DPA (financial aggregates + tenant identifiers). It is sent only when an external LLM is intentionally enabled.
Conditional / future sub-processors — NOT active in production
| Sub-processor | Purpose | Data that would be accessed | Location | Status |
|---|---|---|---|---|
NVIDIA Corporation (NVIDIA Integrate API, https://integrate.api.nvidia.com) | QBR Copilot narration (meta/muse-glimmer-30b) when AGENT_PROVIDER=nvidia and key present | Aggregates listed above | United States — NVIDIA hosted inference | Disabled in production (P0). Would require re-enablement checklist below. |
| Microsoft Corporation (Azure OpenAI) | Alternative QBR Copilot narration (openai/deployments/{AZURE_OPENAI_DEPLOYMENT}/chat/completions) | Same aggregates | United States — Azure West US 2 (same boundary as hosting) | Disabled in production (P0). Covered by Microsoft DPA when enabled, but still requires checklist. |
Local Ollama (OLLAMA_HOST) | Dev-only local model (qwen3:8b) | Same aggregates | Developer machine / private network | Never in production. Dev only. |
Until the re-enablement checklist is satisfied, these rows are disclosed but not authorized for customer-data access in production.
Re-enablement checklist — required before any external model may receive customer data
External LLM re-enablement is not part of the P0 launch. Each item must be completed and documented:
- Approved subprocessor disclosure and notice — update this file and
legal/DPA.md:Annex III, publish 30 days' notice, provide objection mechanism. - Contractual retention / no-training terms — signed terms with the provider stating customer data is not retained beyond processing, not used to train models, and deleted within provider's documented window (commit to specific days and cite provider docs).
- Region and data-flow review — confirm processing region(s), data residency, and that the flow stays within the disclosed transfer mechanism (SCCs / DPA). Document in
COMPLIANCE.md/ DPA Annex I. - Tenant-level opt-in — explicit per-tenant / per-org consent stored and enforced in
shared/agent.py/routes/agent.pybefore any call; default remains deterministic. - Provider-specific labeling — UI and API must report the actual provider. Backend returns
provider: nvidia|azure|ollama|deterministic(shared/agent.py:chat,routes/agent.py), frontend rendersvia NVIDIA/via Azure OpenAI/via Ollamavsgrounded in …(dashboard/dashboard.html:wireCopilot). - Prompt / output redaction and audit controls — strip or hash any tenant identifiers not needed for narration, log provider, model, prompt hash, output hash, and grounding result to immutable audit trail; sample and review.
No code change that would make _llm_allowed() return True in a deployed environment may ship until this checklist is signed.
Deliberately not used
Listed because "which third parties see our data" is the real question behind the one above, and the absence of these is more informative than the presence of Microsoft.
| Category | Status |
|---|---|
| Analytics (Google Analytics, Segment, Mixpanel) | None. The site sets no analytics cookies and does not track visitors. |
| Error tracking (Sentry, Rollbar) | None. Diagnostics stay in Azure Application Insights. |
| Support desk (Intercom, Zendesk, Front) | None. Support is email only. |
| Email marketing (Mailchimp, SendGrid) | None. |
| CDN outside Azure (Cloudflare, Fastly) | None. Azure Static Web Apps only. |
| AI or LLM services (production) | None in production (P0). Deterministic only; see conditional table above for future. |
The one third-party request the site makes is to Google Fonts for typefaces. That transmits the visitor's IP address to Google as part of an ordinary HTTP request. It carries no customer data and applies to the marketing site only — but it is a third-party request, so it is disclosed rather than omitted.
Infrastructure without customer data access
These support development but never receive customer data.
| Service | Purpose |
|---|---|
| GitHub | Source control and deployment automation. Contains no customer data. |
| PyPI, npm | Dependency distribution during build. |
Changes
Material changes are notified to account holders by email at least 30 days before taking effect. Contact kyler@ebbwater.net to object.