Gunnar

nordisk/frida

docs/PROTOCOL.md

# frida — protocol & service design (draft)

Canonical design for the EU eID `frida`. Vetra's `heimdal-frida` is a *client*; keep protocol and
service decisions here.

## Standards (EU-native)

| concern | standard |
|---|---|
| issuance | **OpenID4VCI** |
| authentication / presentation | **OpenID4VP** |
| credential format | **SD-JWT VC** (+ **ISO/IEC 18013-5 mdoc**) |
| device binding (mobile) | **WebAuthn / FIDO2**, hardware-backed |
| card reader (web) | **PKCS#11** (`cryptoki`) |
| envelopes / signatures | **COSE** (mdoc) / **JOSE** (SD-JWT) |

These are global (OpenID Foundation / IETF / ISO) standards; eIDAS 2.0 / EUDI is a *profile + trust
governance* on top. `frida` runs its **own trust registry** (issuer/verifier trust anchors) so it
is eIDAS-*compatible* without being eIDAS-*dependent* — resilient to EU governance changes while
staying interoperable.

## Service

Rust, **tonic** gRPC over tokio/hyper (HTTP/2, TLS). Two deployment modes:

- **standalone (single server)** — one binary over an embedded store (see Persistence).
- **kubernetes (multi-server)** — a **kube-rs operator** with CRDs (`Issuer`, `Verifier`,
  `TrustRegistry`) provisions/scales issuer & verifier nodes and rotates trust material.

gRPC surface (sketch): `StartAuth`, `StartSign`, `Collect` (server-stream for status), `Cancel`,
`Issue`, `Revoke`, `Status`. Mirrors `heimdal_core::IdentityProvider` so the provider maps 1:1.

### Why gRPC (and not a proprietary wire)

Protobuf is already compact binary (varint + field tags) — the XML→binary win is captured, and
gRPC brings streaming, load-balancing, and Cilium-level observability. A proprietary format would
shave a little more only on tiny/high-frequency messages and constrained devices — which is exactly
what **`tyr`** exists for. `frida` optimises for **interoperability**; `tyr` optimises for size.

## Persistence — no relational database, ever

Persistence is a **`Store` trait** (lives in `edda`, following the existing `nornir-warehouse-trait`
pattern), never an RDBMS. Two backends:

| backend | use | shape |
|---|---|---|
| **redb / rocksdb** | single-server | embedded KV; nothing to operate |
| **skade** | large transactional / analytical / audit at scale | pure-Rust Iceberg lakehouse (embedded ACID catalog `skade-katalog` on redb; all-core gatling ingest, time-travel snapshots) |

- **Single server** → embedded redb/rocksdb: orders, nonces, issued-credential status.
- **Multi-server** → an **append-only event log with per-event ACK** as the source of truth; nodes
  replay/subscribe. High-volume records (issued-credential ledger, audit receipts) sink into
  **skade** for cheap, snapshotted, queryable history. The `Store` trait hides which backend a
  deployment uses.

## Networking (multi-server)

- **WireGuard** secures node-to-node traffic — a natural fit as **Cilium transparent WireGuard
  encryption** between nodes (built into the CNI, no sidecars).
- **Cilium cannot *guarantee* application-level ACK.** Cilium/eBPF guarantees the *network*:
  connectivity, policy, load-balancing, mTLS/identity, and WireGuard encryption — i.e. that a
  delivered packet is authenticated and encrypted. **Delivery/ACK semantics are the event log's
  job** (append → replicate → ACK → commit), not the CNI's. So: WireGuard+Cilium for a secure,
  observable fabric; the event protocol owns exactly-/at-least-once and acknowledgement.

## Lifecycle (maps onto heimdal's `IdentityProvider`)

- **start** → build an OpenID4VP request; return cross-device request URI (QR) + same-device deep
  link.
- **collect** → poll/stream the verifier for the wallet's verified presentation; return disclosed
  subject + verified signature (COSE/JOSE + signer key id).
- **cancel** → invalidate the pending request.

## PKCS#11 (card) path

Web RP asks host middleware to sign a verifier challenge with the card key via PKCS#11. `frida`
verifies the card cert chain to a trusted `frida`/national root and its validity window (same
pattern as `heimdal-freja`'s JWS check), then returns the verified signature. Key stays on the card.

## Capabilities roadmap

Core: **auth**, **sign**. Then, in rough priority: **issuance** (OpenID4VCI), **selective
disclosure** (SD-JWT VC), **QES** (qualified remote signing), **mandates/representation**,
**mdoc/mDL** (ISO 18013-5), **status/revocation**, **age verification**, **audit receipts**.

## Not decided here

Whether to pursue formal **eIDAS certification** (conformance to an EU trusted list) or run purely
self-anchored. Both are supported by the design; it's a business/regulatory call.