# Production Readiness Report — First Multi-Tenant Isolation Proof

**Proof ID:** `first-multi-tenant-proof`
**Subject:** Cross-tenant zero leakage at store, replay, and injection layers
**Date:** 2026-06-02
**Determination:** PROVEN IN OPERATION (scope: two tenants, same database, same code, same signing keys; structural Tenant B)
**Version:** 1.0 (Final)

---

## Strict wording

This proof demonstrates that two tenants sharing the same canonical-auth runtime — same database, same code, same substrate signing keys — produce structurally independent authority reconstructions with zero cross-tenant identifier leakage. It is **not** "isolation against a hostile co-tenant attacker," **not** "scale-tested with many tenants," and Tenant B is **a structural test tenant**, not a second commercial customer. The isolation property being proven is structural; promotion to "two real production customers" earns its own proof.

---

## Three claims (the 10-second read)

1. **`fetch(A)` returns only A's events; `fetch(B)` returns only B's events.**
2. **`replay_until(A)` and `replay_until(B)` produce distinct `state_id`s with disjoint identifiers.**
3. **Cross-tenant provenance attacks fail closed** — A's events fed to replay under B's root principal return `ProvenanceBroken`, zero active grants.

---

## 01 — Problem

A platform that runs multiple tenants on the same database and the same signing infrastructure is one schema-level mistake away from disaster: a missing `WHERE tenant_id = $1` filter, a typo in a join condition, a replay engine that accidentally trusts an attacker's claimed `tenant_root` over the events' actual provenance. The platform has to prove — not assert — that those failures don't happen.

This proof exercises tenant isolation at the three layers where it can fail: the storage layer (`PostgresEventLogSource`), the replay layer (`replay_until`), and the provenance layer (the "No Derived Authority Without Provenance" invariant).

---

## 02 — Environment

| Component | Detail |
|---|---|
| Isolation test | `tests/multi_tenant_isolation_001.rs` in `scif-backend` at SHA `2be2df3f8` |
| Storage | `PostgresEventLogSource` against `h33_production.canonical_auth_events` |
| Replay | `h33_xeon_api::agent_zero::astate_replay::replay_until` |
| Tenant A signing | Production PQ keys at `h33/production/canonical-event-signer` (the same keys that signed the V101 first-proof events for Tenant A) |
| Tenant B signing | **Same keys.** The point of the proof is that shared keys do not imply shared authority. |

---

## 03 — Identity

| Tenant | tenant_id | tenant_root | principal | authority_id |
|---|---|---|---|---|
| A (V101 first-proof real tenant) | `tenant_v101_44962d9b-25f5-5622-bd9a-98d5580bb8a2` | `princ_root_v101_44962d9b-…` | `princ_customer_9` | `auth_44962d9b-…_v101_export` |
| B (structural test tenant) | `tenant_v101_7905888e-56fd-59ea-86cb-82661e13a851` | `princ_root_v101_7905888e-…` | `princ_customer_99001` | `auth_7905888e-…_v101_export` |

Tenant B's `creator_uuid` was derived via the locked NS_H33_CREATORS_V1 namespace: `uuid5(NS_H33_CREATORS_V1, "99001")`. The same derivation Tenant A used; deterministic and reproducible.

---

## 04 — Authority

Both tenants registered the same policy_id `pol_v101_exporter_v1` independently (each with its own signed `policy_register` event). Both tenants issued an `export_content_bundle` grant against that policy to their own customer principal. The grants are structurally identical but cryptographically distinct (different `authority_id`, different `granted_by`, different `granted_to`, different 148-hex signature).

Tenant A grant: `auth_44962d9b-…_v101_export` → `princ_customer_9` · expiry `1811825726633`
Tenant B grant: `auth_7905888e-…_v101_export` → `princ_customer_99001` · expiry `1811934128501`

---

## 05 — Replay (isolation matrix)

Three layers tested:

### Layer 1 — Store

`fetch(TENANT_A)` returned 2 events. `fetch(TENANT_B)` returned 2 events. Quote-bounded substring checks confirmed:

- A's serialized events contain zero `"princ_root_v101_7905888e-…"`, `"princ_customer_99001"`, `"auth_7905888e-…_v101_export"`
- B's serialized events contain zero `"princ_root_v101_44962d9b-…"`, `"princ_customer_9"`, `"auth_44962d9b-…_v101_export"`

Positive sanity: each tenant's own root identifier was found in its own blob.

### Layer 2 — Replay

Both `replay_until` invocations returned verdict `Valid`. Snapshots:

| Tenant | state_id | active_grants |
|---|---|---|
| A | `24a06e845ce573dd773298451ad9a05da213cea52068e8b93e054ae9166f9db9` | 1 (A's grant only) |
| B | `c11b3ca74742c191bf1f2846970f91a104b78a2e375bcceef23c48f116e20f15` | 1 (B's grant only) |

`state_id`s are byte-distinct. A's snapshot JSON contains zero `princ_customer_99001`, zero `auth_7905888e-…_v101_export`, zero `princ_root_v101_7905888e-…`. B's snapshot JSON contains zero `princ_customer_9`, zero `auth_44962d9b-…_v101_export`, zero `princ_root_v101_44962d9b-…`.

### Layer 3 — Injection attack

A malicious caller fed Tenant A's events to `replay_until` with **Tenant B's `tenant_root_principal`** claimed as the root authority. The "No Derived Authority Without Provenance" invariant rejected the attack:

```
verdict           = ProvenanceBroken
active_grants     = 0
```

Because A's grants were granted by `princ_root_v101_44962d9b-…`, not by `princ_root_v101_7905888e-…`, the chain to the claimed root cannot be reconstructed. The replay engine does not return "partial" authority — it returns no authority and a clear verdict explaining why.

---

## 06 — Result (isolation matrix artifact)

The full result is published as a sibling file: [`isolation-matrix.json`](isolation-matrix.json).

```json
{
  "proof_id": "first-multi-tenant-proof",
  "isolation_matrix": {
    "fetch_a_returns_only_a": true,
    "fetch_b_returns_only_b": true,
    "a_events_contain_no_b_identifiers": true,
    "b_events_contain_no_a_identifiers": true,
    "state_id_distinct": true,
    "a_snapshot_contains_no_b_identifiers": true,
    "b_snapshot_contains_no_a_identifiers": true,
    "injection_a_events_under_b_root_rejected": true,
    "injection_active_grants_after_attack": 0
  }
}
```

Every cell of the matrix is `true`. No isolation property fails. No leakage observed.

---

## 07 — Anchor (none issued; this proof does not anchor a new receipt)

This proof does not exercise bundle issuance for Tenant B. Tenant B does not have a real Auth1 customer record; minting a Bearer for `princ_customer_99001` would require operator-side customer provisioning, which would promote Tenant B from "structural test tenant" to "second real customer." That promotion earns its own proof.

The original Tenant A anchor (V101 first-bundle `d9adcfb0-…`) is referenced as the upstream artifact this proof builds on.

---

## 08 — Known limitations

1. **Tenant B is structural, not a real customer.** A's identity chain reaches all the way to Auth1 (real EdDSA Bearer, real OTP login, real audit trail). B's identity chain stops at the canonical event log — sufficient to prove isolation, not sufficient to be a "second customer." When the first second-customer proof lands, B is replaced.
2. **Two tenants, not many.** Scale-of-isolation (10, 100, 10,000 tenants) is not yet measured. Belongs in #5 (Scale).
3. **Single point-in-time check.** Isolation was verified at one moment with one event set per tenant. Continuous isolation under churn (grants and revokes interleaved across tenants) is not yet tested.
4. **Bundle issuance for Tenant B not exercised.** Tenant B's grant resolved correctly in replay; whether the V101 bundle-issue endpoint produces an anchored receipt for B is not part of this proof.
5. **Same signing keys for both tenants.** The isolation proven is at the application layer. Cryptographic isolation (different keys per tenant) is a different proof not yet undertaken.

---

## 09 — Evidence appendix

| Field | Value |
|---|---|
| Tenant A `state_id` | `24a06e845ce573dd773298451ad9a05da213cea52068e8b93e054ae9166f9db9` |
| Tenant B `state_id` | `c11b3ca74742c191bf1f2846970f91a104b78a2e375bcceef23c48f116e20f15` |
| Injection verdict | `ProvenanceBroken` |
| Injection active grants after attack | `0` |
| Replay-until `T` (ms) | `1800000000000` (well after both tenants' latest event) |
| Tenant A events count | `2` |
| Tenant B events count | `2` |
| Tenant B `creator_uuid` derivation | `uuid5(NS_H33_CREATORS_V1, "99001") = 7905888e-56fd-59ea-86cb-82661e13a851` |
| Isolation matrix JSON | [`isolation-matrix.json`](isolation-matrix.json) |
| Test harness | `tests/multi_tenant_isolation_001.rs` in scif-backend @ `2be2df3f8` |
| Upstream proof | [Regulator Replay #001](/proofs/regulator-replay-001/) (Tenant A's state_id reconstruction) |
| Upstream artifact | [V101 first-proof bundle `d9adcfb0-…`](https://app.v101.ai/v101/bundle/d9adcfb0-e0bc-426b-8725-fc12d555692b) |

---

## Deployment commit SHAs

| Component | SHA | Subject |
|---|---|---|
| scif-backend (isolation harness) | `2be2df3f8` | proof(canonical-auth): #3 Multi-Tenant Isolation reconstruction test |
| scif-backend (regulator replay harness) | `d310d8134` | proof(canonical-auth): #2 Regulator Replay reconstruction test |
| scif-backend (runtime) | `99756176c` | fix(canonical-auth): background JWKS refresh |
| auth1 (deployed) | `2f49d0a` | Auth1 Phase 2 canonical-token endpoint |
| V101 (deployed) | `68034b1` | V101 Content Bundle endpoint |

---

## Independent reconstruction inputs

A third party with the following can reproduce this proof:

- Read access to `canonical_auth_events` for both `tenant_v101_44962d9b-…` and `tenant_v101_7905888e-…`.
- The replay engine source: `scif-backend` at SHA `2be2df3f8`.
- The test harness: `tests/multi_tenant_isolation_001.rs`.

Run:

```bash
H33_TEST_PG_URL='postgres://…?sslmode=require' \
  cargo test --test multi_tenant_isolation_001 -- --ignored --nocapture
```

Expected outputs (byte-identical to those above):

```
state_id_A = 24a06e845ce573dd773298451ad9a05da213cea52068e8b93e054ae9166f9db9
state_id_B = c11b3ca74742c191bf1f2846970f91a104b78a2e375bcceef23c48f116e20f15
injection verdict = ProvenanceBroken, active_grants = 0
```

---

## Readiness determination

> **Multi-Tenant Isolation: PROVEN IN OPERATION** for two tenants at one moment in time, with structural Tenant B.

What this unlocks: customer conversations about "what happens if you onboard a second customer; what happens if you serve a competitor; what happens if you make a typo in a WHERE clause." The answer is the isolation matrix.

What this does NOT unlock: scale-of-isolation (#5), continuous-churn isolation, cryptographic-isolation (different signing keys per tenant), or commercial-second-customer claims. Each earns its own published proof.

---

## Version

| Field | Value |
|---|---|
| Report version | v1.0 (Final) |
| Frozen | 2026-06-02 |
| Supersedes | None |
| Superseded by | None |

---

*Issued by H33, Inc. — Eric Beans, CEO. Independently reconstructable per Section 09.*
