---
title: Smart BAA (On-Chain Business Associate Agreement Escrow)
acronyms: [BAA]
created: 2026-07-09
updated: 2026-07-15
type: concept
tags: [compliance, tokenomics]
confidence: high
source_files:
- contracts/src/health/SmartBAA.sol
- contracts/src/health/SmartBAAFactory.sol
---
This page merges and corrects the old wiki's `hybrid-escrow.md` and
`smart-baa-technical-guide.md` — both described the same subject
(HIPAA Business Associate Agreements represented on-chain) with
overlapping and, in places, aspirational detail. This page documents only
what `contracts/src/health/SmartBAA.sol` actually implements; the
"what's not built" section at the bottom lists the old pages' extras
explicitly so nothing here is silently dropped.
## Table of contents
- [The real mechanism](#the-real-mechanism)
- [The closed loop with BCC/OPA](#the-closed-loop-with-bcc-opa)
- [What's NOT built (correcting the old wiki's extras)](#what-s-not-built-correcting-the-old-wiki-s-extras)
## The real mechanism
One `SmartBAA` instance per `(coveredEntity, businessAssociate)` pair,
deployed by `SmartBAAFactory` — never constructed directly, so the
"who may even become a covered entity" gate is checked once at the
factory, not re-checked (or forgotten) per instance. A Covered Entity
(hospital) and a Business Associate (the agent, acting as `businessAssociate`)
post a `bytes32 agreementHash` — a hash of their off-chain legal agreement —
plus the agent's $ITK collateral (`requiredCollateral`), and a single
named `arbitrator` address resolves disputes:
```solidity
enum Status { Proposed, Active, Disputed, Terminated }
function sign() external onlyBA; // BA posts collateral, Proposed -> Active
function raiseDispute() external onlyCE; // CE flags a breach, Active -> Disputed (freezes revoke)
function arbitrate(bool slash) external onlyArbitrator; // Disputed -> Terminated (slash=true, collateral to CE)
// or -> Active (slash=false, dismissed)
function revoke() external; // either party, Active -> Terminated, collateral returns to BA
```
```mermaid
stateDiagram-v2
[*] --> Proposed: SmartBAAFactory deploys
(agreementHash, requiredCollateral, arbitrator)
Proposed --> Active: sign() — BA posts collateral
Active --> Disputed: raiseDispute() — CE flags a breach
Active --> Terminated: revoke() — either party
Disputed --> Terminated: arbitrate(slash=true)
collateral to CE
Disputed --> Active: arbitrate(slash=false)
dismissed
Terminated --> [*]
note right of Disputed
revoke() is blocked while Disputed —
no dodging arbitration by exiting
end note
```
**Collateral is isolated per agreement** (a single ITK balance held by this
one contract) — a deliberate departure from a shared/pooled staking vault
design, so a slash on one BAA can never be starved by withdrawals against
an unrelated one. `revoke()` cannot be called while `Disputed`, so a party
under active accusation can't dodge arbitration by unilaterally exiting.
## The closed loop with BCC/OPA
[BCC middleware](bcc_middleware.md) enforces the same BAA
on-chain *before* an agent even acts, not just after a dispute: a clinical
[BCC commitment](bcc.md) carries a signed `covered_entity_address`, OPA
flags the intent `requires_baa`, and the middleware calls
`SmartBAAFactory.isBAAActive(coveredEntity, agent)` — failing closed if it
can't positively confirm. [ComplianceGate](compliance-gate.md)'s
`isHealthcareCompliant` performs the equivalent read for the read-optimized
compliance summary surface; [EHRGate](compliance-gate.md) performs its own
independent live check at actual PHI-access time. All three consult the
same underlying `SmartBAAFactory.isBAAActive`.
## What's NOT built (correcting the old wiki's extras)
The old `smart-baa-technical-guide.md` described several mechanisms that do
**not** exist in `SmartBAA.sol` today — flagged here explicitly, not
silently dropped, per the schema's `[PLANNED]` rule:
- **`[PLANNED]` 72-hour dispute window.** The old guide described a
`initiateSlash()` "soft slash" with a 3-day evidence window before
`finalizeSlash()`. The real contract has no time-based logic at all:
`arbitrate(bool)` can be called immediately after `raiseDispute()`, with
no minimum delay.
- **`[PLANNED]` On-chain EIP-712 typed signing.** The old guide described
parties signing the `documentHash` via EIP-712 typed data in-wallet. The
real contract takes `agreementHash` as a plain constructor argument (set
by `SmartBAAFactory` at deploy time) — there is no on-chain signature
verification step; `sign()` just transfers collateral and flips status.
- **`[PLANNED]` `recoverBusinessAssociate()` / controller recovery.** No
such function exists — there is no key-recovery pathway if a party loses
its private key.
- **`[PLANNED]` Nested/subcontractor BAAs.** No support for one BAA
requiring a downstream agent to stake its own collateral.
- **Corrected: single arbitrator, not a 3-party multi-sig.** The old
`hybrid-escrow.md` described a multi-signature wallet of "Hospital
Administrator + Neutral Third-Party Auditor + AI Vendor." The real
contract has one `arbitrator` address, set once at deployment
(`SmartBAAFactory`, expected to be a neutral/governance address, not
either party) — not a multi-sig of the three parties themselves.
- **Not evidenced anywhere in this repo**: an IPFS-pinned legal document,
an OPA-linked `baaId`, a "Compliance Officer Command Center" UI, or a
`slashAndRevoke()` combined function. `arbitrate(true)` is the real
slashing path; there is no dashboard UI for BAA proposal/review built yet
(see [integrity-dashboard](integrity-dashboard.md)'s "What's built").
Related: [ComplianceGate](compliance-gate.md), [BCC](bcc.md),
[contracts](contracts.md).