Roadmap: correct the eSIM trust model (COTS UEs ARE in scope)

Earlier framing wrongly treated the eUICC as immutable and put consumer phones
out of scope. Corrected: we supply a controllable eUICC (removable sysmoEUICC
with SGP.26/private root) that trusts our local osmo-smdpp, so any COTS phone/
modem works via its LPA (EasyEUICC/OpenEUICC or lpac) with no GSMA involvement.
Update the trust-model section, architecture, Phase 3, and open questions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
A ashkan@beigi.net 2026-07-02 03:15:24 +00:00
parent 90490e649c
commit f0f97a8926

View File

@ -19,26 +19,39 @@ link to the core exists, it can also register new subscribers dynamically.
- Available for testing: **srsRAN gNB + Open5GS running**, a **test eUICC / phone**. - Available for testing: **srsRAN gNB + Open5GS running**, a **test eUICC / phone**.
- Deployment targets **Pi and Android**, equally. - Deployment targets **Pi and Android**, equally.
## The hard constraint that shapes everything ## The trust model (and how we work with it — not against it)
Consumer eSIM (GSMA SGP.22 RSP) does **not** let you sideload a profile file into Consumer eSIM (GSMA SGP.22 RSP) doesn't let you sideload a profile file into an
an eUICC. The device's LPA downloads the profile from an **SM-DP+** identified by eUICC: the device's LPA downloads it from an **SM-DP+**, and the eUICC only
an activation code, and **the eUICC will only trust an SM-DP+ whose certificate installs profiles from an SM-DP+ whose certificate chains to a **CI root the
chains to the GSMA CI root**. eUICC trusts**.
A field-local SM-DP+ (e.g. Osmocom `osmo-smdpp`) uses **test CI keys**, which only The key realization: **we control which eUICC the device uses.** We do *not* need
**test eUICCs** accept. Therefore: to defeat a phone's soldered factory eUICC (that would need GSMA CI accreditation).
Instead we supply a **controllable eUICC** whose root-of-trust is ours/test — and
then any COTS UE works with our own local SM-DP+, with **no GSMA involvement**.
This is a productized, well-trodden path (sysmocom sells the cards and runs a
test SM-DP+ for them).
Concretely, three ingredients:
1. **A controllable eUICC**, e.g. **sysmoEUICC1** — a removable eUICC in 2FF/3FF/4FF
plastic (or MFF2 solder) form, loaded with **test (SGP.26) or private roots**
instead of GSMA keys. Plugs into virtually any COTS phone/modem with a SIM slot.
2. **A local SM-DP+** — Osmocom **`osmo-smdpp`** (proof-of-concept, ships with
pySim), serving *our* SAIP profiles, using SGP.26 test / private-root certs that
match the eUICC.
3. **An LPA on the device****EasyEUICC / OpenEUICC** (Android, via UICC Carrier
Privileges; needs the eUICC's ISD-R to grant an ARA-M rule) or **`lpac`** for
modems / CLI. The LPA consumes an activation-code **QR** and drives the install.
Delivery tracks:
- ✅ **Software UE** — loads a profile/credential file directly. Works today, no RSP. - ✅ **Software UE** — loads a profile/credential file directly. Works today, no RSP.
- ✅ **Test eUICCs** (dev eUICC cards / test modems) — can install from a local - ✅ **COTS UE + controllable eUICC** — removable sysmoEUICC (test/private root) in a
`osmo-smdpp`. This is the realistic "real eSIM" demo path. COTS phone/modem + LPA + our local `osmo-smdpp`. The real eSIM path.
- ❌ **Arbitrary consumer phones with factory eUICCs** — will reject a local - ⚠️ **A phone's untouched factory eUICC** — would reject a local SM-DP+ (needs GSMA
SM-DP+. Not achievable in an ad-hoc/offline deployment without a GSMA-accredited CI accreditation). We sidestep this by supplying the eUICC, so it's not a blocker.
SM-DP+ (out of scope for emergency/NTN).
**Implication:** target the **software UE** and **test-eUICC modems**. Treat
generic consumer-phone eSIM as explicitly out of scope until/unless a real
SM-DP+ relationship exists.
## Where we are (done) ## Where we are (done)
@ -58,9 +71,11 @@ Drop device (Pi / Android)
└─ Backhaul to core (optional) ← dynamic registration when present └─ Backhaul to core (optional) ← dynamic registration when present
Two delivery tracks: Two delivery tracks:
Track S — Software UE: profile file → soft-UE → attach (Phase 1) Track S — Software UE: profile file → soft-UE → attach (Phase 1)
Track E — Test eUICC: QR activation code → LPA → local SM-DP+ Track E — COTS UE + eUICC: COTS phone/modem with a controllable
→ eUICC installs SAIP profile → attach (Phase 3) (removable/private-root) eUICC + LPA:
QR activation code → LPA → local SM-DP+
→ eUICC installs SAIP profile → attach (Phase 3)
``` ```
## Phases ## Phases
@ -89,15 +104,20 @@ a test eUICC) on srsRAN+Open5GS; confirm authentication succeeds.
queue dynamic registrations for when the core link returns. queue dynamic registrations for when the core link returns.
- Deliverable: a drop that works fully offline from a pre-loaded batch. - Deliverable: a drop that works fully offline from a pre-loaded batch.
### Phase 3 — Test-eUICC via local SM-DP+ (the real eSIM last mile) ### Phase 3 — COTS UE via local SM-DP+ (the real eSIM last mile)
- Stand up `osmo-smdpp` on the drop; wire our SAIP profiles into it; manage the - Obtain **controllable eUICCs** (removable sysmoEUICC1 with SGP.26/private root, or
(test) CI cert chain. equivalent) and confirm an **LPA** on the target UEs (EasyEUICC/OpenEUICC on
Android; `lpac` for modems). Verify the eUICC's ISD-R grants the ARA-M rule the
LPA needs.
- Stand up **`osmo-smdpp`** on the drop; wire our SAIP profiles into it; manage the
matching (SGP.26/private) CI cert chain.
- Complete the SAIP profile to an installable one (PIN/PUK, ARR, security domain, - Complete the SAIP profile to an installable one (PIN/PUK, ARR, security domain,
remaining mandatory PEs) — **validated against the test eUICC** (this is where remaining mandatory PEs) — **validated against the real eUICC** (this is where
the deferred SAIP PE work finally gets card-validated rather than guessed). the deferred SAIP PE work finally gets card-validated rather than guessed).
- Captive portal renders the LPA activation-code **QR**; test device installs and Cross-check against pySim's known-good test profiles.
attaches. - Captive portal renders the LPA activation-code **QR**; a COTS phone/modem (with
- Deliverable: test-eUICC device → scan QR → eSIM installed → on the network. the controllable eUICC) installs and attaches.
- Deliverable: COTS UE + controllable eUICC → scan QR → eSIM installed → on the network.
### Phase 4 — Field hardening (Pi + Android, first-class) ### Phase 4 — Field hardening (Pi + Android, first-class)
Offline/power/thermal, monitoring/observability, capacity, subscriber Offline/power/thermal, monitoring/observability, capacity, subscriber
@ -117,7 +137,10 @@ revoke/expire/resync, backhaul-aware dynamic registration, secure batch loading.
- **Open5GS access** — reachable from the dev environment, or do you run sync? - **Open5GS access** — reachable from the dev environment, or do you run sync?
MongoDB URI, slice SST/SD, APN/DNN, PLMN to match the gNB. MongoDB URI, slice SST/SD, APN/DNN, PLMN to match the gNB.
- **SM-DP+** — OK to vendor/run `osmo-smdpp` on the drop, or a different RSP? - **SM-DP+** — OK to vendor/run `osmo-smdpp` on the drop, or a different RSP?
- **Test eUICCs** — which test eUICC(s)/modems are the real targets (so Phase 3 - **Controllable eUICCs** — which eUICC do we standardize on (sysmoEUICC1 with
profile completion is validated against them)? SGP.26 vs private root)? Do the current "test eUICC/phone" you have match the
SGP.26 root osmo-smdpp ships, or do we need a private-root batch?
- **LPA** — EasyEUICC/OpenEUICC (Android) and/or `lpac` (modems) as the on-device
LPA? Any UEs whose SIM slot / carrier-privilege behavior needs checking?
- **Batch model** — expected batch size per drop; how batches are provisioned and - **Batch model** — expected batch size per drop; how batches are provisioned and
loaded (offline media vs one-time backhaul). loaded (offline media vs one-time backhaul).