Compliance

What we can prove, and what we will not claim.

AdaptivMapr maps regulated data, so the interesting part of a compliance page is not the list of frameworks — it is the list of things a vendor refuses to overstate. Every row below names the file or the filed clause it came from.

HIPAA-ready · BAA offered · Security Risk Assessment on file · SOC 2 Type II in progress · no “HIPAA certified” claim

The posture

Three sentences a reviewer can check.

One thing we hold, one thing that limits exposure, and one thing that is still open. If a vendor's compliance page has no third category, it is a brochure.

What we hold

HIPAA-ready, not HIPAA certified

We act as a Business Associate, we offer our own BAA, and we hold a HIPAA Security Risk Assessment on file. No vendor holds a “HIPAA certification” — no such thing exists in U.S. law — so we do not claim one, and you should treat anyone who does with suspicion.

Filed · Security Risk Assessment produced under 45 CFR § 164.308(a)(1)(ii)(A), following the HHS/ONC SRA structure. Request it at compliance@adaptivmapr.com.

What limits exposure

Most imports send no rows at all

Schema-only is a data-minimisation mode, not a trial tier: only column headers and up to three sample values per column, each truncated to 80 characters, ever leave your tenant. It never touches the metered AI layer.

Enforced · One chokepoint — clampForSchemaOnly() in lib/parser.ts — applied at the HTTP edge in every /api/v1 route that accepts sample rows, and re-applied at the LLM boundary.

What is still open

SOC 2 Type II is in progress

The observation window is running. There is no attestation report yet, so there is nothing for us to send you. Our hosting providers hold their own SOC 2 Type II reports — that is their attestation, not ours, and we will not present it as ours.

Status · We do not hold SOC 2 Type II, HITRUST or ISO 27001 today. /legal/security §7 is the binding statement of the same thing.

  • BAA offered · HIPAA SRA on file
  • Headers + ≤3 rows in schema-only
  • PHI routing blocked until you accept
  • Hash-chained audit_logs
  • Uploads purged at 24h

Frameworks

Four states, because two would be a lie.

“In force” means it applies to your traffic today. “Contract-dependent” means the coverage exists only once the operator has executed the upstream paid agreement — the honest label for an inherited posture. “Not claimed” is where most of the damage is usually done.

FrameworkScopeWhat it actually meansState
HIPAA (as a Business Associate)United States · full-data modeAdaptivMapr is HIPAA-ready: we offer our own BAA covering our role as a business associate, and we hold a HIPAA Security Risk Assessment on file under 45 CFR § 164.308(a)(1)(ii)(A). HIPAA is not a certification anyone can hold, so we do not claim one./legal/security §8 · app/legal/operational/hipaa-sraIn force
GDPR (EU 2016/679)European UnionProcessing runs under our DPA, with Standard Contractual Clauses incorporated by reference. The subprocessor list is maintained publicly and changes are notified 30 days in advance to customers under a signed BAA./legal/dpa Art. 8 · /legal/subprocessors §3In force
nFADP (Switzerland, 2020)SwitzerlandThe Swiss Federal Act on Data Protection is treated as equivalent to GDPR for the purposes of customer obligations. CH is the default workspace region pin./legal/security §7 · lib/workspaceSettings.ts DEFAULTS.regionIn force
UK GDPR / DPA 2018United KingdomCovered by the same DPA. UK is one of the four jurisdictions the reshape sandbox will accept as a compliant placement./legal/privacy §1 · lib/reshape/sandbox.ts SANDBOX_REGIONSIn force
CCPA / CPRACaliforniaWe do not sell or share personal data within the meaning of California law./legal/security §7In force
SOC 2 Type IIAdaptivMapr platformObservation window in progress. No attestation report exists yet, so we do not present one. Our hosting providers hold their own SOC 2 Type II reports, available from each provider under NDA — that is their attestation, not ours./legal/security §6, §7In progress
Cloudflare BAAWorkers compute, KV, R2Cloudflare offers a HIPAA BAA on its Enterprise plan. AdaptivMapr will not process PHI through Cloudflare Workers, KV, R2 or Analytics Engine unless the operating account is on Enterprise with a signed BAA covering those services./legal/subprocessors §2Contract-dependent
Supabase HIPAA add-onAccount metadata, audit log, upload mirrorSupabase offers HIPAA-eligible hosting on Teams and Enterprise with a signed BAA. The AdaptivMapr project must be configured against a BAA-covered Supabase organisation before any PHI is persisted to account metadata or audit logs./legal/subprocessors §2Contract-dependent
phi-cloud BAA chainLayer-5 LLM, full-data modephi-cloud holds BAAs with each downstream model provider in its region matrix. AdaptivMapr inherits that chain when full-data mode routes through phi-cloud — it is a chain, not a certificate we hold./legal/subprocessors §2 · lib/llm.tsContract-dependent
HITRUST · ISO 27001 · "HIPAA certified"We do not hold these and do not claim them. No "HIPAA certified" status exists in U.S. law for any vendor to hold./legal/security §8Not claimed

The source column names the file or the clause each row was read from. Where this page and a document under /legal disagree, the document is binding and this page is the bug — tell us at compliance@adaptivmapr.com.

Data minimisation

The cheapest way to protect a record is not to send it.

Schema-only and full-data are two modes of the same cascade, not two tiers of a plan. Both draw the same small flat per-map fee; only one of them can see a row of your data.

Schema-only — the default path

The cascade resolves columns from statistics, heuristics and fuzzy matching before any model is consulted. In schema-only mode the metered AI layer is never reached at all, so a DPA is usually unnecessary — one is provided on request.

Contract · ≤3 rows, each cell ≤80 characters. Nothing else leaves. parsed_rows is null in this mode (DPA Art. 8, Supabase row).

Full-data — in-region, under a BAA

Row-level AI cleanup goes to phi-cloud with X-PHI and X-Region set, so the gateway is forced to pick a PHI-eligible, in-region model. It costs 20% more on the whole map charge, and it is locked until your workspace accepts the BAA/NDA in the app.

Gated · An explicit PHI ask with no acceptance on file returns 403 agreement_required plus a settings_url pointer. There is no silent downgrade to the general catalogue.

Unstructured convert input is the one exception: it is always PHI-routed, and asking for standard routing on it returns 400 phi_required_for_full_data. See how the two modes differ and how a run resolves its routing.

The BAA gate

PHI routing is locked until you accept it.

A signed agreement that lives in a filing cabinet protects nobody. Acceptance is recorded in the product, and the gate reads it on every run — so a workspace cannot route PHI on the strength of an intention.

  1. 1Standard is what you get

    tenants.phi_mode defaults to false. An unconfigured workspace runs standard routing — we never silently upgrade unknown traffic into the surcharge and the agreement gate.

  2. 2You accept in the app

    Settings → Security & Data records the BAA/NDA acceptance against your workspace in public.tenant_agreements, readable and writable at /api/v1/me/agreements.

  3. 3The gate reads it per run

    resolveRunPhi() resolves the per-run choice against the workspace default; an explicit PHI ask with no acceptance on file is refused, not downgraded.

  4. 4Failure resolves to standard

    Every fail-soft path defaults to standard routing on an unreadable settings row. The safe direction here is the cheaper, less regulated one.

request
# An explicit PHI ask from a workspace that has not accepted.
curl -X POST https://api.adaptivmapr.com/v1/me/reshape \
  -H "Authorization: Bearer mp_live_…" \
  -H "content-type: application/json" \
  -d '{"phi_mode": true, "upload_id": "up_…"}'
response
HTTP/1.1 403 Forbidden

{
  "error": {
    "code": "agreement_required",
    "message": "PHI routing requires the BAA/NDA to be accepted for this workspace",
    "settings_url": "https://adaptivmapr.com/dashboard/settings/security"
  }
}
→ refused, with a pointer to where you can fix it — never a quiet downgrade

How hard the gate bites

MAPR_BAA_ENFORCE=strictThe production setting.
Every PHI-routed run requires an in-app acceptance on file.
MAPR_BAA_ENFORCE=explicitThe code default when the variable is unset.
Only an explicit PHI ask is refused; a run that merely inherits an existing workspace phi_mode is grandfathered.
MAPR_BAA_ENFORCE=off
Advisory only — the gate reports but does not block.

Audit & erasure

Six controls you can name in a questionnaire.

Not “enterprise-grade security”. The store, the enforcement point, and the rule that keeps each one honest.

One append-only trail

Key creation and revocation, mapping commits, confirmations, billing events, erasure intents and PHI-agreement acceptances are written to a hash-chained audit log, scoped to your workspace.

Where · Supabase audit_logs. The external CHAINLOG_* variables are a legacy fallback, not the primary sink.

Written even after the response

Audit writes, wallet debits and usage reports are registered with the Worker’s waitUntil rather than fired and forgotten, because a Cloudflare isolate may stop the moment a response is returned.

How · afterResponse() in lib/backgroundWork.ts. Every billing, metering, audit and email call site was migrated to it.

Content is never the payload

A remembered Workbench chat records ids, counts, byte sizes and the routing a run got — never the text of a message or a cell of your data. An incognito chat leaves no trail at all.

Event · workbench.chat in audit_logs, via lib/workbenchChatAudit.ts. Chat memory follows PHI routing: PHI defaults to off.

Uploads expire on their own

Parsed uploads live in Cloudflare KV under a native 24-hour TTL and are mirrored to Supabase for the same window. Expiry is the storage layer’s job, not a cleanup job that can fail silently.

Where · MAPR_KV with expirationTtl, service-role reads with an explicit tenant_id filter. Retention is configurable per workspace: 0, 24, 168 or 720 hours.

Erasure is one implementation

“Delete workspace” and “Delete account” destroy the same thing through the same code path: audit event first, Supabase cascade, KV purge, cache invalidation, notification email. Both require a CSRF token and a typed confirmation string.

Rule · lib/workspaceErasure.ts. Neither route may report success when tenant_deleted is false — a failed erasure returns an error, never “Account deleted”.

Isolation is enforced by the database

The dashboard plane runs on your own Supabase user JWT, so row-level security is the gate rather than application code. Uploads, connectors and the v1 bearer API run service-role with an explicit tenant_id on every read.

Identity · auth.users.id → tenants.id via a handle_new_user trigger populating tenant_members. v1 API keys are HMAC-signed and self-contained, with a Supabase revocation check that fails closed.

The binding documents

This page is a summary. These are the instruments.

Where a sentence here and a clause there disagree, the clause governs. Send them to your counsel before you send us a questionnaire — most of the answers are already in them.

Operational instruments — the Security Risk Assessment, the incident response plan, the breach notification procedure, the security officer designation, and the sanction and training policy — are held internally and released on request under NDA. Ask at compliance@adaptivmapr.com. Data-protection requests go to dpo@adaptivmapr.com; security disclosures to security@adaptivmapr.com.

Before the questionnaire

Ask us the hard question first.

If a control below the line matters to your deployment, we would rather tell you now that it is contract-dependent than have you find out in a review.

No free tier · prepaid wallet from $10 · PHI routing +20%, locked until the BAA is accepted in-app