Grounded in the intended use (SIM-drop AP with pre-registered eSIM batch, QR captive portal, COTS + software UEs, srsRAN+Open5GS, Pi+Android). Phases 0-4 from proving live core attach through a local SM-DP+ for test eUICCs, and flags the GSMA-CI trust constraint that rules out arbitrary consumer phones from a field-local SM-DP+. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.0 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 hard constraint that shapes everything
Consumer eSIM (GSMA SGP.22 RSP) does not let you sideload a profile file into an eUICC. The device's LPA downloads the profile from an SM-DP+ identified by an activation code, and the eUICC will only trust an SM-DP+ whose certificate chains to the GSMA CI root.
A field-local SM-DP+ (e.g. Osmocom osmo-smdpp) uses test CI keys, which only
test eUICCs accept. Therefore:
- ✅ Software UE — loads a profile/credential file directly. Works today, no RSP.
- ✅ Test eUICCs (dev eUICC cards / test modems) — can install from a local
osmo-smdpp. This is the realistic "real eSIM" demo path. - ❌ Arbitrary consumer phones with factory eUICCs — will reject a local SM-DP+. Not achievable in an ad-hoc/offline deployment without a GSMA-accredited 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)
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 — Test eUICC: 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/provisionformat). - 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.confwithimsi/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 — Test-eUICC via local SM-DP+ (the real eSIM last mile)
- Stand up
osmo-smdppon the drop; wire our SAIP profiles into it; manage the (test) CI cert chain. - Complete the SAIP profile to an installable one (PIN/PUK, ARR, security domain, remaining mandatory PEs) — validated against the test eUICC (this is where the deferred SAIP PE work finally gets card-validated rather than guessed).
- Captive portal renders the LPA activation-code QR; test device installs and attaches.
- Deliverable: test-eUICC device → 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.
Recommended immediate next steps
- Phase 0 — prove live attach (software UE + Open5GS). Highest de-risking value.
- 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-smdppon the drop, or a different RSP? - Test eUICCs — which test eUICC(s)/modems are the real targets (so Phase 3 profile completion is validated against them)?
- Batch model — expected batch size per drop; how batches are provisioned and loaded (offline media vs one-time backhaul).