The first time I audited the third-party stack at a regulated DTC healthcare platform, I expected the gap list to be short. The team had BAAs with the obvious vendors and outside counsel on retainer. The CTO had run a HIPAA-eligible build before. I still found three vendors with no BAA in the first hour, and a fourth by the end of the afternoon.
None of them were the vendor anyone remembers choosing. That is the whole problem with running a BAA audit by memory: the vendors that hurt you are the ones nobody is thinking about. This is the BAA business associate agreement checklist I run instead, organized by vendor category rather than by vendor name, so the audit catches what the team has stopped seeing.
The vendor map nobody draws
Most regulated platforms know which vendors they have BAAs with. They do not know which vendors they actually have. Those are different lists.
The "vendors with BAAs" list is what is in the compliance binder. The "vendors we actually have" list is the union of every domain in production network traffic, every package in package.json, every recurring charge under $500 on the company card, and every SaaS account in the SSO directory. The second list is twice as long and full of names the current team did not put there.
Reconcile the vendor inventory against the agreements and data flows already reviewed. New integrations start with the intake record. The category audit below finds relationships that need to be reviewed again.

The BAA business associate agreement checklist
Run through every category. For each one, ask the audit question, look for the failure mode, and record the most common gap. The categories are ordered from highest PHI proximity to lowest, so if time is short, the first three are the ones to finish today.
1. Analytics and product analytics
Question: Which analytics tools fire on authenticated pages, and which of them offer a BAA?
Common gap: A product-analytics SDK installed for a feature launch is capturing URLs, user IDs, and event payloads on member-area pages. The vendor has a HIPAA-eligible plan; the team is on the default plan. The remediation is the plan upgrade, a swap to a vendor that covers authenticated traffic, or a tag-manager guard that scopes the SDK to marketing pages. None of these are quick; plan it in a separate sprint.
2. Marketing automation and lifecycle email
Question: What member data flows into the marketing platform, and is the platform on a BAA-supporting tier?
Common gap: A nightly sync still uses SELECT * after the member schema has expanded. Enumerate the outbound fields and their purposes, then implement the reviewed allowlist. If the receiving vendor acts as a business associate handling PHI, confirm the required agreement covers the account and services. Have the qualified reviewer assess a flow claimed to fall outside that relationship.
3. Transactional email, voice, and SMS
Question: Which messaging vendors carry communications to members, and is each one on a BAA?
Common gap: A transactional vendor selected when the platform was pre-PHI got grandfathered through the regulated launch. The vendor offers a BAA only on enterprise; the team is below that tier. The remediation is an upgrade or a swap, and the swap is harder than it looks because templates, deliverability reputation, and integration code all depend on the current vendor. Check SMS and voice against the same standard.
4. Error tracking and observability
Question: What does the error tracker capture in stack traces, request payloads, and user contexts, and does the vendor have a BAA?
Common gap: The vendor has a BAA but the integration leaks. The default capture sends request bodies, full URLs, and the session user object. A handler error on a member-area route ships all of that. The fix is in the SDK config, not the contract: strip request bodies on PHI-bearing routes, scrub query parameters, limit user context to a non-PHI identifier. The pattern matches the boundary thinking for App Router surfaces: assume the SDK will exfiltrate everything you do not explicitly hide.
5. CDN, edge, and image optimization
Question: Which CDN and edge providers see member traffic, and what do they cache or log?
Common gap: The CDN has a BAA at enterprise but the platform is on a lower tier because the upgrade was deferred. CDN logs include URLs and IPs for every member request. Worse: an image-optimization service in front of a member-uploaded photo gallery has no BAA at any tier and slipped in via a build-tool default. Upgrade the CDN. For the image optimizer, swap to a self-hosted pipeline or to a vendor that signs.
6. Support tools, chat widgets, and helpdesks
Question: Which support vendors hold conversations or tickets that contain member context, and is each on a BAA?
Common gap: A live-chat widget loads on authenticated pages and stores transcripts in its own database with no BAA. The helpdesk where tickets land does have one, but the chat vendor and the helpdesk are different products. Consolidate (the chat tool exports to the BAA-covered helpdesk on close) or switch the chat to a BAA-supporting product. The script-discovery discipline I describe in the third-party scripts and HIPAA risk piece catches the chat widget even when nobody on the current team installed it.
7. Authentication, identity, and session storage
Question: Which identity providers and session-storage backends hold member tokens or attributes, and is each on a BAA?
Common gap: The identity provider has a BAA but the session-storage layer is a managed cache below the BAA tier. The cache holds session tokens, last-active identifiers, and a serialized user object with PHI-adjacent attributes. It was selected for cost. Upgrade if a BAA-eligible tier exists; if not, move the session store onto your own infrastructure.
8. Schedulers, queues, and background workers
Question: Which job platforms execute background work over member data, and what data lands in their dashboards?
Common gap: A job scheduler captures stdout into a log dashboard. Every print statement in every job is now in the vendor's database, and developers tend to print member identifiers and field values during development. Sign the BAA where available, and replace prints with structured logs that go to your audit log using the append-only pattern from the audit-table tutorial for healthcare Next.js stacks.

The hidden vendors most teams forget
The gaps that hurt are the ones nobody on the current team chose. They show up in four shapes.
The subprocessor of a vendor you signed. You signed a BAA with Vendor A. Vendor A uses Subprocessor B, whose contract allows it to retain data on its own terms. Your data sits in Subprocessor B's database under Vendor A's name, and your BAA does not contemplate the transfer cleanly. Most vendor BAAs name a subprocessor list and flow obligations through; some do not. Reading the actual flow-down language is a separate audit step.
The dev account that became prod. A founder signed up for a free tier in 2022 to test something. The free tier became the production account, registered to a personal email that is not a current employee. Signing a BAA against that account requires migrating the account, the migration breaks the API tokens, and the API tokens are wired into seven cron jobs. This is the ugliest remediation because the technical and contractual fixes are coupled.
The free tier that auto-upgraded. A vendor moved from a free tier to a paid tier with a BAA available, but nobody countersigned because nobody noticed the upgrade. Until the BAA is signed, the legal posture is the same as if the vendor were still on the free tier.
The vendor swallowed by an acquisition. A small SaaS the team relied on got acquired. The acquiring company has a different compliance posture and a different BAA template. The original BAA may or may not survive. If the acquiring company's BAA is materially worse, the practical answer is to renegotiate or to leave; the contractual answer is whatever the change-of-control language in the original BAA actually says. Read that, too.
How to run the audit in an afternoon
Four steps, three to five hours on a small platform.
Step 1: pull every domain from production traffic. Export the list of unique third-party-script and outbound domains from your CDN or load balancer over the last 30 days. If you do not have that log, walk the browser network panel on every authenticated route and the top ten unauthenticated pages.
Step 2: cross-reference against the codebase. Open package.json, the env file, and the infra config. Pull out every vendor name and API host. Reconcile against step 1; any domain that appears in traffic but not in source came in through a tag manager, a dashboard, or a runtime config.
Step 3: ask billing for every recurring charge under $500. The big-ticket vendors usually have BAAs. The dangerous ones are the small line items the CFO has stopped reviewing. Match each charge to a vendor in steps 1 or 2; flag anything in billing that does not appear in either list.
Step 4: produce the gap list and prioritize by risk. For every vendor on the union of the three lists, record the BAA status (signed, available-but-unsigned, not available, unknown). Sort the unsigned and unknown rows by risk tier. That is your remediation backlog.
The audit does not require a tool, a vendor, or a consultant. It needs an afternoon and the willingness to look at every domain on the list. The pattern is similar to the commerce-side discipline I describe in the productized stack audit for DTC platforms, which surfaces the same class of vendor sprawl from the attribution angle.

What "risk level" actually means here
Three tiers cover almost every case.
Tier 1: high-risk. The vendor receives PHI directly, has no BAA, and is on production traffic right now. Remediation is immediate. Upgrade, swap, or turn the integration off today. A single Tier 1 gap is enough reason to stop the next feature ship.
Tier 2: medium-risk. The vendor could receive PHI under common flows. A BAA is available but not signed, or is signed against the wrong account, or is signed against the wrong legal entity. This is a contract-and-config sprint, not a swap. Plan it within two weeks; the medium-risk tier is where the most embarrassing audit findings come from when a regulator does ask.
Tier 3: low-risk. The vendor handles only derivative data, unauthenticated traffic, or strictly non-PHI fields. The action is documentation. Write down the data flow that justifies the determination, save the evidence in the BAA binder, revisit annually. "No BAA needed" without documented reasoning is not defensible; "no BAA needed because we send only these fields, here is the evidence" is.
“The BAA gap is rarely with a vendor you remember choosing.
”
What happens if you skip any of these
The failures are predictable, and I have seen each of them.
Miss the analytics category, and a product-analytics SDK is quietly collecting member-area URLs and event payloads for six months. The remediation is a breach assessment, possible notification, and a renegotiation. The renegotiation is the cheap part.
Without an error-tracker review, the next exception on a member-area route ships the request body to the vendor's pipeline. The vendor has a BAA, but the SDK config is the leak, and the BAA does not paper over a misconfigured integration.
Review downstream storage and subprocessors against the approved data flow. A change can require a fresh assessment of contract terms, subcontractor obligations, and safeguards by the qualified privacy reviewer.
Without the billing reconciliation, the smallest line item turns out to be the vendor with the worst exposure. This has happened to me twice. Both times, the answer was a $49-per-month tool nobody on the current team had heard of.
The audit is a one-afternoon habit that prevents a one-week incident response. Run it quarterly, and after any change to the head of compliance, the CTO, or the marketing lead. Those roles are where unrecorded vendor decisions live. The same gap-reconciliation discipline shows up in integration outage recoveries I've worked through, applied to a different surface.

The intake record before a new integration ships
The category audit finds existing vendors. A new vendor needs a record before its first production data flow. Start with the actual contracting entity and account, the subscription plan, the services covered by the agreement, and the person who confirmed the terms. A BAA offered on a website is different evidence from the agreement that covers your account.
For each integration, keep the following with the review:
- The executed agreement or the documented reason the relationship falls outside the business associate requirement.
- A field list for every outbound and inbound payload, including URLs, headers, log context, and support attachments.
- The purpose for each field and where the receiving service stores, forwards, or exposes it.
- Subprocessor terms, retention and deletion handling, incident contacts, and the path for returning or destroying data at termination.
- The integration owner, a way to disable the data flow, and the events that demonstrate what it accessed.
HHS describes the required business associate contract provisions, including safeguards and obligations passed to relevant subcontractors. Have a qualified reviewer determine which relationships and services need those terms. A pseudonymous identifier can still be linkable to a person; naming a field anonymous_id does not settle that question.
Exercise the disable path in a test environment. The application should report that the integration is unavailable and preserve work that must be retried. Check audit events for both outbound fetches and inbound operations. Those checks provide operational evidence alongside the contract review.
Reopen the record when the plan changes, a new payload field ships, account ownership transfers, the vendor is acquired, or the subprocessor list changes. A quarterly inventory review is my reminder to look for changes that the integration owner missed. Keep the dated decision with the exact services and data flow it covered.
Sources and specifics
The legal references for this review include 45 CFR 164.308, 164.504, and 164.410. Have the contract requirements and applicability reviewed against the actual relationship. Operational examples here describe vendor inventory methods rather than a finding about a named vendor or account.
