Push Tracker
ria-ran--sim-drop/plan/roadmap.md
A ashkan@beigi.net f0f97a8926 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>
2026-07-02 03:15:24 +00:00

7.6 KiB

Roadmap — Closed-Loop eSIM Provisioning ("SIM Drop")

Last updated: 2026-07-02

Context

Goal. A "SIM drop": a WiFi access point dropped into the field, pre-loaded with a batch of eSIM profiles already registered in the 5G core, that hands credentials to devices through a captive portal reached by QR code. If a backhaul link to the core exists, it can also register new subscribers dynamically.

End devices.

  • COTS UEs (handsets / modems) with real eUICCs.
  • An in-house software UE stack that can load credentials from a file.

Constraints & resources.

  • Purely eSIM — no physical SIM programming (Open-Cells cards on hand are not the target path).
  • Available for testing: srsRAN gNB + Open5GS running, a test eUICC / phone.
  • Deployment targets Pi and Android, equally.

The trust model (and how we work with it — not against it)

Consumer eSIM (GSMA SGP.22 RSP) doesn't let you sideload a profile file into an eUICC: the device's LPA downloads it from an SM-DP+, and the eUICC only installs profiles from an SM-DP+ whose certificate chains to a CI root the eUICC trusts.

The key realization: we control which eUICC the device uses. We do not need 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 deviceEasyEUICC / 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.
  • COTS UE + controllable eUICC — removable sysmoEUICC (test/private root) in a COTS phone/modem + LPA + our local osmo-smdpp. The real eSIM path.
  • ⚠️ A phone's untouched factory eUICC — would reject a local SM-DP+ (needs GSMA CI accreditation). We sidestep this by supplying the eUICC, so it's not a blocker.

Where we are (done)

Provisioning server: credential generation (IMSI/Ki/OPc/ICCID), SQLite store, per-MAC rate limiting, captive portal, Open5GS/free5gc adapters, v2 + real SAIP profile generation, security-hardened, 109 tests. Missing: the last mile (delivery to a device) and live core-integration proof.

Target architecture

Drop device (Pi / Android)
├─ WiFi AP (open) + captive portal (QR entry)
├─ Provisioning server (Flask)      ← built
├─ Subscriber DB (pre-registered batch + dynamic)  ← built, needs batch layer
├─ Local SM-DP+ (osmo-smdpp)        ← Phase 3
└─ Backhaul to core (optional)      ← dynamic registration when present

Two delivery tracks:
  Track S — Software UE:      profile file → soft-UE → attach       (Phase 1)
  Track E — COTS UE + eUICC:  COTS phone/modem with a controllable
                              (removable/private-root) eUICC + LPA:
                              QR activation code → LPA → local SM-DP+
                              → eUICC installs SAIP profile → attach (Phase 3)

Phases

Phase 0 — Prove core attach (de-risk the foundation)

Register one generated credential in Open5GS and attach with the software UE (or a test eUICC) on srsRAN+Open5GS; confirm authentication succeeds.

  • Validates our Milenage/OPc derivation and the adapter document shape against a live core — everything downstream depends on this being correct.
  • Needs from you: Open5GS reachability (MongoDB URI / network) or you run the sync; the slice (SST/SD), APN/DNN, and PLMN the gNB expects.

Phase 1 — Software-UE loop (file delivery; first closed loop, no SM-DP+)

  • Define the soft-UE profile format and add an exporter (extend scripts/make_profile.py / a new /api/provision format).
  • Flow: WiFi → captive portal → provision → download soft-UE profile → attach.
  • Needs from you: the exact format your soft-UE ingests (e.g. srsUE-style ue.conf with imsi/k/opc/opc_type, or a custom schema).

Phase 2 — Pre-registered batch + drop packaging (the "drop" model) [software-only; can start now]

  • Batch generator: pre-generate N profiles, register all in the core, persist to the drop DB marked "available".
  • Captive-portal claim flow: atomically hand an unclaimed pre-registered profile to a device (QR/portal).
  • Offline operation: with no backhaul, hand out from the pre-loaded batch; queue dynamic registrations for when the core link returns.
  • Deliverable: a drop that works fully offline from a pre-loaded batch.

Phase 3 — COTS UE via local SM-DP+ (the real eSIM last mile)

  • Obtain controllable eUICCs (removable sysmoEUICC1 with SGP.26/private root, or 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, remaining mandatory PEs) — validated against the real eUICC (this is where the deferred SAIP PE work finally gets card-validated rather than guessed). Cross-check against pySim's known-good test profiles.
  • Captive portal renders the LPA activation-code QR; a COTS phone/modem (with 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)

Offline/power/thermal, monitoring/observability, capacity, subscriber revoke/expire/resync, backhaul-aware dynamic registration, secure batch loading.

  1. Phase 0 — prove live attach (software UE + Open5GS). Highest de-risking value.
  2. Phase 2 groundwork (in parallel, software-only, no hardware needed): the batch pre-registration generator + atomic claim flow. This is squarely on the critical path for the "dropped, pre-loaded, offline" model and I can build and test it now.

Open questions

  • Soft-UE profile format — what schema does your software UE ingest?
  • Open5GS access — reachable from the dev environment, or do you run sync? 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?
  • Controllable eUICCs — which eUICC do we standardize on (sysmoEUICC1 with 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 loaded (offline media vs one-time backhaul).