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
Storetrait 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.