# NoData — Architecture & Threat Model

**Version:** 1.0 (April 2026)
**Audience:** enterprise security & platform engineers
**Companion docs:** `crypto-primitives.md` · `audit-chain-spec.md` · `open-vs-closed.md`

---

## 1. What NoData is

NoData is a **cryptographic control plane**. It does not replace your encryption; it sits above it and produces tamper-evident, mathematically verifiable evidence of every action taken on data — without ever seeing the data itself.

The primitive operates the same way across:

- backend services (Node, Python, Go, Java, .NET)
- desktop CLIs and editors
- mobile and IoT devices
- file systems, object storage, and databases

The same client SDK and the same proof chain back every surface.

---

## 2. The asymmetry we exploit

Conventional security stacks observe data **at rest** and **in transit** and infer behavior from telemetry. NoData inverts the order: every action is **announced cryptographically before it happens**, the announcement is signed, and the signature becomes the only authoritative record of the event.

| Conventional posture | NoData posture |
| --- | --- |
| Observe → log → infer | Announce → sign → record |
| Trust the operator, audit later | Operator is blind; audit is intrinsic |
| Encryption protects content | Proof chain protects *actions on* content |
| Logs can be edited / forged | Receipts are HMAC-chained; tampering breaks the chain |

This is why we say: *"We are not an encryption company. Encryption is a primitive. We are the control plane."*

---

## 3. Adversary model

We build against the following adversaries, ranked by capability:

### A1. Network attacker
Can read and modify TLS-protected traffic mid-flight (e.g., compromised transit).
**Assumed defeated by:** TLS 1.3 + per-session key wrapping + receipt-bound signatures.

### A2. Endpoint compromise (single user)
Has full control of a single client device.
**Defeated by:** device-bound keys; receipts produced by a compromised device are clearly attributed to it. Other devices' chains remain intact.

### A3. Insider at NoData
A NoData employee or operator with access to production servers.
**Defeated by:** server-side blindness — the server holds key material it cannot bind to plaintext. Plaintext only appears in client-side RAM during operation. Server audit table contains field names, sizes, hashes, timestamps, action types — never values.

### A4. Compromise of the NoData server
Attacker takes full control of NoData production.
**Defeated by:** the receipt chain is sealed hourly into a Merkle epoch, the epoch root is signed with Ed25519, published to an external witness feed we do not control (`github.com/proofbydefault/witness-feed`, one commit per epoch), and anchored to Bitcoin via OpenTimestamps. A compromised server cannot rewrite history without contradicting a record that already left our infrastructure. Verification is fully offline and does not involve NoData (see §5).

### A5. State-level compulsion against NoData
Government order to hand over data.
**Defeated by:** there is nothing to hand over. The operational table contains no data values. Customer keys are wrapped under customer-controlled KEK in BYOK mode.

### A6. Quantum attacker
Forward-looking threat against current asymmetric primitives.
**Mitigation:** the chain link itself is HMAC-SHA-256 (symmetric, post-quantum-safe by current understanding), so chain continuity survives a quantum adversary. The receipt and epoch-root **signatures** are Ed25519, which is **not** post-quantum-safe: a future quantum attacker could forge a signature over a root we never sealed. What it could not do is change what the external witness and the Bitcoin anchor already recorded at the time. PQC signatures are the planned migration; we do not claim to be post-quantum today.

---

## 4. What we **do** protect

✅ **Action integrity** — every operation (encrypt, decrypt, sign, verify, scan, export) is cryptographically attested
✅ **Operator blindness** — server can prove what happened without learning what was operated on
✅ **Tamper-evident audit** — chain breakage is detectable by any verifier, including the customer and any third party
✅ **Device attribution** — every receipt names which device produced it (no "anonymous" actions)
✅ **Time anchoring** — receipts include server-side timestamps inside the HMAC, preventing back-dating
✅ **Cross-device proofs** — a single chain spans all devices in an org
✅ **Independent verification** — operator and decision receipts carry an Ed25519 signature and the signing public key inline; the active key is published at `/api/chain/pubkey`. You verify with standard libraries, offline, without asking us anything
✅ **An external witness** — every hourly epoch root is committed to a public feed outside our infrastructure and timestamped into Bitcoin, so "show one story to you and another to a regulator" is not available to us

---

## 5. What we **do not** protect against (today)

❌ **Plaintext theft from a compromised endpoint mid-operation.** If an attacker has root on the device while `nodata run` is active, they can read plaintext from RAM. This is true of any encryption tool. We minimize the window (decrypt → use → discard) but do not eliminate it.

❌ **Integrity of the browser code that touches your plaintext.** The receipt chain proves what happened after the fact. It does not prove that the JavaScript your browser executed is the JavaScript we published. An attacker who can change what we serve can read plaintext before it is ever sealed. Binary transparency for the web client (publishing the bundle hash into the same witness feed) is the planned answer; it is not shipped.

❌ **Content-signature sidecars (`.nodatasig`) are a separate, weaker chain.** The `/sign` and `/verify` surface links sidecars with a symmetric HMAC, so a full verify of a *sidecar* still requires a server roundtrip. That limitation does **not** apply to operator and decision receipts, which are Ed25519-signed and independently verifiable (see below). Do not read a claim about one chain as a claim about the other.

❌ **Side-channel timing attacks against AES-GCM** in environments without constant-time hardware. Production deployments use AES-NI / ARMv8-AES.

❌ **Pre-image attacks against SHA-256.** None known; standard cryptographic assumption.

❌ **Loss of customer-held BYOK material.** If the customer loses their KEK, NoData cannot recover their data. By design.

We name these openly because a vendor who claims complete protection is either lying or naïve.

---

## 6. Where keys live (production reality, April 2026)

| Key | Storage | Who holds | Rotation |
| --- | --- | --- | --- |
| Per-record DEK (data encryption key) | Wrapped in the ciphertext header (`aes256gcm:v2:...`) | Customer's client | New per write |
| Tenant KEK (key encryption key) | NoData server-managed *or* customer KMS (BYOK roadmap) | Customer-influenced | On demand |
| **Chain HMAC secret** (`PROOF_HMAC_SECRET`) | Vercel env var **or** GCP-KMS-wrapped (`GCP_KMS_WRAPPED_HMAC`) | NoData operator | None scheduled today (§audit-chain-spec §7) |
| Device signing key | Local device keystore | Customer per device | Per device re-bind |
| MyGate ECDH P-256 keys | Browser keychain (mygate-crypto-core.ts) | Customer per device | Per device |
| Receipt verification | Public via `/api/verify` | Anyone | N/A — verification is public |

**Important honesty note**: today's chain uses a **single global HMAC secret**, not per-tenant. We are not pretending otherwise. Per-tenant chain secrets are an engineering item we'd consider under a contract that explicitly required tenant-isolated chain compromise blast-radius. See `audit-chain-spec.md` §7 and §10 Scenario 5 for our public-facing risk model on this.

---

## 7. Data flow — encrypt operation

```
┌────────┐        ┌──────────────────┐       ┌────────────┐
│ Client │───┬───▶│ NoData "control" │       │ Customer   │
│ SDK    │   │    │  (metadata only) │       │ storage    │
└────────┘   │    └──────────────────┘       └────────────┘
             │            │                          ▲
             │            │  receipt id              │
             │            ▼                          │
             │    ┌──────────────────┐               │
             │    │ Append to chain  │               │
             │    │ HMAC(prev || ev) │               │
             │    └──────────────────┘               │
             │                                       │
             └───────[ ciphertext ]──────────────────┘
```

The ciphertext bytes never touch NoData servers. Only the announcement of the operation does.

---

## 8. Trust boundaries

A NoData deployment has four trust boundaries:

1. **Client ↔ NoData control API** — TLS 1.3, mTLS optional for enterprise tenants
2. **NoData ↔ KMS (NoData-managed or BYOK)** — customer-rotatable, BYOK wins
3. **NoData ↔ verifier** — public, read-only, rate-limited per IP
4. **Tenant ↔ tenant** — hard isolation at chain, KEK, and database level

We publish the boundaries deliberately. Auditors should know exactly where the trust pivots so they can challenge each one.

---

## 9. What you can verify yourself

Without contacting us, you can:

- Verify any receipt's HMAC chain by hitting `/api/verify` with the receipt JSON
- Download `audit-export.zip` and recompute the chain hash from `events.json`
- Run `nodata verify <receipt-id>` from the CLI on a file you signed
- Compute the SHA-256 of any sample artifact in the kit and compare to its published hash

This document, and every linked artifact, is itself signed. Compute its hash and compare to `kit-manifest.txt`.

---

## 10. Reading further

- `crypto-primitives.md` — exact algorithms, key sizes, KDFs
- `audit-chain-spec.md` — HMAC chain construction and verification math
- `open-vs-closed.md` — what the open-source CLI does, what the closed server does, and why

---

*Questions, challenges, or threat-model holes you think we missed?*
*Email security@nodatacapsule.com — we publish responses, including ours-was-wrong replies.*
