Summary
MicroPythonOS currently has no first-class way to disable the radios (WiFi, Bluetooth) on the device, and no way for an app to declare it needs to run with networking off. That's a problem for apps that handle secrets — Bitcoin signers, seed-phrase tools, password managers, anything that should be offline-by-construction. Today the user has no UI affordance to airplane-mode the device, and a sensitive app can't communicate that requirement to the framework.
Today's state (as of 0.10.0)
- WiFi is auto-started on every boot:
mpos/main.py line 318 kicks off WifiService.auto_connect() on a thread, which calls sta.active(True) and reconnects to any saved network.
- The Settings → WiFi app lets users scan / connect / forget networks. There's no "WiFi: Off" master switch.
WifiService.temporarily_disable() / temporarily_enable() exist (mpos/net/wifi_service.py line 391+), but the docstring is explicit that the intent is ADC2 conflict resolution on ESP32-S3 — not security.
- The only WiFi-off code path that runs in normal use is the power-save in
auto_connect() (line 381) when initial connection fails.
- There's no
airplane, secure_mode, offline_mode, or network_disabled setting anywhere in the codebase.
- Bluetooth: MPOS bundles no BLE code at all. The ESP32-S3 has the silicon, MPOS just doesn't activate it. So today BLE is "off by accident", which is fine, but if BLE support is added later, the same security gap would emerge for it.
What I'd like
1. User-facing: airplane mode toggle
A toggle in Settings (probably next to the existing WiFi entry, or as a top-level entry) labelled "Airplane mode" / "Offline". When ON:
- The connectivity manager doesn't auto-connect on boot
WifiService.auto_connect() no-ops while the toggle is on
- Any currently-active connection is dropped and
sta.active(False) is called
- A visible indicator on the status bar / launcher so the user knows networking is disabled
- (Future) if/when Bluetooth ships, the same toggle gates the BLE stack
Backing pref: something like mpos.settings.airplane_mode = true/false, read by WifiService.auto_connect (and the future BLE init).
2. Per-app: declare offline requirement in MANIFEST
A new optional manifest field:
{
\"requires_offline\": true
}
When an app with requires_offline: true is launched:
- If airplane mode is already on, the app just launches normally.
- If airplane mode is OFF, MPOS shows a one-tap dialog: "This app requires offline mode. Enable airplane mode to continue?" → user confirms → airplane mode flips on → app launches.
- On the app's
onPause / onDestroy, airplane mode does NOT automatically flip back. The user explicitly turned it on (with consent), so they explicitly turn it off later — never a surprise reconnect mid-session, never a surprise reconnect after sensitive work.
3. Programmatic API for apps
So a security-conscious app can also enforce "radios down" defensively without relying solely on the manifest gate:
from mpos.net.airplane import AirplaneMode
AirplaneMode.enable() # disables WiFi (and BLE if present)
AirplaneMode.is_enabled()
AirplaneMode.disable() # explicit user-consent flow, not auto
A mpos.net.airplane.AirplaneMode class (analogous to WifiService) seems like the right shape — keeps the radio policy in one place rather than scattered across each app.
Why this matters
Lightning Piggy is the obvious nearby example — it's a display-only wallet so WiFi-on is fine. But MicroPythonOS could also be a great target for hardware-wallet-style apps: a Nostr signer, a BIP-32 cold storage viewer, a secp256k1 PSBT signer, a passphrase manager. All of those want "radios off" as a foundational property, not as something each app re-implements with WifiService.temporarily_disable() (a private API meant for ADC2). Without an airplane-mode primitive, MPOS is implicitly an "online-only" OS.
Implementation sketch
- Add
airplane_mode pref to com.micropythonos.settings
- Gate
WifiService.auto_connect() and WifiService.connect() on it (early return if true, plus immediate sta.active(False) if any radio is up)
- Add a settings activity row that toggles the pref + a small icon in the launcher / status area
- Manifest schema: optional
requires_offline: bool field in META-INF/MANIFEST.JSON. Handle in the launcher / activity-start path.
- Public Python API:
mpos.net.airplane.AirplaneMode with enable / disable / is_enabled.
Happy to take a first pass at this if there's interest — would prefer to align on the API shape first so we don't end up with two competing surfaces.
Related
Summary
MicroPythonOS currently has no first-class way to disable the radios (WiFi, Bluetooth) on the device, and no way for an app to declare it needs to run with networking off. That's a problem for apps that handle secrets — Bitcoin signers, seed-phrase tools, password managers, anything that should be offline-by-construction. Today the user has no UI affordance to airplane-mode the device, and a sensitive app can't communicate that requirement to the framework.
Today's state (as of 0.10.0)
mpos/main.pyline 318 kicks offWifiService.auto_connect()on a thread, which callssta.active(True)and reconnects to any saved network.WifiService.temporarily_disable()/temporarily_enable()exist (mpos/net/wifi_service.pyline 391+), but the docstring is explicit that the intent is ADC2 conflict resolution on ESP32-S3 — not security.auto_connect()(line 381) when initial connection fails.airplane,secure_mode,offline_mode, ornetwork_disabledsetting anywhere in the codebase.What I'd like
1. User-facing: airplane mode toggle
A toggle in Settings (probably next to the existing WiFi entry, or as a top-level entry) labelled "Airplane mode" / "Offline". When ON:
WifiService.auto_connect()no-ops while the toggle is onsta.active(False)is calledBacking pref: something like
mpos.settings.airplane_mode = true/false, read byWifiService.auto_connect(and the future BLE init).2. Per-app: declare offline requirement in MANIFEST
A new optional manifest field:
{ \"requires_offline\": true }When an app with
requires_offline: trueis launched:onPause/onDestroy, airplane mode does NOT automatically flip back. The user explicitly turned it on (with consent), so they explicitly turn it off later — never a surprise reconnect mid-session, never a surprise reconnect after sensitive work.3. Programmatic API for apps
So a security-conscious app can also enforce "radios down" defensively without relying solely on the manifest gate:
A
mpos.net.airplane.AirplaneModeclass (analogous toWifiService) seems like the right shape — keeps the radio policy in one place rather than scattered across each app.Why this matters
Lightning Piggy is the obvious nearby example — it's a display-only wallet so WiFi-on is fine. But MicroPythonOS could also be a great target for hardware-wallet-style apps: a Nostr signer, a BIP-32 cold storage viewer, a secp256k1 PSBT signer, a passphrase manager. All of those want "radios off" as a foundational property, not as something each app re-implements with
WifiService.temporarily_disable()(a private API meant for ADC2). Without an airplane-mode primitive, MPOS is implicitly an "online-only" OS.Implementation sketch
airplane_modepref tocom.micropythonos.settingsWifiService.auto_connect()andWifiService.connect()on it (early return if true, plus immediatesta.active(False)if any radio is up)requires_offline: boolfield inMETA-INF/MANIFEST.JSON. Handle in the launcher / activity-start path.mpos.net.airplane.AirplaneModewithenable / disable / is_enabled.Happy to take a first pass at this if there's interest — would prefer to align on the API shape first so we don't end up with two competing surfaces.
Related